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