--------------------------- file_system_type ---------------------------
 prototypes:
-       struct super_block *(*get_sb) (struct file_system_type *, int,
-                       const char *, void *);
+       struct int (*get_sb) (struct file_system_type *, int,
+                       const char *, void *, struct vfsmount *);
        void (*kill_sb) (struct super_block *);
 locking rules:
                may block       BKL
 get_sb         yes             yes
 kill_sb                yes             yes
 
-->get_sb() returns error or a locked superblock (exclusive on ->s_umount).
+->get_sb() returns error or 0 with locked superblock attached to the vfsmount
+(exclusive on ->s_umount).
 ->kill_sb() takes a write-locked superblock, does all shutdown work on it,
 unlocks and drops the reference.
 
 
 success and negative number in case of error (-EINVAL unless you have more
 informative error value to report).  Call it foo_fill_super().  Now declare
 
-struct super_block foo_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+int foo_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, foo_fill_super,
+                          mnt);
 }
 
 (or similar with s/bdev/nodev/ or s/bdev/single/, depending on the kind of
 
 struct file_system_type {
        const char *name;
        int fs_flags;
-        struct super_block *(*get_sb) (struct file_system_type *, int,
-                                       const char *, void *);
+        struct int (*get_sb) (struct file_system_type *, int,
+                              const char *, void *, struct vfsmount *);
         void (*kill_sb) (struct super_block *);
         struct module *owner;
         struct file_system_type * next;
 
 }
 
 
-static struct super_block *
-pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
+static int
+pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data,
+            struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
+       return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt);
 }
 
 static struct file_system_type pfm_fs_type = {
 
        return spufs_create_root(sb, data);
 }
 
-static struct super_block *
+static int
 spufs_get_sb(struct file_system_type *fstype, int flags,
-               const char *name, void *data)
+               const char *name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fstype, flags, data, spufs_fill_super);
+       return get_sb_single(fstype, flags, data, spufs_fill_super, mnt);
 }
 
 static struct file_system_type spufs_type = {
 
        kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
 }
 
-static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
-                                              const char *dev_name, void *data)
+static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
+                              const char *dev_name, void *data,
+                              struct vfsmount *mnt)
 {
        return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
-                            INFINIBANDEVENTFS_MAGIC);
+                            INFINIBANDEVENTFS_MAGIC, mnt);
 }
 
 static struct file_system_type uverbs_event_fs = {
 
        return ret;
 }
 
-static struct super_block *ipathfs_get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *dev_name,
-                                       void *data)
+static int ipathfs_get_sb(struct file_system_type *fs_type, int flags,
+                       const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       ipath_super = get_sb_single(fs_type, flags, data,
-                                   ipathfs_fill_super);
-       return ipath_super;
+       int ret = get_sb_single(fs_type, flags, data,
+                                   ipathfs_fill_super, mnt);
+       if (ret >= 0)
+               ipath_super = mnt->mnt_sb;
+       return ret;
 }
 
 static void ipathfs_kill_super(struct super_block *s)
 
        return -ENOMEM;
 }
 
-static struct super_block *capifs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int capifs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, capifs_fill_super);
+       return get_sb_single(fs_type, flags, data, capifs_fill_super, mnt);
 }
 
 static struct file_system_type capifs_fs_type = {
 
 static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
 
 
-static struct super_block *ibmasmfs_get_super(struct file_system_type *fst,
-                       int flags, const char *name, void *data)
+static int ibmasmfs_get_super(struct file_system_type *fst,
+                       int flags, const char *name, void *data,
+                       struct vfsmount *mnt)
 {
-       return get_sb_single(fst, flags, data, ibmasmfs_fill_super);
+       return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt);
 }
 
 static struct super_operations ibmasmfs_s_ops = {
 
 }
 
 
-static struct super_block *oprofilefs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int oprofilefs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, oprofilefs_fill_super);
+       return get_sb_single(fs_type, flags, data, oprofilefs_fill_super, mnt);
 }
 
 
 
 
 /* --------------------------------------------------------------------- */
 
-static struct super_block *usb_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int usb_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, usbfs_fill_super);
+       return get_sb_single(fs_type, flags, data, usbfs_fill_super, mnt);
 }
 
 static struct file_system_type usb_fs_type = {
 
 }
 
 /* "mount -t gadgetfs path /dev/gadget" ends up here */
-static struct super_block *
+static int
 gadgetfs_get_sb (struct file_system_type *t, int flags,
-               const char *path, void *opts)
+               const char *path, void *opts, struct vfsmount *mnt)
 {
-       return get_sb_single (t, flags, opts, gadgetfs_fill_super);
+       return get_sb_single (t, flags, opts, gadgetfs_fill_super, mnt);
 }
 
 static void
 
  * @flags: mount flags
  * @dev_name: device name that was mounted
  * @data: mount options
+ * @mnt: mountpoint record to be instantiated
  *
  */
 
-static struct super_block *v9fs_get_sb(struct file_system_type
-                                      *fs_type, int flags,
-                                      const char *dev_name, void *data)
+static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data,
+                      struct vfsmount *mnt)
 {
        struct super_block *sb = NULL;
        struct v9fs_fcall *fcall = NULL;
 
        v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
        if (!v9ses)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
                dprintk(DEBUG_ERROR, "problem initiating session\n");
-               sb = ERR_PTR(newfid);
+               retval = newfid;
                goto out_free_session;
        }
 
        sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
-       if (IS_ERR(sb))
+       if (IS_ERR(sb)) {
+               retval = PTR_ERR(sb);
                goto out_close_session;
+       }
        v9fs_fill_super(sb, v9ses, flags);
 
        inode = v9fs_get_inode(sb, S_IFDIR | mode);
                goto put_back_sb;
        }
 
