vfs: bury ->get_sb()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 16 Mar 2011 13:07:58 +0000 (09:07 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 16 Mar 2011 20:48:06 +0000 (16:48 -0400)
This is an ex-parrot.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Documentation/filesystems/Locking
Documentation/filesystems/porting
Documentation/filesystems/vfs.txt
fs/super.c
include/linux/fs.h

index 4471a41..2e994ef 100644 (file)
@@ -166,13 +166,11 @@ prototypes:
        void (*kill_sb) (struct super_block *);
 locking rules:
                may block
-get_sb         yes
 mount          yes
 kill_sb                yes
 
-->get_sb() returns error or 0 with locked superblock attached to the vfsmount
-(exclusive on ->s_umount).
-->mount() returns ERR_PTR or the root dentry.
+->mount() returns ERR_PTR or the root dentry; its superblock should be locked
+on return.
 ->kill_sb() takes a write-locked superblock, does all shutdown work on it,
 unlocks and drops the reference.
 
index dfbcd1b..0c986c9 100644 (file)
@@ -394,3 +394,10 @@ file) you must return -EOPNOTSUPP if FALLOC_FL_PUNCH_HOLE is set in mode.
 Currently you can only have FALLOC_FL_PUNCH_HOLE with FALLOC_FL_KEEP_SIZE set,
 so the i_size should not change when hole punching, even when puching the end of
 a file off.
+
+--
+[mandatory]
+       ->get_sb() is gone.  Switch to use of ->mount().  Typically it's just
+a matter of switching from calling get_sb_... to mount_... and changing the
+function type.  If you were doing it manually, just switch from setting ->mnt_root
+to some pointer to returning that pointer.  On errors return ERR_PTR(...).
index 94cf97b..ef0714a 100644 (file)
@@ -95,10 +95,11 @@ functions:
    extern int unregister_filesystem(struct file_system_type *);
 
 The passed struct file_system_type describes your filesystem. When a
-request is made to mount a device onto a directory in your filespace,
-the VFS will call the appropriate get_sb() method for the specific
-filesystem. The dentry for the mount point will then be updated to
-point to the root inode for the new filesystem.
+request is made to mount a filesystem onto a directory in your namespace,
+the VFS will call the appropriate mount() method for the specific
+filesystem.  New vfsmount refering to the tree returned by ->mount()
+will be attached to the mountpoint, so that when pathname resolution
+reaches the mountpoint it will jump into the root of that vfsmount.
 
 You can see all filesystems that are registered to the kernel in the
 file /proc/filesystems.
@@ -107,14 +108,14 @@ file /proc/filesystems.
 struct file_system_type
 -----------------------
 
