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