-       return sb;
+       return simple_set_mnt(mnt, sb);
 
 out_close_session:
        v9fs_session_close(v9ses);
 out_free_session:
        kfree(v9ses);
-       return sb;
+       return retval;
 
 put_back_sb:
        /* deactivate_super calls v9fs_kill_super which will frees the rest */
        up_write(&sb->s_umount);
        deactivate_super(sb);
-       return ERR_PTR(retval);
+       return retval;
 }
 
 /**
 
        return -EINVAL;
 }
 
-static struct super_block *adfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int adfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type adfs_fs_type = {
 
        return 0;
 }
 
-static struct super_block *affs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int affs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type affs_fs_type = {
 
 static void afs_i_init_once(void *foo, kmem_cache_t *cachep,
                            unsigned long flags);
 
-static struct super_block *afs_get_sb(struct file_system_type *fs_type,
-                                     int flags, const char *dev_name,
-                                     void *data);
+static int afs_get_sb(struct file_system_type *fs_type,
+                     int flags, const char *dev_name,
+                     void *data, struct vfsmount *mnt);
 
 static struct inode *afs_alloc_inode(struct super_block *sb);
 
  * get an AFS superblock
  * - TODO: don't use get_sb_nodev(), but rather call sget() directly
  */
-static struct super_block *afs_get_sb(struct file_system_type *fs_type,
-                                     int flags,
-                                     const char *dev_name,
-                                     void *options)
+static int afs_get_sb(struct file_system_type *fs_type,
+                     int flags,
+                     const char *dev_name,
+                     void *options,
+                     struct vfsmount *mnt)
 {
        struct afs_mount_params params;
        struct super_block *sb;
        ret = afscm_start();
        if (ret < 0) {
                _leave(" = %d", ret);
-               return ERR_PTR(ret);
+               return ret;
        }
 
        /* parse the options */
                goto error;
        }
        sb->s_flags |= MS_ACTIVE;
+       simple_set_mnt(mnt, sb);
 
        afs_put_volume(params.volume);
        afs_put_cell(params.default_cell);
-       _leave(" = %p", sb);
-       return sb;
+       _leave(" = 0 [%p]", 0, sb);
+       return 0;
 
  error:
        afs_put_volume(params.volume);
        afs_put_cell(params.default_cell);
        afscm_stop();
        _leave(" = %d", ret);
-       return ERR_PTR(ret);
+       return ret;
 } /* end afs_get_sb() */
 
 /*****************************************************************************/
 
 #include <linux/init.h>
 #include "autofs_i.h"
 
-static struct super_block *autofs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int autofs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, autofs_fill_super);
+       return get_sb_nodev(fs_type, flags, data, autofs_fill_super, mnt);
 }
 
 static struct file_system_type autofs_fs_type = {
 
 #include <linux/init.h>
 #include "autofs_i.h"
 
-static struct super_block *autofs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int autofs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, autofs4_fill_super);
+       return get_sb_nodev(fs_type, flags, data, autofs4_fill_super, mnt);
 }
 
 static struct file_system_type autofs_fs_type = {
 
        return 0;
 }
 
-static struct super_block *
+static int
 befs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name,
-           void *data)
+           void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, befs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, befs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type befs_fs_type = {
 
        return -EINVAL;
 }
 
-static struct super_block *bfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int bfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super, mnt);
 }
 
 static struct file_system_type bfs_fs_type = {
 
        return err;
 }
 
-static struct super_block *bm_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int bm_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, bm_fill_super);
+       return get_sb_single(fs_type, flags, data, bm_fill_super, mnt);
 }
 
 static struct linux_binfmt misc_format = {
 
        .clear_inode = bdev_clear_inode,
 };
 
-static struct super_block *bd_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int bd_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576);
+       return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576, mnt);
 }
 
 static struct file_system_type bd_type = {
 
        .remount_fs = cifs_remount,
 };
 
-static struct super_block *
+static int
 cifs_get_sb(struct file_system_type *fs_type,
-           int flags, const char *dev_name, void *data)
+           int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
        int rc;
        struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
        cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
 
        if (IS_ERR(sb))
-               return sb;
+               return PTR_ERR(sb);
 
        sb->s_flags = flags;
 
        if (rc) {
                up_write(&sb->s_umount);
                deactivate_super(sb);
-               return ERR_PTR(rc);
+               return rc;
        }
        sb->s_flags |= MS_ACTIVE;
-       return sb;
+       return simple_set_mnt(mnt, sb);
 }
 
 static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
 
 
 /* init_coda: used by filesystems.c to register coda */
 
-static struct super_block *coda_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int coda_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, coda_fill_super);
+       return get_sb_nodev(fs_type, flags, data, coda_fill_super, mnt);
 }
 
 struct file_system_type coda_fs_type = {
 
        return 0;
 }
 
-static struct super_block *configfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int configfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, configfs_fill_super);
+       return get_sb_single(fs_type, flags, data, configfs_fill_super, mnt);
 }
 
 static struct file_system_type configfs_fs_type = {
 
        .statfs         = cramfs_statfs,
 };
 
-static struct super_block *cramfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int cramfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type cramfs_fs_type = {
 
                prune_dcache(found, parent->d_sb);
 }
 