-This describes the filesystem. As of kernel 2.6.22, the following
+This describes the filesystem. As of kernel 2.6.39, the following
 members are defined:
 
 struct file_system_type {
        const char *name;
        int fs_flags;
-        int (*get_sb) (struct file_system_type *, int,
-                       const char *, void *, struct vfsmount *);
+        struct dentry (*mount) (struct file_system_type *, int,
+                       const char *, void *);
         void (*kill_sb) (struct super_block *);
         struct module *owner;
         struct file_system_type * next;
@@ -128,11 +129,11 @@ struct file_system_type {
 
   fs_flags: various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)
 
-  get_sb: the method to call when a new instance of this
+  mount: the method to call when a new instance of this
        filesystem should be mounted
 
   kill_sb: the method to call when an instance of this filesystem
-       should be unmounted
+       should be shut down
 
   owner: for internal VFS use: you should initialize this to THIS_MODULE in
        most cases.
@@ -141,7 +142,7 @@ struct file_system_type {
 
   s_lock_key, s_umount_key: lockdep-specific
 
-The get_sb() method has the following arguments:
+The mount() method has the following arguments:
 
   struct file_system_type *fs_type: describes the filesystem, partly initialized
        by the specific filesystem code
@@ -153,32 +154,39 @@ The get_sb() method has the following arguments:
   void *data: arbitrary mount options, usually comes as an ASCII
        string (see "Mount Options" section)
 
-  struct vfsmount *mnt: a vfs-internal representation of a mount point
+The mount() method must return the root dentry of the tree requested by
+caller.  An active reference to its superblock must be grabbed and the
+superblock must be locked.  On failure it should return ERR_PTR(error).
 
-The get_sb() method must determine if the block device specified
-in the dev_name and fs_type contains a filesystem of the type the method
-supports. If it succeeds in opening the named block device, it initializes a
-struct super_block descriptor for the filesystem contained by the block device.
-On failure it returns an error.
+The arguments match those of mount(2) and their interpretation
+depends on filesystem type.  E.g. for block filesystems, dev_name is
+interpreted as block device name, that device is opened and if it
+contains a suitable filesystem image the method creates and initializes
+struct super_block accordingly, returning its root dentry to caller.
+
+->mount() may choose to return a subtree of existing filesystem - it
+doesn't have to create a new one.  The main result from the caller's
+point of view is a reference to dentry at the root of (sub)tree to
+be attached; creation of new superblock is a common side effect.
 
 The most interesting member of the superblock structure that the
-get_sb() method fills in is the "s_op" field. This is a pointer to
+mount() method fills in is the "s_op" field. This is a pointer to
 a "struct super_operations" which describes the next level of the
 filesystem implementation.
 
-Usually, a filesystem uses one of the generic get_sb() implementations
-and provides a fill_super() method instead. The generic methods are:
+Usually, a filesystem uses one of the generic mount() implementations
+and provides a fill_super() callback instead. The generic variants are:
 
-  get_sb_bdev: mount a filesystem residing on a block device
+  mount_bdev: mount a filesystem residing on a block device
 
-  get_sb_nodev: mount a filesystem that is not backed by a device
+  mount_nodev: mount a filesystem that is not backed by a device
 
-  get_sb_single: mount a filesystem which shares the instance between
+  mount_single: mount a filesystem which shares the instance between
        all mounts
 
-A fill_super() method implementation has the following arguments:
+A fill_super() callback implementation has the following arguments:
 
-  struct super_block *sb: the superblock structure. The method fill_super()
+  struct super_block *sb: the superblock structure. The callback
        must initialize this properly.
 
   void *data: arbitrary mount options, usually comes as an ASCII
index 7e9dd4c..4bae0ef 100644 (file)
@@ -843,23 +843,6 @@ error:
 }
 EXPORT_SYMBOL(mount_bdev);
 
-int get_sb_bdev(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
-{
-       struct dentry *root;
-
-       root = mount_bdev(fs_type, flags, dev_name, data, fill_super);
-       if (IS_ERR(root))
-               return PTR_ERR(root);
-       mnt->mnt_root = root;
-       mnt->mnt_sb = root->d_sb;
-       return 0;
-}
-
-EXPORT_SYMBOL(get_sb_bdev);
-
 void kill_block_super(struct super_block *sb)
 {
        struct block_device *bdev = sb->s_bdev;
@@ -897,22 +880,6 @@ struct dentry *mount_nodev(struct file_system_type *fs_type,
 }
 EXPORT_SYMBOL(mount_nodev);
 
-int get_sb_nodev(struct file_system_type *fs_type,
-       int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
-{
-       struct dentry *root;
-
-       root = mount_nodev(fs_type, flags, data, fill_super);
-       if (IS_ERR(root))
-               return PTR_ERR(root);
-       mnt->mnt_root = root;
-       mnt->mnt_sb = root->d_sb;
-       return 0;
-}
-EXPORT_SYMBOL(get_sb_nodev);
-
 static int compare_single(struct super_block *s, void *p)
 {
        return 1;
@@ -943,22 +910,6 @@ struct dentry *mount_single(struct file_system_type *fs_type,
 }
 EXPORT_SYMBOL(mount_single);
 
-int get_sb_single(struct file_system_type *fs_type,
-       int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
-{
-       struct dentry *root;
-       root = mount_single(fs_type, flags, data, fill_super);
-       if (IS_ERR(root))
-               return PTR_ERR(root);
-       mnt->mnt_root = root;
-       mnt->mnt_sb = root->d_sb;
-       return 0;
-}
-
-EXPORT_SYMBOL(get_sb_single);
-
 struct vfsmount *
 vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
 {
@@ -988,19 +939,13 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
                        goto out_free_secdata;
        }
 
-       if (type->mount) {
-               root = type->mount(type, flags, name, data);
-               if (IS_ERR(root)) {
-                       error = PTR_ERR(root);
-                       goto out_free_secdata;
-               }
-               mnt->mnt_root = root;
-               mnt->mnt_sb = root->d_sb;
-       } else {
-               error = type->get_sb(type, flags, name, data, mnt);
-               if (error < 0)
-                       goto out_free_secdata;
+       root = type->mount(type, flags, name, data);
+       if (IS_ERR(root)) {
+               error = PTR_ERR(root);
+               goto out_free_secdata;
        }
+       mnt->mnt_root = root;
+       mnt->mnt_sb = root->d_sb;
        BUG_ON(!mnt->mnt_sb);
        WARN_ON(!mnt->mnt_sb->s_bdi);
        mnt->mnt_sb->s_flags |= MS_BORN;
index e6d3fe4..ffaa0e4 100644 (file)
@@ -1797,8 +1797,6 @@ int sync_inode_metadata(struct inode *inode, int wait);
 struct file_system_type {
        const char *name;
        int fs_flags;
-       int (*get_sb) (struct file_system_type *, int,
-                      const char *, void *, struct vfsmount *);
        struct dentry *(*mount) (struct file_system_type *, int,
                       const char *, void *);
        void (*kill_sb) (struct super_block *);
@@ -1821,24 +1819,12 @@ extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
 extern struct dentry *mount_bdev(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data,
        int (*fill_super)(struct super_block *, void *, int));
-extern int get_sb_bdev(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt);
 extern struct dentry *mount_single(struct file_system_type *fs_type,
        int flags, void *data,
        int (*fill_super)(struct super_block *, void *, int));
-extern int get_sb_single(struct file_system_type *fs_type,
-       int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt);
 extern struct dentry *mount_nodev(struct file_system_type *fs_type,
        int flags, void *data,
        int (*fill_super)(struct super_block *, void *, int));
-extern int get_sb_nodev(struct file_system_type *fs_type,
-       int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt);
 void generic_shutdown_super(struct super_block *sb);
 void kill_block_super(struct super_block *sb);
 void kill_anon_super(struct super_block *sb);