linux-old/fs/namespace.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/namespace.c
   3 *
   4 * (C) Copyright Al Viro 2000, 2001
   5 *      Released under GPL v2.
   6 *
   7 * Based on code from fs/super.c, copyright Linus Torvalds and others.
   8 * Heavily rewritten.
   9 */
  10
  11#include <linux/config.h>
  12#include <linux/slab.h>
  13#include <linux/smp_lock.h>
  14#include <linux/init.h>
  15#include <linux/quotaops.h>
  16#include <linux/acct.h>
  17#include <linux/module.h>
  18
  19#include <asm/uaccess.h>
  20
  21#include <linux/seq_file.h>
  22#include <linux/namespace.h>
  23
  24struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
  25int do_remount_sb(struct super_block *sb, int flags, void * data);
  26void kill_super(struct super_block *sb);
  27extern int __init init_rootfs(void);
  28
  29static struct list_head *mount_hashtable;
  30static int hash_mask, hash_bits;
  31static kmem_cache_t *mnt_cache; 
  32
  33static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
  34{
  35        unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
  36        tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
  37        tmp = tmp + (tmp >> hash_bits);
  38        return tmp & hash_mask;
  39}
  40
  41struct vfsmount *alloc_vfsmnt(char *name)
  42{
  43        struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL); 
  44        if (mnt) {
  45                memset(mnt, 0, sizeof(struct vfsmount));
  46                atomic_set(&mnt->mnt_count,1);
  47                INIT_LIST_HEAD(&mnt->mnt_hash);
  48                INIT_LIST_HEAD(&mnt->mnt_child);
  49                INIT_LIST_HEAD(&mnt->mnt_mounts);
  50                INIT_LIST_HEAD(&mnt->mnt_list);
  51                if (name) {
  52                        int size = strlen(name)+1;
  53                        char * newname = kmalloc(size, GFP_KERNEL);
  54                        if (newname) {
  55                                memcpy(newname, name, size);
  56                                mnt->mnt_devname = newname;
  57                        }
  58                }
  59        }
  60        return mnt;
  61}
  62
  63void free_vfsmnt(struct vfsmount *mnt)
  64{
  65        if (mnt->mnt_devname)
  66                kfree(mnt->mnt_devname);
  67        kmem_cache_free(mnt_cache, mnt);
  68}
  69
  70struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
  71{
  72        struct list_head * head = mount_hashtable + hash(mnt, dentry);
  73        struct list_head * tmp = head;
  74        struct vfsmount *p;
  75
  76        for (;;) {
  77                tmp = tmp->next;
  78                p = NULL;
  79                if (tmp == head)
  80                        break;
  81                p = list_entry(tmp, struct vfsmount, mnt_hash);
  82                if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry)
  83                        break;
  84        }
  85        return p;
  86}
  87
  88static int check_mnt(struct vfsmount *mnt)
  89{
  90        spin_lock(&dcache_lock);
  91        while (mnt->mnt_parent != mnt)
  92                mnt = mnt->mnt_parent;
  93        spin_unlock(&dcache_lock);
  94        return mnt == current->namespace->root;
  95}
  96
  97static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
  98{
  99        old_nd->dentry = mnt->mnt_mountpoint;
 100        old_nd->mnt = mnt->mnt_parent;
 101        mnt->mnt_parent = mnt;
 102        mnt->mnt_mountpoint = mnt->mnt_root;
 103        list_del_init(&mnt->mnt_child);
 104        list_del_init(&mnt->mnt_hash);
 105        old_nd->dentry->d_mounted--;
 106}
 107
 108static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
 109{
 110        mnt->mnt_parent = mntget(nd->mnt);
 111        mnt->mnt_mountpoint = dget(nd->dentry);
 112        list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
 113        list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
 114        nd->dentry->d_mounted++;
 115}
 116
 117static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root)
 118{
 119        struct list_head *next = p->mnt_mounts.next;
 120        if (next == &p->mnt_mounts) {
 121                while (1) {
 122                        if (p == root)
 123                                return NULL;
 124                        next = p->mnt_child.next;
 125                        if (next != &p->mnt_parent->mnt_mounts)
 126                                break;
 127                        p = p->mnt_parent;
 128                }
 129        }
 130        return list_entry(next, struct vfsmount, mnt_child);
 131}
 132
 133static struct vfsmount *
 134clone_mnt(struct vfsmount *old, struct dentry *root)
 135{
 136        struct super_block *sb = old->mnt_sb;
 137        struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
 138
 139        if (mnt) {
 140                mnt->mnt_flags = old->mnt_flags;
 141                atomic_inc(&sb->s_active);
 142                mnt->mnt_sb = sb;
 143                mnt->mnt_root = dget(root);
 144                mnt->mnt_mountpoint = mnt->mnt_root;
 145                mnt->mnt_parent = mnt;
 146        }
 147        return mnt;
 148}
 149
 150void __mntput(struct vfsmount *mnt)
 151{
 152        struct super_block *sb = mnt->mnt_sb;
 153        dput(mnt->mnt_root);
 154        free_vfsmnt(mnt);
 155        kill_super(sb);
 156}
 157
 158/* iterator */
 159static void *m_start(struct seq_file *m, loff_t *pos)
 160{
 161        struct namespace *n = m->private;
 162        struct list_head *p;
 163        loff_t l = *pos;
 164
 165        down_read(&n->sem);
 166        list_for_each(p, &n->list)
 167                if (!l--)
 168                        return list_entry(p, struct vfsmount, mnt_list);
 169        return NULL;
 170}
 171
 172static void *m_next(struct seq_file *m, void *v, loff_t *pos)
 173{
 174        struct namespace *n = m->private;
 175        struct list_head *p = ((struct vfsmount *)v)->mnt_list.next;
 176        (*pos)++;
 177        return p==&n->list ? NULL : list_entry(p, struct vfsmount, mnt_list);
 178}
 179
 180static void m_stop(struct seq_file *m, void *v)
 181{
 182        struct namespace *n = m->private;
 183        up_read(&n->sem);
 184}
 185
 186static inline void mangle(struct seq_file *m, const char *s)
 187{
 188        seq_escape(m, s, " \t\n\\");
 189}
 190
 191static int show_vfsmnt(struct seq_file *m, void *v)
 192{
 193        struct vfsmount *mnt = v;
 194        int err = 0;
 195        static struct proc_fs_info {
 196                int flag;
 197                char *str;
 198        } fs_info[] = {
 199                { MS_SYNCHRONOUS, ",sync" },
 200                { MS_MANDLOCK, ",mand" },
 201                { MS_NOATIME, ",noatime" },
 202                { MS_NODIRATIME, ",nodiratime" },
 203                { 0, NULL }
 204        };
 205        static struct proc_fs_info mnt_info[] = {
 206                { MNT_NOSUID, ",nosuid" },
 207                { MNT_NODEV, ",nodev" },
 208                { MNT_NOEXEC, ",noexec" },
 209                { 0, NULL }
 210        };
 211        struct proc_fs_info *fs_infop;
 212        char *path_buf, *path;
 213
 214        path_buf = (char *) __get_free_page(GFP_KERNEL);
 215        if (!path_buf)
 216                return -ENOMEM;
 217        path = d_path(mnt->mnt_root, mnt, path_buf, PAGE_SIZE);
 218        if (IS_ERR(path)) {
 219                free_page((unsigned long) path_buf);
 220                return PTR_ERR(path);
 221        }
 222
 223        mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
 224        seq_putc(m, ' ');
 225        mangle(m, path);
 226        free_page((unsigned long) path_buf);
 227        seq_putc(m, ' ');
 228        mangle(m, mnt->mnt_sb->s_type->name);
 229        seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
 230        for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
 231                if (mnt->mnt_sb->s_flags & fs_infop->flag)
 232                        seq_puts(m, fs_infop->str);
 233        }
 234        for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
 235                if (mnt->mnt_flags & fs_infop->flag)
 236                        seq_puts(m, fs_infop->str);
 237        }
 238        if (mnt->mnt_sb->s_op->show_options)
 239                err = mnt->mnt_sb->s_op->show_options(m, mnt);
 240        seq_puts(m, " 0 0\n");
 241        return err;
 242}
 243
 244struct seq_operations mounts_op = {
 245        start:  m_start,
 246        next:   m_next,
 247        stop:   m_stop,
 248        show:   show_vfsmnt
 249};
 250
 251/*
 252 * Doesn't take quota and stuff into account. IOW, in some cases it will
 253 * give false negatives. The main reason why it's here is that we need
 254 * a non-destructive way to look for easily umountable filesystems.
 255 */
 256int may_umount(struct vfsmount *mnt)
 257{
 258        if (atomic_read(&mnt->mnt_count) > 2)
 259                return -EBUSY;
 260        return 0;
 261}
 262
 263void umount_tree(struct vfsmount *mnt)
 264{
 265        struct vfsmount *p;
 266        LIST_HEAD(kill);
 267
 268        for (p = mnt; p; p = next_mnt(p, mnt)) {
 269                list_del(&p->mnt_list);
 270                list_add(&p->mnt_list, &kill);
 271        }
 272
 273        while (!list_empty(&kill)) {
 274                mnt = list_entry(kill.next, struct vfsmount, mnt_list);
 275                list_del_init(&mnt->mnt_list);
 276                if (mnt->mnt_parent == mnt) {
 277                        spin_unlock(&dcache_lock);
 278                } else {
 279                        struct nameidata old_nd;
 280                        detach_mnt(mnt, &old_nd);
 281                        spin_unlock(&dcache_lock);
 282                        path_release(&old_nd);
 283                }
 284                mntput(mnt);
 285                spin_lock(&dcache_lock);
 286        }
 287}
 288
 289static int do_umount(struct vfsmount *mnt, int flags)
 290{
 291        struct super_block * sb = mnt->mnt_sb;
 292        int retval = 0;
 293
 294        /*
 295         * If we may have to abort operations to get out of this
 296         * mount, and they will themselves hold resources we must
 297         * allow the fs to do things. In the Unix tradition of
 298         * 'Gee thats tricky lets do it in userspace' the umount_begin
 299         * might fail to complete on the first run through as other tasks
 300         * must return, and the like. Thats for the mount program to worry
 301         * about for the moment.
 302         */
 303
 304        lock_kernel();
 305        if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
 306                sb->s_op->umount_begin(sb);
 307        unlock_kernel();
 308
 309        /*
 310         * No sense to grab the lock for this test, but test itself looks
 311         * somewhat bogus. Suggestions for better replacement?
 312         * Ho-hum... In principle, we might treat that as umount + switch
 313         * to rootfs. GC would eventually take care of the old vfsmount.
 314         * Actually it makes sense, especially if rootfs would contain a
 315         * /reboot - static binary that would close all descriptors and
 316         * call reboot(9). Then init(8) could umount root and exec /reboot.
 317         */
 318        if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
 319                /*
 320                 * Special case for "unmounting" root ...
 321                 * we just try to remount it readonly.
 322                 */
 323                down_write(&sb->s_umount);
 324                if (!(sb->s_flags & MS_RDONLY)) {
 325                        lock_kernel();
 326                        retval = do_remount_sb(sb, MS_RDONLY, 0);
 327                        unlock_kernel();
 328                }
 329                up_write(&sb->s_umount);
 330                return retval;
 331        }
 332
 333        down_write(&current->namespace->sem);
 334        spin_lock(&dcache_lock);
 335
 336        if (atomic_read(&sb->s_active) == 1) {
 337                /* last instance - try to be smart */
 338                spin_unlock(&dcache_lock);
 339                lock_kernel();
 340                DQUOT_OFF(sb);
 341                acct_auto_close(sb->s_dev);
 342                unlock_kernel();
 343                spin_lock(&dcache_lock);
 344        }
 345        retval = -EBUSY;
 346        if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
 347                if (!list_empty(&mnt->mnt_list))
 348                        umount_tree(mnt);
 349                retval = 0;
 350        }
 351        spin_unlock(&dcache_lock);
 352        up_write(&current->namespace->sem);
 353        return retval;
 354}
 355
 356/*
 357 * Now umount can handle mount points as well as block devices.
 358 * This is important for filesystems which use unnamed block devices.
 359 *
 360 * We now support a flag for forced unmount like the other 'big iron'
 361 * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
 362 */
 363
 364asmlinkage long sys_umount(char * name, int flags)
 365{
 366        struct nameidata nd;
 367        int retval;
 368
 369        retval = __user_walk(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd);
 370        if (retval)
 371                goto out;
 372        retval = -EINVAL;
 373        if (nd.dentry != nd.mnt->mnt_root)
 374                goto dput_and_out;
 375        if (!check_mnt(nd.mnt))
 376                goto dput_and_out;
 377
 378        retval = -EPERM;
 379        if (!capable(CAP_SYS_ADMIN))
 380                goto dput_and_out;
 381
 382        retval = do_umount(nd.mnt, flags);
 383dput_and_out:
 384        path_release(&nd);
 385out:
 386        return retval;
 387}
 388
 389/*
 390 *      The 2.0 compatible umount. No flags. 
 391 */
 392 
 393asmlinkage long sys_oldumount(char * name)
 394{
 395        return sys_umount(name,0);
 396}
 397
 398static int mount_is_safe(struct nameidata *nd)
 399{
 400        if (capable(CAP_SYS_ADMIN))
 401                return 0;
 402        return -EPERM;
 403#ifdef notyet
 404        if (S_ISLNK(nd->dentry->d_inode->i_mode))
 405                return -EPERM;
 406        if (nd->dentry->d_inode->i_mode & S_ISVTX) {
 407                if (current->uid != nd->dentry->d_inode->i_uid)
 408                        return -EPERM;
 409        }
 410        if (permission(nd->dentry->d_inode, MAY_WRITE))
 411                return -EPERM;
 412        return 0;
 413#endif
 414}
 415
 416static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
 417{
 418        struct vfsmount *p, *next, *q, *res;
 419        struct nameidata nd;
 420
 421        p = mnt;
 422        res = nd.mnt = q = clone_mnt(p, dentry);
 423        if (!q)
 424                goto Enomem;
 425        q->mnt_parent = q;
 426        q->mnt_mountpoint = p->mnt_mountpoint;
 427
 428        while ( (next = next_mnt(p, mnt)) != NULL) {
 429                while (p != next->mnt_parent) {
 430                        p = p->mnt_parent;
 431                        q = q->mnt_parent;
 432                }
 433                p = next;
 434                nd.mnt = q;
 435                nd.dentry = p->mnt_mountpoint;
 436                q = clone_mnt(p, p->mnt_root);
 437                if (!q)
 438                        goto Enomem;
 439                spin_lock(&dcache_lock);
 440                list_add_tail(&q->mnt_list, &res->mnt_list);
 441                attach_mnt(q, &nd);
 442                spin_unlock(&dcache_lock);
 443        }
 444        return res;
 445Enomem:
 446        if (res) {
 447                spin_lock(&dcache_lock);
 448                umount_tree(res);
 449                spin_unlock(&dcache_lock);
 450        }
 451        return NULL;
 452}
 453
 454static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
 455{
 456        int err;
 457        if (mnt->mnt_sb->s_flags & MS_NOUSER)
 458                return -EINVAL;
 459
 460        if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
 461              S_ISDIR(mnt->mnt_root->d_inode->i_mode))
 462                return -ENOTDIR;
 463
 464        err = -ENOENT;
 465        down(&nd->dentry->d_inode->i_zombie);
 466        if (IS_DEADDIR(nd->dentry->d_inode))
 467                goto out_unlock;
 468
 469        spin_lock(&dcache_lock);
 470        if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) {
 471                struct list_head head;
 472                attach_mnt(mnt, nd);
 473                list_add_tail(&head, &mnt->mnt_list);
 474                list_splice(&head, current->namespace->list.prev);
 475                mntget(mnt);
 476                err = 0;
 477        }
 478        spin_unlock(&dcache_lock);
 479out_unlock:
 480        up(&nd->dentry->d_inode->i_zombie);
 481        return err;
 482}
 483
 484/*
 485 * do loopback mount.
 486 */
 487static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
 488{
 489        struct nameidata old_nd;
 490        struct vfsmount *mnt = NULL;
 491        int err = mount_is_safe(nd);
 492        if (err)
 493                return err;
 494        if (!old_name || !*old_name)
 495                return -EINVAL;
 496        err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
 497        if (err)
 498                return err;
 499
 500        down_write(&current->namespace->sem);
 501        err = -EINVAL;
 502        if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
 503                err = -ENOMEM;
 504                if (recurse)
 505                        mnt = copy_tree(old_nd.mnt, old_nd.dentry);
 506                else
 507                        mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
 508        }
 509
 510        if (mnt) {
 511                err = graft_tree(mnt, nd);
 512                if (err) {
 513                        spin_lock(&dcache_lock);
 514                        umount_tree(mnt);
 515                        spin_unlock(&dcache_lock);
 516                } else
 517                        mntput(mnt);
 518        }
 519
 520        up_write(&current->namespace->sem);
 521        path_release(&old_nd);
 522        return err;
 523}
 524
 525/*
 526 * change filesystem flags. dir should be a physical root of filesystem.
 527 * If you've mounted a non-root directory somewhere and want to do remount
 528 * on it - tough luck.
 529 */
 530
 531static int do_remount(struct nameidata *nd,int flags,int mnt_flags,void *data)
 532{
 533        int err;
 534        struct super_block * sb = nd->mnt->mnt_sb;
 535
 536        if (!capable(CAP_SYS_ADMIN))
 537                return -EPERM;
 538
 539        if (!check_mnt(nd->mnt))
 540                return -EINVAL;
 541
 542        if (nd->dentry != nd->mnt->mnt_root)
 543                return -EINVAL;
 544
 545        down_write(&sb->s_umount);
 546        err = do_remount_sb(sb, flags, data);
 547        if (!err)
 548                nd->mnt->mnt_flags=mnt_flags;
 549        up_write(&sb->s_umount);
 550        return err;
 551}
 552
 553static int do_move_mount(struct nameidata *nd, char *old_name)
 554{
 555        struct nameidata old_nd, parent_nd;
 556        struct vfsmount *p;
 557        int err = 0;
 558        if (!capable(CAP_SYS_ADMIN))
 559                return -EPERM;
 560        if (!old_name || !*old_name)
 561                return -EINVAL;
 562        err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
 563        if (err)
 564                return err;
 565
 566        down_write(&current->namespace->sem);
 567        while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
 568                ;
 569        err = -EINVAL;
 570        if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
 571                goto out;
 572
 573        err = -ENOENT;
 574        down(&nd->dentry->d_inode->i_zombie);
 575        if (IS_DEADDIR(nd->dentry->d_inode))
 576                goto out1;
 577
 578        spin_lock(&dcache_lock);
 579        if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
 580                goto out2;
 581
 582        err = -EINVAL;
 583        if (old_nd.dentry != old_nd.mnt->mnt_root)
 584                goto out2;
 585
 586        if (old_nd.mnt == old_nd.mnt->mnt_parent)
 587                goto out2;
 588
 589        if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
 590              S_ISDIR(old_nd.dentry->d_inode->i_mode))
 591                goto out2;
 592
 593        err = -ELOOP;
 594        for (p = nd->mnt; p->mnt_parent!=p; p = p->mnt_parent)
 595                if (p == old_nd.mnt)
 596                        goto out2;
 597        err = 0;
 598
 599        detach_mnt(old_nd.mnt, &parent_nd);
 600        attach_mnt(old_nd.mnt, nd);
 601out2:
 602        spin_unlock(&dcache_lock);
 603out1:
 604        up(&nd->dentry->d_inode->i_zombie);
 605out:
 606        up_write(&current->namespace->sem);
 607        if (!err)
 608                path_release(&parent_nd);
 609        path_release(&old_nd);
 610        return err;
 611}
 612
 613static int do_add_mount(struct nameidata *nd, char *type, int flags,
 614                        int mnt_flags, char *name, void *data)
 615{
 616        struct vfsmount *mnt;
 617        int err;
 618
 619        if (!type || !memchr(type, 0, PAGE_SIZE))
 620                return -EINVAL;
 621
 622        /* we need capabilities... */
 623        if (!capable(CAP_SYS_ADMIN))
 624                return -EPERM;
 625
 626        mnt = do_kern_mount(type, flags, name, data);
 627        err = PTR_ERR(mnt);
 628        if (IS_ERR(mnt))
 629                goto out;
 630
 631        down_write(&current->namespace->sem);
 632        /* Something was mounted here while we slept */
 633        while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
 634                ;
 635        err = -EINVAL;
 636        if (!check_mnt(nd->mnt))
 637                goto unlock;
 638
 639        /* Refuse the same filesystem on the same mount point */
 640        err = -EBUSY;
 641        if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
 642                goto unlock;
 643
 644        mnt->mnt_flags = mnt_flags;
 645        err = graft_tree(mnt, nd);
 646unlock:
 647        up_write(&current->namespace->sem);
 648        mntput(mnt);
 649out:
 650        return err;
 651}
 652
 653static int copy_mount_options (const void *data, unsigned long *where)
 654{
 655        int i;
 656        unsigned long page;
 657        unsigned long size;
 658        
 659        *where = 0;
 660        if (!data)
 661                return 0;
 662
 663        if (!(page = __get_free_page(GFP_KERNEL)))
 664                return -ENOMEM;
 665
 666        /* We only care that *some* data at the address the user
 667         * gave us is valid.  Just in case, we'll zero
 668         * the remainder of the page.
 669         */
 670        /* copy_from_user cannot cross TASK_SIZE ! */
 671        size = TASK_SIZE - (unsigned long)data;
 672        if (size > PAGE_SIZE)
 673                size = PAGE_SIZE;
 674
 675        i = size - copy_from_user((void *)page, data, size);
 676        if (!i) {
 677                free_page(page); 
 678                return -EFAULT;
 679        }
 680        if (i != PAGE_SIZE)
 681                memset((char *)page + i, 0, PAGE_SIZE - i);
 682        *where = page;
 683        return 0;
 684}
 685
 686/*
 687 * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
 688 * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
 689 *
 690 * data is a (void *) that can point to any structure up to
 691 * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
 692 * information (or be NULL).
 693 *
 694 * Pre-0.97 versions of mount() didn't have a flags word.
 695 * When the flags word was introduced its top half was required
 696 * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
 697 * Therefore, if this magic number is present, it carries no information
 698 * and must be discarded.
 699 */
 700long do_mount(char * dev_name, char * dir_name, char *type_page,
 701                  unsigned long flags, void *data_page)
 702{
 703        struct nameidata nd;
 704        int retval = 0;
 705        int mnt_flags = 0;
 706
 707        /* Discard magic */
 708        if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
 709                flags &= ~MS_MGC_MSK;
 710
 711        /* Basic sanity checks */
 712
 713        if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))
 714                return -EINVAL;
 715        if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
 716                return -EINVAL;
 717
 718        if (data_page)
 719                ((char *)data_page)[PAGE_SIZE - 1] = 0;
 720
 721        /* Separate the per-mountpoint flags */
 722        if (flags & MS_NOSUID)
 723                mnt_flags |= MNT_NOSUID;
 724        if (flags & MS_NODEV)
 725                mnt_flags |= MNT_NODEV;
 726        if (flags & MS_NOEXEC)
 727                mnt_flags |= MNT_NOEXEC;
 728        flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
 729
 730        /* ... and get the mountpoint */
 731        retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 732        if (retval)
 733                return retval;
 734
 735        if (flags & MS_REMOUNT)
 736                retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
 737                                    data_page);
 738        else if (flags & MS_BIND)
 739                retval = do_loopback(&nd, dev_name, flags & MS_REC);
 740        else if (flags & MS_MOVE)
 741                retval = do_move_mount(&nd, dev_name);
 742        else
 743                retval = do_add_mount(&nd, type_page, flags, mnt_flags,
 744                                      dev_name, data_page);
 745        path_release(&nd);
 746        return retval;
 747}
 748
 749int copy_namespace(int flags, struct task_struct *tsk)
 750{
 751        struct namespace *namespace = tsk->namespace;
 752        struct namespace *new_ns;
 753        struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
 754        struct fs_struct *fs = tsk->fs;
 755
 756        if (!namespace)
 757                return 0;
 758
 759        get_namespace(namespace);
 760
 761        if (! (flags & CLONE_NEWNS))
 762                return 0;
 763
 764        if (!capable(CAP_SYS_ADMIN)) {
 765                put_namespace(namespace);
 766                return -EPERM;
 767        }
 768
 769        new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
 770        if (!new_ns)
 771                goto out;
 772
 773        atomic_set(&new_ns->count, 1);
 774        init_rwsem(&new_ns->sem);
 775        new_ns->root = NULL;
 776        INIT_LIST_HEAD(&new_ns->list);
 777
 778        down_write(&tsk->namespace->sem);
 779        /* First pass: copy the tree topology */
 780        new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
 781        spin_lock(&dcache_lock);
 782        list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
 783        spin_unlock(&dcache_lock);
 784
 785        /* Second pass: switch the tsk->fs->* elements */
 786        if (fs) {
 787                struct vfsmount *p, *q;
 788                write_lock(&fs->lock);
 789
 790                p = namespace->root;
 791                q = new_ns->root;
 792                while (p) {
 793                        if (p == fs->rootmnt) {
 794                                rootmnt = p;
 795                                fs->rootmnt = mntget(q);
 796                        }
 797                        if (p == fs->pwdmnt) {
 798                                pwdmnt = p;
 799                                fs->pwdmnt = mntget(q);
 800                        }
 801                        if (p == fs->altrootmnt) {
 802                                altrootmnt = p;
 803                                fs->altrootmnt = mntget(q);
 804                        }
 805                        p = next_mnt(p, namespace->root);
 806                        q = next_mnt(q, new_ns->root);
 807                }
 808                write_unlock(&fs->lock);
 809        }
 810        up_write(&tsk->namespace->sem);
 811
 812        tsk->namespace = new_ns;
 813
 814        if (rootmnt)
 815                mntput(rootmnt);
 816        if (pwdmnt)
 817                mntput(pwdmnt);
 818        if (altrootmnt)
 819                mntput(altrootmnt);
 820
 821        put_namespace(namespace);
 822        return 0;
 823
 824out:
 825        put_namespace(namespace);
 826        return -ENOMEM;
 827}
 828
 829asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
 830                          unsigned long flags, void * data)
 831{
 832        int retval;
 833        unsigned long data_page;
 834        unsigned long type_page;
 835        unsigned long dev_page;
 836        char *dir_page;
 837
 838        retval = copy_mount_options (type, &type_page);
 839        if (retval < 0)
 840                return retval;
 841
 842        dir_page = getname(dir_name);
 843        retval = PTR_ERR(dir_page);
 844        if (IS_ERR(dir_page))
 845                goto out1;
 846
 847        retval = copy_mount_options (dev_name, &dev_page);
 848        if (retval < 0)
 849                goto out2;
 850
 851        retval = copy_mount_options (data, &data_page);
 852        if (retval < 0)
 853                goto out3;
 854
 855        lock_kernel();
 856        retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
 857                          flags, (void*)data_page);
 858        unlock_kernel();
 859        free_page(data_page);
 860
 861out3:
 862        free_page(dev_page);
 863out2:
 864        putname(dir_page);
 865out1:
 866        free_page(type_page);
 867        return retval;
 868}
 869
 870static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
 871{
 872        struct task_struct *p;
 873        struct fs_struct *fs;
 874
 875        read_lock(&tasklist_lock);
 876        for_each_task(p) {
 877                task_lock(p);
 878                fs = p->fs;
 879                if (fs) {
 880                        atomic_inc(&fs->count);
 881                        task_unlock(p);
 882                        if (fs->root==old_nd->dentry&&fs->rootmnt==old_nd->mnt)
 883                                set_fs_root(fs, new_nd->mnt, new_nd->dentry);
 884                        if (fs->pwd==old_nd->dentry&&fs->pwdmnt==old_nd->mnt)
 885                                set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
 886                        put_fs_struct(fs);
 887                } else
 888                        task_unlock(p);
 889        }
 890        read_unlock(&tasklist_lock);
 891}
 892
 893/*
 894 * Moves the current root to put_root, and sets root/cwd of all processes
 895 * which had them on the old root to new_root.
 896 *
 897 * Note:
 898 *  - we don't move root/cwd if they are not at the root (reason: if something
 899 *    cared enough to change them, it's probably wrong to force them elsewhere)
 900 *  - it's okay to pick a root that isn't the root of a file system, e.g.
 901 *    /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
 902 *    though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
 903 *    first.
 904 */
 905
 906asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
 907{
 908        struct vfsmount *tmp;
 909        struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
 910        int error;
 911
 912        if (!capable(CAP_SYS_ADMIN))
 913                return -EPERM;
 914
 915        lock_kernel();
 916
 917        error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
 918        if (error)
 919                goto out0;
 920        error = -EINVAL;
 921        if (!check_mnt(new_nd.mnt))
 922                goto out1;
 923
 924        error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
 925        if (error)
 926                goto out1;
 927
 928        read_lock(&current->fs->lock);
 929        user_nd.mnt = mntget(current->fs->rootmnt);
 930        user_nd.dentry = dget(current->fs->root);
 931        read_unlock(&current->fs->lock);
 932        down_write(&current->namespace->sem);
 933        down(&old_nd.dentry->d_inode->i_zombie);
 934        error = -EINVAL;
 935        if (!check_mnt(user_nd.mnt))
 936                goto out2;
 937        error = -ENOENT;
 938        if (IS_DEADDIR(new_nd.dentry->d_inode))
 939                goto out2;
 940        if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
 941                goto out2;
 942        if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
 943                goto out2;
 944        error = -EBUSY;
 945        if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
 946                goto out2; /* loop */
 947        error = -EINVAL;
 948        if (user_nd.mnt->mnt_root != user_nd.dentry)
 949                goto out2;
 950        if (new_nd.mnt->mnt_root != new_nd.dentry)
 951                goto out2; /* not a mountpoint */
 952        tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
 953        spin_lock(&dcache_lock);
 954        if (tmp != new_nd.mnt) {
 955                for (;;) {
 956                        if (tmp->mnt_parent == tmp)
 957                                goto out3;
 958                        if (tmp->mnt_parent == new_nd.mnt)
 959                                break;
 960                        tmp = tmp->mnt_parent;
 961                }
 962                if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
 963                        goto out3;
 964        } else if (!is_subdir(old_nd.dentry, new_nd.dentry))
 965                goto out3;
 966        detach_mnt(new_nd.mnt, &parent_nd);
 967        detach_mnt(user_nd.mnt, &root_parent);
 968        attach_mnt(user_nd.mnt, &old_nd);
 969        attach_mnt(new_nd.mnt, &root_parent);
 970        spin_unlock(&dcache_lock);
 971        chroot_fs_refs(&user_nd, &new_nd);
 972        error = 0;
 973        path_release(&root_parent);
 974        path_release(&parent_nd);
 975out2:
 976        up(&old_nd.dentry->d_inode->i_zombie);
 977        up_write(&current->namespace->sem);
 978        path_release(&user_nd);
 979        path_release(&old_nd);
 980out1:
 981        path_release(&new_nd);
 982out0:
 983        unlock_kernel();
 984        return error;
 985out3:
 986        spin_unlock(&dcache_lock);
 987        goto out2;
 988}
 989
 990static void __init init_mount_tree(void)
 991{
 992        struct vfsmount *mnt;
 993        struct namespace *namespace;
 994        struct task_struct *p;
 995
 996        mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
 997        if (IS_ERR(mnt))
 998                panic("Can't create rootfs");
 999        namespace = kmalloc(sizeof(*namespace), GFP_KERNEL);
1000        if (!namespace)
1001                panic("Can't allocate initial namespace");
1002        atomic_set(&namespace->count, 1);
1003        INIT_LIST_HEAD(&namespace->list);
1004        init_rwsem(&namespace->sem);
1005        list_add(&mnt->mnt_list, &namespace->list);
1006        namespace->root = mnt;
1007
1008        init_task.namespace = namespace;
1009        read_lock(&tasklist_lock);
1010        for_each_task(p) {
1011                get_namespace(namespace);
1012                p->namespace = namespace;
1013        }
1014        read_unlock(&tasklist_lock);
1015
1016        set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
1017        set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
1018}
1019
1020void __init mnt_init(unsigned long mempages)
1021{
1022        struct list_head *d;
1023        unsigned long order;
1024        unsigned int nr_hash;
1025        int i;
1026
1027        mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
1028                                        0, SLAB_HWCACHE_ALIGN, NULL, NULL);
1029        if (!mnt_cache)
1030                panic("Cannot create vfsmount cache");
1031
1032        /* using single pointer list heads would save half of the hash table. */
1033        order = 0; 
1034        mount_hashtable = (struct list_head *)
1035                __get_free_pages(GFP_ATOMIC, order);
1036
1037        if (!mount_hashtable)
1038                panic("Failed to allocate mount hash table\n");
1039
1040        /*
1041         * Find the power-of-two list-heads that can fit into the allocation..
1042         * We don't guarantee that "sizeof(struct list_head)" is necessarily
1043         * a power-of-two.
1044         */
1045        nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct list_head);
1046        hash_bits = 0;
1047        do {
1048                hash_bits++;
1049        } while ((nr_hash >> hash_bits) != 0);
1050        hash_bits--;
1051
1052        /*
1053         * Re-calculate the actual number of entries and the mask
1054         * from the number of bits we can fit.
1055         */
1056        nr_hash = 1UL << hash_bits;
1057        hash_mask = nr_hash-1;
1058
1059        printk(KERN_INFO "Mount cache hash table entries: %d"
1060                " (order: %ld, %ld bytes)\n",
1061                nr_hash, order, (PAGE_SIZE << order));
1062
1063        /* And initialize the newly allocated array */
1064        d = mount_hashtable;
1065        i = nr_hash;
1066        do {
1067                INIT_LIST_HEAD(d);
1068                d++;
1069                i--;
1070        } while (i);
1071        init_rootfs();
1072        init_mount_tree();
1073}
1074
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.