-/**
- * shrink_dcache_anon - further prune the cache
- * @head: head of d_hash list of dentries to prune
- *
- * Prune the dentries that are anonymous
- *
- * parsing d_hash list does not hlist_for_each_entry_rcu() as it
- * done under dcache_lock.
- *
- */
-void shrink_dcache_anon(struct super_block *sb)
-{
-       struct hlist_node *lp;
-       struct hlist_head *head = &sb->s_anon;
-       int found;
-       do {
-               found = 0;
-               spin_lock(&dcache_lock);
-               hlist_for_each(lp, head) {
-                       struct dentry *this = hlist_entry(lp, struct dentry, d_hash);
-                       if (!list_empty(&this->d_lru)) {
-                               dentry_stat.nr_unused--;
-                               list_del_init(&this->d_lru);
-                       }
-
-                       /* 
-                        * move only zero ref count dentries to the end 
-                        * of the unused list for prune_dcache
-                        */
-                       if (!atomic_read(&this->d_count)) {
-                               list_add_tail(&this->d_lru, &dentry_unused);
-                               dentry_stat.nr_unused++;
-                               found++;
-                       }
-               }
-               spin_unlock(&dcache_lock);
-               prune_dcache(found, sb);
-       } while(found);
-}
-
 /*
  * Scan `nr' dentries and return the number which remain.
  *
 
        return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
 }
 
-static struct super_block *debug_get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *dev_name,
-                                       void *data)
+static int debug_get_sb(struct file_system_type *fs_type,
+                       int flags, const char *dev_name,
+                       void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, debug_fill_super);
+       return get_sb_single(fs_type, flags, data, debug_fill_super, mnt);
 }
 
 static struct file_system_type debug_fs_type = {
 
        return -EINVAL;
 }                              /*  End Function devfs_fill_super  */
 
-static struct super_block *devfs_get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *dev_name,
-                                       void *data)
+static int devfs_get_sb(struct file_system_type *fs_type,
+                       int flags, const char *dev_name,
+                       void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, devfs_fill_super);
+       return get_sb_single(fs_type, flags, data, devfs_fill_super, mnt);
 }
 
 static struct file_system_type devfs_fs_type = {
 
        return -ENOMEM;
 }
 
-static struct super_block *devpts_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int devpts_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, devpts_fill_super);
+       return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt);
 }
 
 static struct file_system_type devpts_fs_type = {
 
 static int efs_statfs(struct super_block *s, struct kstatfs *buf);
 static int efs_fill_super(struct super_block *s, void *d, int silent);
 
-static struct super_block *efs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int efs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super, mnt);
 }
 
 static struct file_system_type efs_fs_type = {
 
                   int maxevents, long timeout);
 static int eventpollfs_delete_dentry(struct dentry *dentry);
 static struct inode *ep_eventpoll_inode(void);
-static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
-                                             int flags, const char *dev_name,
-                                             void *data);
+static int eventpollfs_get_sb(struct file_system_type *fs_type,
+                             int flags, const char *dev_name,
+                             void *data, struct vfsmount *mnt);
 
 /*
  * This semaphore is used to serialize ep_free() and eventpoll_release_file().
 }
 
 
-static struct super_block *
+static int
 eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
-                  const char *dev_name, void *data)
+                  const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC);
+       return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC,
+                            mnt);
 }
 
 
 
        return 0;
 }
 
-static struct super_block *ext2_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ext2_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt);
 }
 
 #ifdef CONFIG_QUOTA
 
 
 #endif
 
-static struct super_block *ext3_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ext3_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt);
 }
 
 static struct file_system_type ext3_fs_type = {
 
 /*
  * The usual module blurb.
  */
-static struct super_block *vxfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int vxfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type vxfs_fs_type = {
 
        return err;
 }
 
-static struct super_block *fuse_get_sb(struct file_system_type *fs_type,
-                                      int flags, const char *dev_name,
-                                      void *raw_data)
+static int fuse_get_sb(struct file_system_type *fs_type,
+                      int flags, const char *dev_name,
+                      void *raw_data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super);
+       return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super, mnt);
 }
 
 static struct file_system_type fuse_fs_type = {
 
        return res;
 }
 
-static struct super_block *hfs_get_sb(struct file_system_type *fs_type,
-                                     int flags, const char *dev_name, void *data)
+static int hfs_get_sb(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data,
+                     struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super, mnt);
 }
 
 static struct file_system_type hfs_fs_type = {
 
 
 #define HFSPLUS_INODE_SIZE     sizeof(struct hfsplus_inode_info)
 
-static struct super_block *hfsplus_get_sb(struct file_system_type *fs_type,
-                                         int flags, const char *dev_name, void *data)
+static int hfsplus_get_sb(struct file_system_type *fs_type,
+                         int flags, const char *dev_name, void *data,
+                         struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super,
+                          mnt);
 }
 
 static struct file_system_type hfsplus_fs_type = {
 
        return(err);
 }
 
-static struct super_block *hostfs_read_sb(struct file_system_type *type,
-                                            int flags, const char *dev_name,
-                                            void *data)
+static int hostfs_read_sb(struct file_system_type *type,
+                         int flags, const char *dev_name,
+                         void *data, struct vfsmount *mnt)
 {
-       return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
+       return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt);
 }
 
 static struct file_system_type hostfs_type = {
 
        return -EINVAL;
 }
 
-static struct super_block *hpfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int hpfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type hpfs_fs_type = {
 
        return(err);
 }
 
-static struct super_block *hppfs_read_super(struct file_system_type *type,
-                                            int flags, const char *dev_name,
-                                            void *data)
+static int hppfs_read_super(struct file_system_type *type,
+                           int flags, const char *dev_name,
+                           void *data, struct vfsmount *mnt)
 {
-       return(get_sb_nodev(type, flags, data, hppfs_fill_super));
+       return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt);
 }
 
 static struct file_system_type hppfs_type = {
 
        }
 }
 
-static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int hugetlbfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super);
+       return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super, mnt);
 }
 
 static struct file_system_type hugetlbfs_fs_type = {
 
        return ret;
 }
 
