linux-old/fs/super.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/super.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 *  super.c contains code to handle: - mount structures
   7 *                                   - super-block tables
   8 *                                   - filesystem drivers list
   9 *                                   - mount system call
  10 *                                   - umount system call
  11 *                                   - ustat system call
  12 *
  13 * GK 2/5/95  -  Changed to support mounting the root fs via NFS
  14 *
  15 *  Added kerneld support: Jacques Gelinas and Bjorn Ekwall
  16 *  Added change_root: Werner Almesberger & Hans Lermen, Feb '96
  17 *  Added options to /proc/mounts:
  18 *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
  19 *  Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
  20 *  Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
  21 */
  22
  23#include <linux/config.h>
  24#include <linux/slab.h>
  25#include <linux/locks.h>
  26#include <linux/smp_lock.h>
  27#include <linux/devfs_fs_kernel.h>
  28#include <linux/major.h>
  29#include <linux/acct.h>
  30#include <linux/quotaops.h>
  31
  32#include <asm/uaccess.h>
  33
  34#include <linux/kmod.h>
  35#define __NO_VERSION__
  36#include <linux/module.h>
  37
  38LIST_HEAD(super_blocks);
  39spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
  40
  41/*
  42 * Handling of filesystem drivers list.
  43 * Rules:
  44 *      Inclusion to/removals from/scanning of list are protected by spinlock.
  45 *      During the unload module must call unregister_filesystem().
  46 *      We can access the fields of list element if:
  47 *              1) spinlock is held or
  48 *              2) we hold the reference to the module.
  49 *      The latter can be guaranteed by call of try_inc_mod_count(); if it
  50 *      returned 0 we must skip the element, otherwise we got the reference.
  51 *      Once the reference is obtained we can drop the spinlock.
  52 */
  53
  54static struct file_system_type *file_systems;
  55static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
  56
  57/* WARNING: This can be used only if we _already_ own a reference */
  58static void get_filesystem(struct file_system_type *fs)
  59{
  60        if (fs->owner)
  61                __MOD_INC_USE_COUNT(fs->owner);
  62}
  63
  64static void put_filesystem(struct file_system_type *fs)
  65{
  66        if (fs->owner)
  67                __MOD_DEC_USE_COUNT(fs->owner);
  68}
  69
  70static struct file_system_type **find_filesystem(const char *name)
  71{
  72        struct file_system_type **p;
  73        for (p=&file_systems; *p; p=&(*p)->next)
  74                if (strcmp((*p)->name,name) == 0)
  75                        break;
  76        return p;
  77}
  78
  79/**
  80 *      register_filesystem - register a new filesystem
  81 *      @fs: the file system structure
  82 *
  83 *      Adds the file system passed to the list of file systems the kernel
  84 *      is aware of for mount and other syscalls. Returns 0 on success,
  85 *      or a negative errno code on an error.
  86 *
  87 *      The &struct file_system_type that is passed is linked into the kernel 
  88 *      structures and must not be freed until the file system has been
  89 *      unregistered.
  90 */
  91 
  92int register_filesystem(struct file_system_type * fs)
  93{
  94        int res = 0;
  95        struct file_system_type ** p;
  96
  97        if (!fs)
  98                return -EINVAL;
  99        if (fs->next)
 100                return -EBUSY;
 101        INIT_LIST_HEAD(&fs->fs_supers);
 102        write_lock(&file_systems_lock);
 103        p = find_filesystem(fs->name);
 104        if (*p)
 105                res = -EBUSY;
 106        else
 107                *p = fs;
 108        write_unlock(&file_systems_lock);
 109        return res;
 110}
 111
 112/**
 113 *      unregister_filesystem - unregister a file system
 114 *      @fs: filesystem to unregister
 115 *
 116 *      Remove a file system that was previously successfully registered
 117 *      with the kernel. An error is returned if the file system is not found.
 118 *      Zero is returned on a success.
 119 *      
 120 *      Once this function has returned the &struct file_system_type structure
 121 *      may be freed or reused.
 122 */
 123 
 124int unregister_filesystem(struct file_system_type * fs)
 125{
 126        struct file_system_type ** tmp;
 127
 128        write_lock(&file_systems_lock);
 129        tmp = &file_systems;
 130        while (*tmp) {
 131                if (fs == *tmp) {
 132                        *tmp = fs->next;
 133                        fs->next = NULL;
 134                        write_unlock(&file_systems_lock);
 135                        return 0;
 136                }
 137                tmp = &(*tmp)->next;
 138        }
 139        write_unlock(&file_systems_lock);
 140        return -EINVAL;
 141}
 142
 143static int fs_index(const char * __name)
 144{
 145        struct file_system_type * tmp;
 146        char * name;
 147        int err, index;
 148
 149        name = getname(__name);
 150        err = PTR_ERR(name);
 151        if (IS_ERR(name))
 152                return err;
 153
 154        err = -EINVAL;
 155        read_lock(&file_systems_lock);
 156        for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
 157                if (strcmp(tmp->name,name) == 0) {
 158                        err = index;
 159                        break;
 160                }
 161        }
 162        read_unlock(&file_systems_lock);
 163        putname(name);
 164        return err;
 165}
 166
 167static int fs_name(unsigned int index, char * buf)
 168{
 169        struct file_system_type * tmp;
 170        int len, res;
 171
 172        read_lock(&file_systems_lock);
 173        for (tmp = file_systems; tmp; tmp = tmp->next, index--)
 174                if (index <= 0 && try_inc_mod_count(tmp->owner))
 175                                break;
 176        read_unlock(&file_systems_lock);
 177        if (!tmp)
 178                return -EINVAL;
 179
 180        /* OK, we got the reference, so we can safely block */
 181        len = strlen(tmp->name) + 1;
 182        res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
 183        put_filesystem(tmp);
 184        return res;
 185}
 186
 187static int fs_maxindex(void)
 188{
 189        struct file_system_type * tmp;
 190        int index;
 191
 192        read_lock(&file_systems_lock);
 193        for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
 194                ;
 195        read_unlock(&file_systems_lock);
 196        return index;
 197}
 198
 199/*
 200 * Whee.. Weird sysv syscall. 
 201 */
 202asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2)
 203{
 204        int retval = -EINVAL;
 205
 206        switch (option) {
 207                case 1:
 208                        retval = fs_index((const char *) arg1);
 209                        break;
 210
 211                case 2:
 212                        retval = fs_name(arg1, (char *) arg2);
 213                        break;
 214
 215                case 3:
 216                        retval = fs_maxindex();
 217                        break;
 218        }
 219        return retval;
 220}
 221
 222int get_filesystem_list(char * buf)
 223{
 224        int len = 0;
 225        struct file_system_type * tmp;
 226
 227        read_lock(&file_systems_lock);
 228        tmp = file_systems;
 229        while (tmp && len < PAGE_SIZE - 80) {
 230                len += sprintf(buf+len, "%s\t%s\n",
 231                        (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
 232                        tmp->name);
 233                tmp = tmp->next;
 234        }
 235        read_unlock(&file_systems_lock);
 236        return len;
 237}
 238
 239struct file_system_type *get_fs_type(const char *name)
 240{
 241        struct file_system_type *fs;
 242        
 243        read_lock(&file_systems_lock);
 244        fs = *(find_filesystem(name));
 245        if (fs && !try_inc_mod_count(fs->owner))
 246                fs = NULL;
 247        read_unlock(&file_systems_lock);
 248        if (!fs && (request_module(name) == 0)) {
 249                read_lock(&file_systems_lock);
 250                fs = *(find_filesystem(name));
 251                if (fs && !try_inc_mod_count(fs->owner))
 252                        fs = NULL;
 253                read_unlock(&file_systems_lock);
 254        }
 255        return fs;
 256}
 257
 258/**
 259 *      alloc_super     -       create new superblock
 260 *
 261 *      Allocates and initializes a new &struct super_block.  alloc_super()
 262 *      returns a pointer new superblock or %NULL if allocation had failed.
 263 */
 264static struct super_block *alloc_super(void)
 265{
 266        static struct super_operations empty_sops = {};
 267        struct super_block *s = kmalloc(sizeof(struct super_block),  GFP_USER);
 268        if (s) {
 269                memset(s, 0, sizeof(struct super_block));
 270                INIT_LIST_HEAD(&s->s_dirty);
 271                INIT_LIST_HEAD(&s->s_locked_inodes);
 272                INIT_LIST_HEAD(&s->s_files);
 273                INIT_LIST_HEAD(&s->s_instances);
 274                init_rwsem(&s->s_umount);
 275                sema_init(&s->s_lock, 1);
 276                down_write(&s->s_umount);
 277                s->s_count = S_BIAS;
 278                atomic_set(&s->s_active, 1);
 279                sema_init(&s->s_vfs_rename_sem,1);
 280                sema_init(&s->s_nfsd_free_path_sem,1);
 281                sema_init(&s->s_dquot.dqio_sem, 1);
 282                sema_init(&s->s_dquot.dqoff_sem, 1);
 283                s->s_maxbytes = MAX_NON_LFS;
 284                s->s_op = &empty_sops;
 285                s->dq_op = sb_dquot_ops;
 286                s->s_qcop = sb_quotactl_ops;
 287        }
 288        return s;
 289}
 290
 291/**
 292 *      destroy_super   -       frees a superblock
 293 *      @s: superblock to free
 294 *
 295 *      Frees a superblock.
 296 */
 297static inline void destroy_super(struct super_block *s)
 298{
 299        kfree(s);
 300}
 301
 302/* Superblock refcounting  */
 303
 304/**
 305 *      deactivate_super        -       turn an active reference into temporary
 306 *      @s: superblock to deactivate
 307 *
 308 *      Turns an active reference into temporary one.  Returns 0 if there are
 309 *      other active references, 1 if we had deactivated the last one.
 310 */
 311static inline int deactivate_super(struct super_block *s)
 312{
 313        if (!atomic_dec_and_lock(&s->s_active, &sb_lock))
 314                return 0;
 315        s->s_count -= S_BIAS-1;
 316        spin_unlock(&sb_lock);
 317        return 1;
 318}
 319
 320/**
 321 *      put_super       -       drop a temporary reference to superblock
 322 *      @s: superblock in question
 323 *
 324 *      Drops a temporary reference, frees superblock if there's no
 325 *      references left.
 326 */
 327static inline void put_super(struct super_block *s)
 328{
 329        spin_lock(&sb_lock);
 330        if (!--s->s_count)
 331                destroy_super(s);
 332        spin_unlock(&sb_lock);
 333}
 334
 335/**
 336 *      grab_super      - acquire an active reference
 337 *      @s      - reference we are trying to make active
 338 *
 339 *      Tries to acquire an active reference.  grab_super() is used when we
 340 *      had just found a superblock in super_blocks or fs_type->fs_supers
 341 *      and want to turn it into a full-blown active reference.  grab_super()
 342 *      is called with sb_lock held and drops it.  Returns 1 in case of
 343 *      success, 0 if we had failed (superblock contents was already dead or
 344 *      dying when grab_super() had been called).
 345 */
 346static int grab_super(struct super_block *s)
 347{
 348        s->s_count++;
 349        spin_unlock(&sb_lock);
 350        down_write(&s->s_umount);
 351        if (s->s_root) {
 352                spin_lock(&sb_lock);
 353                if (s->s_count > S_BIAS) {
 354                        atomic_inc(&s->s_active);
 355                        s->s_count--;
 356                        spin_unlock(&sb_lock);
 357                        return 1;
 358                }
 359                spin_unlock(&sb_lock);
 360        }
 361        up_write(&s->s_umount);
 362        put_super(s);
 363        return 0;
 364}
 365 
 366/**
 367 *      insert_super    -       put superblock on the lists
 368 *      @s:     superblock in question
 369 *      @type:  filesystem type it will belong to
 370 *
 371 *      Associates superblock with fs type and puts it on per-type and global
 372 *      superblocks' lists.  Should be called with sb_lock held; drops it.
 373 */
 374static void insert_super(struct super_block *s, struct file_system_type *type)
 375{
 376        s->s_type = type;
 377        list_add(&s->s_list, super_blocks.prev);
 378        list_add(&s->s_instances, &type->fs_supers);
 379        spin_unlock(&sb_lock);
 380        get_filesystem(type);
 381}
 382
 383static void put_anon_dev(kdev_t dev);
 384
 385/**
 386 *      remove_super    -       makes superblock unreachable
 387 *      @s:     superblock in question
 388 *
 389 *      Removes superblock from the lists, unlocks it, drop the reference
 390 *      and releases the hosting device.  @s should have no active
 391 *      references by that time and after remove_super() it's essentially
 392 *      in rundown mode - all remaining references are temporary, no new
 393 *      reference of any sort are going to appear and all holders of
 394 *      temporary ones will eventually drop them.  At that point superblock
 395 *      itself will be destroyed; all its contents is already gone.
 396 */
 397static void remove_super(struct super_block *s)
 398{
 399        kdev_t dev = s->s_dev;
 400        struct block_device *bdev = s->s_bdev;
 401        struct file_system_type *fs = s->s_type;
 402
 403        spin_lock(&sb_lock);
 404        list_del(&s->s_list);
 405        list_del(&s->s_instances);
 406        spin_unlock(&sb_lock);
 407        up_write(&s->s_umount);
 408        put_super(s);
 409        put_filesystem(fs);
 410        if (bdev)
 411                blkdev_put(bdev, BDEV_FS);
 412        else
 413                put_anon_dev(dev);
 414}
 415
 416struct vfsmount *alloc_vfsmnt(char *name);
 417void free_vfsmnt(struct vfsmount *mnt);
 418
 419static inline struct super_block * find_super(kdev_t dev)
 420{
 421        struct list_head *p;
 422
 423        list_for_each(p, &super_blocks) {
 424                struct super_block * s = sb_entry(p);
 425                if (s->s_dev == dev) {
 426                        s->s_count++;
 427                        return s;
 428                }
 429        }
 430        return NULL;
 431}
 432
 433void drop_super(struct super_block *sb)
 434{
 435        up_read(&sb->s_umount);
 436        put_super(sb);
 437}
 438
 439static inline void write_super(struct super_block *sb)
 440{
 441        lock_super(sb);
 442        if (sb->s_root && sb->s_dirt)
 443                if (sb->s_op && sb->s_op->write_super)
 444                        sb->s_op->write_super(sb);
 445        unlock_super(sb);
 446}
 447
 448/*
 449 * Note: check the dirty flag before waiting, so we don't
 450 * hold up the sync while mounting a device. (The newly
 451 * mounted device won't need syncing.)
 452 */
 453void sync_supers(kdev_t dev, int wait)
 454{
 455        struct super_block * sb;
 456
 457        if (dev) {
 458                sb = get_super(dev);
 459                if (sb) {
 460                        if (sb->s_dirt)
 461                                write_super(sb);
 462                        if (wait && sb->s_op && sb->s_op->sync_fs)
 463                                sb->s_op->sync_fs(sb);
 464                        drop_super(sb);
 465                }
 466                return;
 467        }
 468restart:
 469        spin_lock(&sb_lock);
 470        sb = sb_entry(super_blocks.next);
 471        while (sb != sb_entry(&super_blocks))
 472                if (sb->s_dirt) {
 473                        sb->s_count++;
 474                        spin_unlock(&sb_lock);
 475                        down_read(&sb->s_umount);
 476                        write_super(sb);
 477                        if (wait && sb->s_root && sb->s_op && sb->s_op->sync_fs)
 478                                sb->s_op->sync_fs(sb);
 479                        drop_super(sb);
 480                        goto restart;
 481                } else
 482                        sb = sb_entry(sb->s_list.next);
 483        spin_unlock(&sb_lock);
 484}
 485
 486/**
 487 *      get_super       -       get the superblock of a device
 488 *      @dev: device to get the superblock for
 489 *      
 490 *      Scans the superblock list and finds the superblock of the file system
 491 *      mounted on the device given. %NULL is returned if no match is found.
 492 */
 493 
 494struct super_block * get_super(kdev_t dev)
 495{
 496        struct super_block * s;
 497
 498        if (!dev)
 499                return NULL;
 500restart:
 501        spin_lock(&sb_lock);
 502        s = find_super(dev);
 503        if (s) {
 504                spin_unlock(&sb_lock);
 505                down_read(&s->s_umount);
 506                if (s->s_root)
 507                        return s;
 508                drop_super(s);
 509                goto restart;
 510        }
 511        spin_unlock(&sb_lock);
 512        return NULL;
 513}
 514
 515asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf)
 516{
 517        struct super_block *s;
 518        struct ustat tmp;
 519        struct statfs sbuf;
 520        int err = -EINVAL;
 521
 522        s = get_super(to_kdev_t(dev));
 523        if (s == NULL)
 524                goto out;
 525        err = vfs_statfs(s, &sbuf);
 526        drop_super(s);
 527        if (err)
 528                goto out;
 529
 530        memset(&tmp,0,sizeof(struct ustat));
 531        tmp.f_tfree = sbuf.f_bfree;
 532        tmp.f_tinode = sbuf.f_ffree;
 533
 534        err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0;
 535out:
 536        return err;
 537}
 538
 539/**
 540 *      do_remount_sb   -       asks filesystem to change mount options.
 541 *      @sb:    superblock in question
 542 *      @flags: numeric part of options
 543 *      @data:  the rest of options
 544 *
 545 *      Alters the mount options of a mounted file system.
 546 */
 547int do_remount_sb(struct super_block *sb, int flags, void *data)
 548{
 549        int retval;
 550        
 551        if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
 552                return -EACCES;
 553                /*flags |= MS_RDONLY;*/
 554        if (flags & MS_RDONLY)
 555                acct_auto_close(sb->s_dev);
 556        shrink_dcache_sb(sb);
 557        fsync_super(sb);
 558        /* If we are remounting RDONLY, make sure there are no rw files open */
 559        if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
 560                if (!fs_may_remount_ro(sb))
 561                        return -EBUSY;
 562        if (sb->s_op && sb->s_op->remount_fs) {
 563                lock_super(sb);
 564                retval = sb->s_op->remount_fs(sb, &flags, data);
 565                unlock_super(sb);
 566                if (retval)
 567                        return retval;
 568        }
 569        sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
 570        return 0;
 571}
 572
 573/*
 574 * Unnamed block devices are dummy devices used by virtual
 575 * filesystems which don't use real block-devices.  -- jrs
 576 */
 577
 578enum {Max_anon = 256};
 579static unsigned long unnamed_dev_in_use[Max_anon/(8*sizeof(unsigned long))];
 580static spinlock_t unnamed_dev_lock = SPIN_LOCK_UNLOCKED;/* protects the above */
 581
 582/**
 583 *      put_anon_dev    -       release anonymous device number.
 584 *      @dev:   device in question
 585 */
 586static void put_anon_dev(kdev_t dev)
 587{
 588        spin_lock(&unnamed_dev_lock);
 589        clear_bit(MINOR(dev), unnamed_dev_in_use);
 590        spin_unlock(&unnamed_dev_lock);
 591}
 592
 593/**
 594 *      get_anon_super  -       allocate a superblock for non-device fs
 595 *      @type:          filesystem type
 596 *      @compare:       check if existing superblock is what we want
 597 *      @data:          argument for @compare.
 598 *
 599 *      get_anon_super is a helper for non-blockdevice filesystems.
 600 *      It either finds and returns one of the superblocks of given type
 601 *      (if it can find one that would satisfy caller) or creates a new
 602 *      one.  In the either case we return an active reference to superblock
 603 *      with ->s_umount locked.  If superblock is new it gets a new
 604 *      anonymous device allocated for it and is inserted into lists -
 605 *      other initialization is left to caller.
 606 *
 607 *      Rather than duplicating all that logics every time when
 608 *      we want something that doesn't fit "nodev" and "single" we pull
 609 *      the relevant code into common helper and let get_sb_...() call
 610 *      it.
 611 *
 612 *      NB: get_sb_...() is going to become an fs type method, with
 613 *      current ->read_super() becoming a callback used by common instances.
 614 */
 615struct super_block *get_anon_super(struct file_system_type *type,
 616        int (*compare)(struct super_block *,void *), void *data)
 617{
 618        struct super_block *s = alloc_super();
 619        kdev_t dev;
 620        struct list_head *p;
 621
 622        if (!s)
 623                return ERR_PTR(-ENOMEM);
 624
 625retry:
 626        spin_lock(&sb_lock);
 627        if (compare) list_for_each(p, &type->fs_supers) {
 628                struct super_block *old;
 629                old = list_entry(p, struct super_block, s_instances);
 630                if (!compare(old, data))
 631                        continue;
 632                if (!grab_super(old))
 633                        goto retry;
 634                destroy_super(s);
 635                return old;
 636        }
 637
 638        spin_lock(&unnamed_dev_lock);
 639        dev = find_first_zero_bit(unnamed_dev_in_use, Max_anon);
 640        if (dev == Max_anon) {
 641                spin_unlock(&unnamed_dev_lock);
 642                spin_unlock(&sb_lock);
 643                destroy_super(s);
 644                return ERR_PTR(-EMFILE);
 645        }
 646        set_bit(dev, unnamed_dev_in_use);
 647        spin_unlock(&unnamed_dev_lock);
 648
 649        s->s_dev = dev;
 650        insert_super(s, type);
 651        return s;
 652}
 653
 654static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
 655        int flags, char *dev_name, void * data)
 656{
 657        struct inode *inode;
 658        struct block_device *bdev;
 659        struct block_device_operations *bdops;
 660        devfs_handle_t de;
 661        struct super_block * s;
 662        struct nameidata nd;
 663        struct list_head *p;
 664        kdev_t dev;
 665        int error = 0;
 666        mode_t mode = FMODE_READ; /* we always need it ;-) */
 667
 668        /* What device it is? */
 669        if (!dev_name || !*dev_name)
 670                return ERR_PTR(-EINVAL);
 671        error = path_lookup(dev_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 672        if (error)
 673                return ERR_PTR(error);
 674        inode = nd.dentry->d_inode;
 675        error = -ENOTBLK;
 676        if (!S_ISBLK(inode->i_mode))
 677                goto out;
 678        error = -EACCES;
 679        if (nd.mnt->mnt_flags & MNT_NODEV)
 680                goto out;
 681        bd_acquire(inode);
 682        bdev = inode->i_bdev;
 683        de = devfs_get_handle_from_inode (inode);
 684        bdops = devfs_get_ops (de);         /*  Increments module use count  */
 685        if (bdops) bdev->bd_op = bdops;
 686        /* Done with lookups, semaphore down */
 687        dev = to_kdev_t(bdev->bd_dev);
 688        if (!(flags & MS_RDONLY))
 689                mode |= FMODE_WRITE;
 690        error = blkdev_get(bdev, mode, 0, BDEV_FS);
 691        devfs_put_ops (de);   /*  Decrement module use count now we're safe  */
 692        if (error)
 693                goto out;
 694        check_disk_change(dev);
 695        error = -EACCES;
 696        if (!(flags & MS_RDONLY) && is_read_only(dev))
 697                goto out1;
 698
 699        error = -ENOMEM;
 700        s = alloc_super();
 701        if (!s)
 702                goto out1;
 703
 704        error = -EBUSY;
 705restart:
 706        spin_lock(&sb_lock);
 707
 708        list_for_each(p, &super_blocks) {
 709                struct super_block *old = sb_entry(p);
 710                if (old->s_dev != dev)
 711                        continue;
 712                if (old->s_type != fs_type ||
 713                    ((flags ^ old->s_flags) & MS_RDONLY)) {
 714                        spin_unlock(&sb_lock);
 715                        destroy_super(s);
 716                        goto out1;
 717                }
 718                if (!grab_super(old))
 719                        goto restart;
 720                destroy_super(s);
 721                blkdev_put(bdev, BDEV_FS);
 722                path_release(&nd);
 723                return old;
 724        }
 725        s->s_dev = dev;
 726        s->s_bdev = bdev;
 727        s->s_flags = flags;
 728        insert_super(s, fs_type);
 729        if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
 730                goto Einval;
 731        s->s_flags |= MS_ACTIVE;
 732        path_release(&nd);
 733        return s;
 734
 735Einval:
 736        deactivate_super(s);
 737        remove_super(s);
 738        error = -EINVAL;
 739        goto out;
 740out1:
 741        blkdev_put(bdev, BDEV_FS);
 742out:
 743        path_release(&nd);
 744        return ERR_PTR(error);
 745}
 746
 747static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
 748        int flags, char *dev_name, void *data)
 749{
 750        struct super_block *s = get_anon_super(fs_type, NULL, NULL);
 751
 752        if (IS_ERR(s))
 753                return s;
 754
 755        s->s_flags = flags;
 756        if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
 757                deactivate_super(s);
 758                remove_super(s);
 759                return ERR_PTR(-EINVAL);
 760        }
 761        s->s_flags |= MS_ACTIVE;
 762        return s;
 763}
 764
 765static int compare_single(struct super_block *s, void *p)
 766{
 767        return 1;
 768}
 769
 770static struct super_block *get_sb_single(struct file_system_type *fs_type,
 771        int flags, char *dev_name, void *data)
 772{
 773        struct super_block *s = get_anon_super(fs_type, compare_single, NULL);
 774
 775        if (IS_ERR(s))
 776                return s;
 777        if (!s->s_root) {
 778                s->s_flags = flags;
 779                if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
 780                        deactivate_super(s);
 781                        remove_super(s);
 782                        return ERR_PTR(-EINVAL);
 783                }
 784                s->s_flags |= MS_ACTIVE;
 785        }
 786        do_remount_sb(s, flags, data);
 787        return s;
 788}
 789
 790struct vfsmount *
 791do_kern_mount(const char *fstype, int flags, char *name, void *data)
 792{
 793        struct file_system_type *type = get_fs_type(fstype);
 794        struct super_block *sb = ERR_PTR(-ENOMEM);
 795        struct vfsmount *mnt;
 796
 797        if (!type)
 798                return ERR_PTR(-ENODEV);
 799
 800        mnt = alloc_vfsmnt(name);
 801        if (!mnt)
 802                goto out;
 803        if (type->fs_flags & FS_REQUIRES_DEV)
 804                sb = get_sb_bdev(type, flags, name, data);
 805        else if (type->fs_flags & FS_SINGLE)
 806                sb = get_sb_single(type, flags, name, data);
 807        else
 808                sb = get_sb_nodev(type, flags, name, data);
 809        if (IS_ERR(sb))
 810                goto out_mnt;
 811        if (type->fs_flags & FS_NOMOUNT)
 812                sb->s_flags |= MS_NOUSER;
 813        mnt->mnt_sb = sb;
 814        mnt->mnt_root = dget(sb->s_root);
 815        mnt->mnt_mountpoint = sb->s_root;
 816        mnt->mnt_parent = mnt;
 817        up_write(&sb->s_umount);
 818        put_filesystem(type);
 819        return mnt;
 820out_mnt:
 821        free_vfsmnt(mnt);
 822out:
 823        put_filesystem(type);
 824        return (struct vfsmount *)sb;
 825}
 826
 827void kill_super(struct super_block *sb)
 828{
 829        struct dentry *root = sb->s_root;
 830        struct file_system_type *fs = sb->s_type;
 831        struct super_operations *sop = sb->s_op;
 832
 833        if (!deactivate_super(sb))
 834                return;
 835
 836        down_write(&sb->s_umount);
 837        sb->s_root = NULL;
 838        /* Need to clean after the sucker */
 839        if (fs->fs_flags & FS_LITTER)
 840                d_genocide(root);
 841        shrink_dcache_parent(root);
 842        dput(root);
 843        fsync_super(sb);
 844        lock_super(sb);
 845        lock_kernel();
 846        sb->s_flags &= ~MS_ACTIVE;
 847        invalidate_inodes(sb);  /* bad name - it should be evict_inodes() */
 848        if (sop) {
 849                if (sop->write_super && sb->s_dirt)
 850                        sop->write_super(sb);
 851                if (sop->put_super)
 852                        sop->put_super(sb);
 853        }
 854
 855        /* Forget any remaining inodes */
 856        if (invalidate_inodes(sb)) {
 857                printk(KERN_ERR "VFS: Busy inodes after unmount. "
 858                        "Self-destruct in 5 seconds.  Have a nice day...\n");
 859        }
 860
 861        unlock_kernel();
 862        unlock_super(sb);
 863        remove_super(sb);
 864}
 865
 866struct vfsmount *kern_mount(struct file_system_type *type)
 867{
 868        return do_kern_mount(type->name, 0, (char *)type->name, NULL);
 869}
 870
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.