-static struct super_block *
+static int
 inotify_get_sb(struct file_system_type *fs_type, int flags,
-              const char *dev_name, void *data)
+              const char *dev_name, void *data, struct vfsmount *mnt)
 {
-    return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA);
+       return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA, mnt);
 }
 
 static struct file_system_type inotify_fs_type = {
 
        return inode;
 }
 
-static struct super_block *isofs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int isofs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type iso9660_fs_type = {
 
        .remount_fs     = jffs_remount,
 };
 
-static struct super_block *jffs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int jffs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type jffs_fs_type = {
 
        return 0;
 }
 
-static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
-                                             int flags, const char *dev_name,
-                                             void *data, struct mtd_info *mtd)
+static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
+                           int flags, const char *dev_name,
+                           void *data, struct mtd_info *mtd,
+                           struct vfsmount *mnt)
 {
        struct super_block *sb;
        struct jffs2_sb_info *c;
 
        c = kmalloc(sizeof(*c), GFP_KERNEL);
        if (!c)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
        memset(c, 0, sizeof(*c));
        c->mtd = mtd;
 
        sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
 
        if (IS_ERR(sb))
-               goto out_put;
+               goto out_error;
 
        if (sb->s_root) {
                /* New mountpoint for JFFS2 which is already mounted */
                D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
                          mtd->index, mtd->name));
+               ret = simple_set_mnt(mnt, sb);
                goto out_put;
        }
 
                /* Failure case... */
                up_write(&sb->s_umount);
                deactivate_super(sb);
-               return ERR_PTR(ret);
+               return ret;
        }
 
        sb->s_flags |= MS_ACTIVE;
-       return sb;
+       return simple_set_mnt(mnt, sb);
 
+out_error:
+       ret = PTR_ERR(sb);
  out_put:
        kfree(c);
        put_mtd_device(mtd);
 
-       return sb;
+       return ret;
 }
 
-static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
-                                             int flags, const char *dev_name,
-                                             void *data, int mtdnr)
+static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
+                             int flags, const char *dev_name,
+                             void *data, int mtdnr,
+                             struct vfsmount *mnt)
 {
        struct mtd_info *mtd;
 
        mtd = get_mtd_device(NULL, mtdnr);
        if (!mtd) {
                D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
-       return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd);
+       return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
 }
 
-static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *dev_name,
-                                       void *data)
+static int jffs2_get_sb(struct file_system_type *fs_type,
+                       int flags, const char *dev_name,
+                       void *data, struct vfsmount *mnt)
 {
        int err;
        struct nameidata nd;
        int mtdnr;
 
        if (!dev_name)
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
 
        D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
 
                                mtd = get_mtd_device(NULL, mtdnr);
                                if (mtd) {
                                        if (!strcmp(mtd->name, dev_name+4))
-                                               return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd);
+                                               return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
                                        put_mtd_device(mtd);
                                }
                        }
                        if (!*endptr) {
                                /* It was a valid number */
                                D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
-                               return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
+                               return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
                        }
                }
        }
                  err, nd.dentry->d_inode));
 
        if (err)
-               return ERR_PTR(err);
+               return err;
 
        err = -EINVAL;
 
        mtdnr = iminor(nd.dentry->d_inode);
        path_release(&nd);
 
-       return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
+       return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
 
 out:
        path_release(&nd);
-       return ERR_PTR(err);
+       return err;
 }
 
 static void jffs2_put_super (struct super_block *sb)
 
        }
 }
 
-static struct super_block *jfs_get_sb(struct file_system_type *fs_type, 
-       int flags, const char *dev_name, void *data)
+static int jfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super,
+                          mnt);
 }
 
 static int jfs_sync_fs(struct super_block *sb, int wait)
 
  * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
  * will never be mountable)
  */
-struct super_block *
-get_sb_pseudo(struct file_system_type *fs_type, char *name,
-       struct super_operations *ops, unsigned long magic)
+int get_sb_pseudo(struct file_system_type *fs_type, char *name,
+       struct super_operations *ops, unsigned long magic,
+       struct vfsmount *mnt)
 {
        struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
        static struct super_operations default_ops = {.statfs = simple_statfs};
        struct qstr d_name = {.name = name, .len = strlen(name)};
 
        if (IS_ERR(s))
-               return s;
+               return PTR_ERR(s);
 
        s->s_flags = MS_NOUSER;
        s->s_maxbytes = ~0ULL;
        d_instantiate(dentry, root);
        s->s_root = dentry;
        s->s_flags |= MS_ACTIVE;
-       return s;
+       return simple_set_mnt(mnt, s);
 
 Enomem:
        up_write(&s->s_umount);
        deactivate_super(s);
-       return ERR_PTR(-ENOMEM);
+       return -ENOMEM;
 }
 
 int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 
                V2_minix_truncate(inode);
 }
 
-static struct super_block *minix_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int minix_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super,
+                          mnt);
 }
 
 static struct file_system_type minix_fs_type = {
 
        return 0;
 }
 
-static struct super_block *msdos_get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *dev_name,
-                                       void *data)
+static int msdos_get_sb(struct file_system_type *fs_type,
+                       int flags, const char *dev_name,
+                       void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super,
+                          mnt);
 }
 
 static struct file_system_type msdos_fs_type = {
 
        return mnt;
 }
 
+int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
+{
+       mnt->mnt_sb = sb;
+       mnt->mnt_root = dget(sb->s_root);
+       return 0;
+}
+
+EXPORT_SYMBOL(simple_set_mnt);
+
 void free_vfsmnt(struct vfsmount *mnt)
 {
        kfree(mnt->mnt_devname);
 
        return result;
 }
 
-static struct super_block *ncp_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ncp_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, ncp_fill_super);
+       return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);
 }
 
 static struct file_system_type ncp_fs_type = {
 
        return !nfs_compare_fh(&old->fh, &server->fh);
 }
 
-static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data)
+static int nfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
        int error;
        struct nfs_server *server = NULL;
        struct nfs_fh *root;
        struct nfs_mount_data *data = raw_data;
 
-       s = ERR_PTR(-EINVAL);
+       error = -EINVAL;
        if (data == NULL) {
                dprintk("%s: missing data argument\n", __FUNCTION__);
-               goto out_err;
+               goto out_err_noserver;
        }
        if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
                dprintk("%s: bad mount version\n", __FUNCTION__);
-               goto out_err;
+               goto out_err_noserver;
        }
        switch (data->version) {
                case 1:
                                dprintk("%s: mount structure version %d does not support NFSv3\n",
                                                __FUNCTION__,
                                                data->version);
-                               goto out_err;
+                               goto out_err_noserver;
                        }
                        data->root.size = NFS2_FHSIZE;
                        memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
                                dprintk("%s: mount structure version %d does not support strong security\n",
                                                __FUNCTION__,
                                                data->version);
-                               goto out_err;
+                               goto out_err_noserver;
                        }
                case 5:
                        memset(data->context, 0, sizeof(data->context));
        }
 #ifndef CONFIG_NFS_V3
        /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
-       s = ERR_PTR(-EPROTONOSUPPORT);
+       error = -EPROTONOSUPPORT;
        if (data->flags & NFS_MOUNT_VER3) {
                dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
-               goto out_err;
+               goto out_err_noserver;
        }
 #endif /* CONFIG_NFS_V3 */
 
-       s = ERR_PTR(-ENOMEM);
+       error = -ENOMEM;
        server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
        if (!server)
-               goto out_err;
+               goto out_err_noserver;
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
        server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
                root->size = data->root.size;
        else
                root->size = NFS2_FHSIZE;
-       s = ERR_PTR(-EINVAL);
+       error = -EINVAL;
        if (root->size > sizeof(root->data)) {
                dprintk("%s: invalid root filehandle\n", __FUNCTION__);
                goto out_err;
        }
 
        /* Fire up rpciod if not yet running */
-       s = ERR_PTR(rpciod_up());
-       if (IS_ERR(s)) {
-               dprintk("%s: couldn't start rpciod! Error = %ld\n",
-                               __FUNCTION__, PTR_ERR(s));
+       error = rpciod_up();
+       if (error < 0) {
+               dprintk("%s: couldn't start rpciod! Error = %d\n",
+                               __FUNCTION__, error);
                goto out_err;
        }
 
        s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
-       if (IS_ERR(s) || s->s_root)
+       if (IS_ERR(s)) {
+               error = PTR_ERR(s);
+               goto out_err_rpciod;
+       }
+
+       if (s->s_root)
                goto out_rpciod_down;
 
        s->s_flags = flags;
        if (error) {
                up_write(&s->s_umount);
                deactivate_super(s);
-               return ERR_PTR(error);
+               return error;
        }
        s->s_flags |= MS_ACTIVE;
-       return s;
+       return simple_set_mnt(mnt, s);
+
 out_rpciod_down:
        rpciod_down();
+       kfree(server);
+       return simple_set_mnt(mnt, s);
+
+out_err_rpciod:
+       rpciod_down();
 out_err:
        kfree(server);
-       return s;
+out_err_noserver:
+       return error;
 }
 
 static void nfs_kill_super(struct super_block *s)
        return dst;
 }
 
-static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data)
+static int nfs4_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
        int error;
        struct nfs_server *server;
 
        if (data == NULL) {
                dprintk("%s: missing data argument\n", __FUNCTION__);
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
        if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
                dprintk("%s: bad mount version\n", __FUNCTION__);
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
        server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
        if (!server)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
        server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
 
        /* We now require that the mount process passes the remote address */
        if (data->host_addrlen != sizeof(server->addr)) {
-               s = ERR_PTR(-EINVAL);
+               error = -EINVAL;
                goto out_free;
        }
        if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {
-               s = ERR_PTR(-EFAULT);
+               error = -EFAULT;
                goto out_free;
        }
        if (server->addr.sin_family != AF_INET ||
            server->addr.sin_addr.s_addr == INADDR_ANY) {
                dprintk("%s: mount program didn't pass remote IP address!\n",
                                __FUNCTION__);
-               s = ERR_PTR(-EINVAL);
+               error = -EINVAL;
                goto out_free;
        }
 
        /* Fire up rpciod if not yet running */
-       s = ERR_PTR(rpciod_up());
-       if (IS_ERR(s)) {
-               dprintk("%s: couldn't start rpciod! Error = %ld\n",
-                               __FUNCTION__, PTR_ERR(s));
+       error = rpciod_up();
+       if (error < 0) {
+               dprintk("%s: couldn't start rpciod! Error = %d\n",
+                               __FUNCTION__, error);
                goto out_free;
        }
 
        s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
-
-       if (IS_ERR(s) || s->s_root)
+       if (IS_ERR(s)) {
+               error = PTR_ERR(s);
                goto out_free;
+       }
+
+       if (s->s_root) {
+               kfree(server->mnt_path);
+               kfree(server->hostname);
+               kfree(server);
+               return simple_set_mnt(mnt, s);
+       }
 
        s->s_flags = flags;
 
        if (error) {
                up_write(&s->s_umount);
                deactivate_super(s);
-               return ERR_PTR(error);
+               return error;
        }
        s->s_flags |= MS_ACTIVE;
-       return s;
+       return simple_set_mnt(mnt, s);
 out_err:
-       s = (struct super_block *)p;
+       error = PTR_ERR(p);
 out_free:
        kfree(server->mnt_path);
        kfree(server->hostname);
        kfree(server);
-       return s;
+       return error;
 }
 
 static void nfs4_kill_super(struct super_block *sb)
 
        return simple_fill_super(sb, 0x6e667364, nfsd_files);
 }
 
-static struct super_block *nfsd_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int nfsd_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, nfsd_fill_super);
+       return get_sb_single(fs_type, flags, data, nfsd_fill_super, mnt);
 }
 
 static struct file_system_type nfsd_fs_type = {
 
 /* Driver wide mutex. */
 DEFINE_MUTEX(ntfs_lock);
 
-static struct super_block *ntfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ntfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type ntfs_fs_type = {
 
        .getattr        = simple_getattr,
 };
 
-static struct super_block *dlmfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int dlmfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super);
+       return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super, mnt);
 }
 
 static struct file_system_type dlmfs_fs_type = {
 
        return status;
 }
 
-static struct super_block *ocfs2_get_sb(struct file_system_type *fs_type,
-                                       int flags,
-                                       const char *dev_name,
-                                       void *data)
+static int ocfs2_get_sb(struct file_system_type *fs_type,
+                       int flags,
+                       const char *dev_name,
+                       void *data,
+                       struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super,
+                          mnt);
 }
 
 static struct file_system_type ocfs2_fs_type = {
 
        return -ENOMEM;
 }
 
-static struct super_block *openprom_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int openprom_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, openprom_fill_super);
+       return get_sb_single(fs_type, flags, data, openprom_fill_super, mnt);
 }
 
 static struct file_system_type openprom_fs_type = {
 
  * any operations on the root directory. However, we need a non-trivial
  * d_name - pipe: will go nicely and kill the special-casing in procfs.
  */
-
-static struct super_block *
-pipefs_get_sb(struct file_system_type *fs_type, int flags,
-             const char *dev_name, void *data)
+static int pipefs_get_sb(struct file_system_type *fs_type,
+                        int flags, const char *dev_name, void *data,
+                        struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
+       return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt);
 }
 
 static struct file_system_type pipe_fs_type = {
 
 struct proc_dir_entry *proc_sys_root;
 #endif
 
-static struct super_block *proc_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int proc_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, proc_fill_super);
+       return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
 }
 
 static struct file_system_type proc_fs_type = {
 
                       "qnx4_inode_cache: not all structures were freed\n");
 }
 
-static struct super_block *qnx4_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int qnx4_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super,
+                          mnt);
 }
 
 static struct file_system_type qnx4_fs_type = {
 
        return 0;
 }
 
-struct super_block *ramfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+int ramfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, ramfs_fill_super);
+       return get_sb_nodev(fs_type, flags, data, ramfs_fill_super, mnt);
 }
 
-static struct super_block *rootfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int rootfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
+       return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super,
+                           mnt);
 }
 
 static struct file_system_type ramfs_fs_type = {
 
 
 #endif
 
-static struct super_block *get_super_block(struct file_system_type *fs_type,
-                                          int flags, const char *dev_name,
-                                          void *data)
+static int get_super_block(struct file_system_type *fs_type,
+                          int flags, const char *dev_name,
+                          void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super,
+                          mnt);
 }
 
 static int __init init_reiserfs_fs(void)
 
        .remount_fs     = romfs_remount,
 };
 
-static struct super_block *romfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int romfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type romfs_fs_type = {
 
        return error;
 }
 
-static struct super_block *smb_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int smb_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, smb_fill_super);
+       return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt);
 }
 
 static struct file_system_type smb_fs_type = {
 
        if (root) {
                sb->s_root = NULL;
                shrink_dcache_parent(root);
-               shrink_dcache_anon(sb);
+               shrink_dcache_sb(sb);
                dput(root);
                fsync_super(sb);
                lock_super(sb);
        }
 }
 
-struct super_block *get_sb_bdev(struct file_system_type *fs_type,
+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))
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt)
 {
        struct block_device *bdev;
        struct super_block *s;
 
        bdev = open_bdev_excl(dev_name, flags, fs_type);
        if (IS_ERR(bdev))
-               return (struct super_block *)bdev;
+               return PTR_ERR(bdev);
 
        /*
         * once the super is inserted into the list by sget, s_umount
        s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
        mutex_unlock(&bdev->bd_mount_mutex);
        if (IS_ERR(s))
-               goto out;
+               goto error_s;
 
        if (s->s_root) {
                if ((flags ^ s->s_flags) & MS_RDONLY) {
                        up_write(&s->s_umount);
                        deactivate_super(s);
-                       s = ERR_PTR(-EBUSY);
+                       error = -EBUSY;
+                       goto error_bdev;
                }
-               goto out;
+
+               close_bdev_excl(bdev);
        } else {
                char b[BDEVNAME_SIZE];
 
                if (error) {
                        up_write(&s->s_umount);
                        deactivate_super(s);
-                       s = ERR_PTR(error);
-               } else {
-                       s->s_flags |= MS_ACTIVE;
-                       bdev_uevent(bdev, KOBJ_MOUNT);
+                       goto error;
                }
+
+               s->s_flags |= MS_ACTIVE;
+               bdev_uevent(bdev, KOBJ_MOUNT);
        }
 
-       return s;
+       return simple_set_mnt(mnt, s);
 
-out:
+error_s:
+       error = PTR_ERR(s);
+error_bdev:
        close_bdev_excl(bdev);
-       return s;
+error:
+       return error;
 }
 
 EXPORT_SYMBOL(get_sb_bdev);
 
 EXPORT_SYMBOL(kill_block_super);
 
-struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+int get_sb_nodev(struct file_system_type *fs_type,
        int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int))
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt)
 {
        int error;
        struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
 
        if (IS_ERR(s))
-               return s;
+               return PTR_ERR(s);
 
        s->s_flags = flags;
 
        if (error) {
                up_write(&s->s_umount);
                deactivate_super(s);
-               return ERR_PTR(error);
+               return error;
        }
        s->s_flags |= MS_ACTIVE;
-       return s;
+       return simple_set_mnt(mnt, s);
 }
 
 EXPORT_SYMBOL(get_sb_nodev);
        return 1;
 }
 
-struct super_block *get_sb_single(struct file_system_type *fs_type,
+int get_sb_single(struct file_system_type *fs_type,
        int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int))
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt)
 {
        struct super_block *s;
        int error;
 
        s = sget(fs_type, compare_single, set_anon_super, NULL);
        if (IS_ERR(s))
-               return s;
+               return PTR_ERR(s);
        if (!s->s_root) {
                s->s_flags = flags;
                error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
                if (error) {
                        up_write(&s->s_umount);
                        deactivate_super(s);
-                       return ERR_PTR(error);
+                       return error;
                }
                s->s_flags |= MS_ACTIVE;
        }
        do_remount_sb(s, flags, data, 0);
-       return s;
+       return simple_set_mnt(mnt, s);
 }
 
 EXPORT_SYMBOL(get_sb_single);
 
 struct vfsmount *
-do_kern_mount(const char *fstype, int flags, const char *name, void *data)
+vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
 {
-       struct file_system_type *type = get_fs_type(fstype);
-       struct super_block *sb = ERR_PTR(-ENOMEM);
        struct vfsmount *mnt;
-       int error;
        char *secdata = NULL;
+       int error;
 
        if (!type)
                return ERR_PTR(-ENODEV);
 
+       error = -ENOMEM;
        mnt = alloc_vfsmnt(name);
        if (!mnt)
                goto out;
 
        if (data) {
                secdata = alloc_secdata();
-               if (!secdata) {
-                       sb = ERR_PTR(-ENOMEM);
+               if (!secdata)
                        goto out_mnt;
-               }
 
                error = security_sb_copy_data(type, data, secdata);
-               if (error) {
-                       sb = ERR_PTR(error);
+               if (error)
                        goto out_free_secdata;
-               }
        }
 
-       sb = type->get_sb(type, flags, name, data);
-       if (IS_ERR(sb))
+       error = type->get_sb(type, flags, name, data, mnt);
+       if (error < 0)
                goto out_free_secdata;
-       error = security_sb_kern_mount(sb, secdata);
+
+       error = security_sb_kern_mount(mnt->mnt_sb, secdata);
        if (error)
                goto out_sb;
-       mnt->mnt_sb = sb;
-       mnt->mnt_root = dget(sb->s_root);
-       mnt->mnt_mountpoint = sb->s_root;
+
+       mnt->mnt_mountpoint = mnt->mnt_root;
        mnt->mnt_parent = mnt;
-       up_write(&sb->s_umount);
+       up_write(&mnt->mnt_sb->s_umount);
        free_secdata(secdata);
-       put_filesystem(type);
        return mnt;
 out_sb:
-       up_write(&sb->s_umount);
-       deactivate_super(sb);
-       sb = ERR_PTR(error);
+       dput(mnt->mnt_root);
+       up_write(&mnt->mnt_sb->s_umount);
+       deactivate_super(mnt->mnt_sb);
 out_free_secdata:
        free_secdata(secdata);
 out_mnt:
        free_vfsmnt(mnt);
 out:
+       return ERR_PTR(error);
+}
+
+EXPORT_SYMBOL_GPL(vfs_kern_mount);
+
+struct vfsmount *
+do_kern_mount(const char *fstype, int flags, const char *name, void *data)
+{
+       struct file_system_type *type = get_fs_type(fstype);
+       struct vfsmount *mnt;
+       if (!type)
+               return ERR_PTR(-ENODEV);
+       mnt = vfs_kern_mount(type, flags, name, data);
        put_filesystem(type);
-       return (struct vfsmount *)sb;
+       return mnt;
 }
 
 EXPORT_SYMBOL_GPL(do_kern_mount);
 
 struct vfsmount *kern_mount(struct file_system_type *type)
 {
-       return do_kern_mount(type->name, 0, type->name, NULL);
+       return vfs_kern_mount(type, 0, type->name, NULL);
 }
 
 EXPORT_SYMBOL(kern_mount);
 
        return 0;
 }
 
-static struct super_block *sysfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int sysfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, sysfs_fill_super);
+       return get_sb_single(fs_type, flags, data, sysfs_fill_super, mnt);
 }
 
 static struct file_system_type sysfs_fs_type = {
 
 
 /* Every kernel module contains stuff like this. */
 
-static struct super_block *sysv_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int sysv_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super,
+                          mnt);
 }
 
-static struct super_block *v7_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int v7_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super, mnt);
 }
 
 static struct file_system_type sysv_fs_type = {
 
 static int udf_statfs(struct super_block *, struct kstatfs *);
 
 /* UDF filesystem type */
-static struct super_block *udf_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int udf_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt);
 }
 
 static struct file_system_type udf_fstype = {
 
 
 #endif
 
-static struct super_block *ufs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ufs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt);
 }
 
 static struct file_system_type ufs_fs_type = {
 
        return 0;
 }
 
-static struct super_block *vfat_get_sb(struct file_system_type *fs_type,
-                                      int flags, const char *dev_name,
-                                      void *data)
+static int vfat_get_sb(struct file_system_type *fs_type,
+                      int flags, const char *dev_name,
+                      void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super,
+                          mnt);
 }
 
 static struct file_system_type vfat_fs_type = {
 
        return -error;
 }
 
-STATIC struct super_block *
+STATIC int
 xfs_fs_get_sb(
        struct file_system_type *fs_type,
        int                     flags,
        const char              *dev_name,
-       void                    *data)
+       void                    *data,
+       struct vfsmount         *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super,
+                          mnt);
 }
 
 STATIC struct super_operations xfs_super_operations = {
 
 extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
 extern void shrink_dcache_sb(struct super_block *);
 extern void shrink_dcache_parent(struct dentry *);
-extern void shrink_dcache_anon(struct super_block *);
 extern int d_invalidate(struct dentry *);
 
 /* only used at mount-time */
 
 struct file_system_type {
        const char *name;
        int fs_flags;
-       struct super_block *(*get_sb) (struct file_system_type *, int,
-                                      const char *, void *);
+       int (*get_sb) (struct file_system_type *, int,
+                      const char *, void *, struct vfsmount *);
        void (*kill_sb) (struct super_block *);
        struct module *owner;
        struct file_system_type * next;
        struct list_head fs_supers;
 };
 
-struct super_block *get_sb_bdev(struct file_system_type *fs_type,
+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 super_block *get_sb_single(struct file_system_type *fs_type,
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt);
+extern int get_sb_single(struct file_system_type *fs_type,
        int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int));
-struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt);
+extern int get_sb_nodev(struct file_system_type *fs_type,
        int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int));
+       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);
                        int (*test)(struct super_block *,void *),
                        int (*set)(struct super_block *,void *),
                        void *data);
-struct super_block *get_sb_pseudo(struct file_system_type *, char *,
-                       struct super_operations *ops, unsigned long);
+extern int get_sb_pseudo(struct file_system_type *, char *,
+       struct super_operations *ops, unsigned long,
+       struct vfsmount *mnt);
+extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
 int __put_super(struct super_block *sb);
 int __put_super_and_need_restart(struct super_block *sb);
 void unnamed_dev_init(void);
 
 #define _LINUX_RAMFS_H
 
 struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev);
-struct super_block *ramfs_get_sb(struct file_system_type *fs_type,
-        int flags, const char *dev_name, void *data);
+extern int ramfs_get_sb(struct file_system_type *fs_type,
+        int flags, const char *dev_name, void *data, struct vfsmount *mnt);
 
 #ifndef CONFIG_MMU
 extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
 
        return 0;
 }
 
-static struct super_block *mqueue_get_sb(struct file_system_type *fs_type,
-                                        int flags, const char *dev_name,
-                                        void *data)
+static int mqueue_get_sb(struct file_system_type *fs_type,
+                        int flags, const char *dev_name,
+                        void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, mqueue_fill_super);
+       return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt);
 }
 
 static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
 
        return 0;
 }
 
-static struct super_block *cpuset_get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *unused_dev_name,
-                                       void *data)
+static int cpuset_get_sb(struct file_system_type *fs_type,
+                        int flags, const char *unused_dev_name,
+                        void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, cpuset_fill_super);
+       return get_sb_single(fs_type, flags, data, cpuset_fill_super, mnt);
 }
 
 static struct file_system_type cpuset_fs_type = {
 
                        (unsigned long)uaddr2, val2, val3);
 }
 
-static struct super_block *
-futexfs_get_sb(struct file_system_type *fs_type,
-              int flags, const char *dev_name, void *data)
+static int futexfs_get_sb(struct file_system_type *fs_type,
+                         int flags, const char *dev_name, void *data,
+                         struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "futex", NULL, 0xBAD1DEA);
+       return get_sb_pseudo(fs_type, "futex", NULL, 0xBAD1DEA, mnt);
 }
 
 static struct file_system_type futex_fs_type = {
 
 };
 
 
-static struct super_block *shmem_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int shmem_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_nodev(fs_type, flags, data, shmem_fill_super);
+       return get_sb_nodev(fs_type, flags, data, shmem_fill_super, mnt);
 }
 
 static struct file_system_type tmpfs_fs_type = {
 
        .statfs =       simple_statfs,
 };
 
-static struct super_block *sockfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int sockfs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
+       return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,
+                            mnt);
 }
 
 static struct vfsmount *sock_mnt __read_mostly;
 
        return -ENOMEM;
 }
 
-static struct super_block *
+static int
 rpc_get_sb(struct file_system_type *fs_type,
-               int flags, const char *dev_name, void *data)
+               int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, rpc_fill_super);
+       return get_sb_single(fs_type, flags, data, rpc_fill_super, mnt);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {
 
        return simple_fill_super(sb, SECURITYFS_MAGIC, files);
 }
 
-static struct super_block *get_sb(struct file_system_type *fs_type,
-                                       int flags, const char *dev_name,
-                                       void *data)
+static int get_sb(struct file_system_type *fs_type,
+                 int flags, const char *dev_name,
+                 void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, fill_super);
+       return get_sb_single(fs_type, flags, data, fill_super, mnt);
 }
 
 static struct file_system_type fs_type = {
 
        goto out;
 }
 
-static struct super_block *sel_get_sb(struct file_system_type *fs_type,
-                                     int flags, const char *dev_name, void *data)
+static int sel_get_sb(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data,
+                     struct vfsmount *mnt)
 {
-       return get_sb_single(fs_type, flags, data, sel_fill_super);
+       return get_sb_single(fs_type, flags, data, sel_fill_super, mnt);
 }
 
 static struct file_system_type sel_fs_type = {