xfs
[Top] [All Lists]

[PATCH 01/27] BKL: Push down BKL from do_new_mount() to the filesystems

To: linux-fsdevel@xxxxxxxxxxxxxxx
Subject: [PATCH 01/27] BKL: Push down BKL from do_new_mount() to the filesystems get_sb/fill_super operation
From: Jan Blunck <jblunck@xxxxxxx>
Date: Mon, 2 Nov 2009 11:04:41 +0100
Cc: Matthew Wilcox <matthew@xxxxxx>, linux-kernel@xxxxxxxxxxxxxxx, Jan Blunck <jblunck@xxxxxxx>, Eric Van Hensbergen <ericvh@xxxxxxxxx>, Ron Minnich <rminnich@xxxxxxxxxx>, Latchesar Ionkov <lucho@xxxxxxxxxx>, Abhishek Kulkarni <adkulkar@xxxxxxxxxxxx>, Al Viro <viro@xxxxxxxxxxxxxxxxxx>, James Morris <jmorris@xxxxxxxxx>, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>, Alexey Dobriyan <adobriyan@xxxxxxxxx>, Christoph Hellwig <hch@xxxxxx>, Roman Zippel <zippel@xxxxxxxxxxxxxx>, David Howells <dhowells@xxxxxxxxxx>, Ian Kent <raven@xxxxxxxxxx>, Jeff Moyer <jmoyer@xxxxxxxxxx>, "Sergey S. Kostyliov" <rathamahata@xxxxxxx>, Greg Kroah-Hartman <gregkh@xxxxxxx>, "Tigran A. Aivazian" <tigran@xxxxxxxxxxxxxxxxxxxx>, Eric Sesterhenn <snakebyte@xxxxxx>, Qinghuang Feng <qhfeng.kernel@xxxxxxxxx>, Chris Mason <chris.mason@xxxxxxxxxx>, Yan Zheng <zheng.yan@xxxxxxxxxx>, Sage Weil <sage@xxxxxxxxxxxx>, Steve French <sfrench@xxxxxxxxx>, Jeff Layton <jlayton@xxxxxxxxxx>, Jan Harkes <jaharkes@xxxxxxxxxx>, co@xxxxxxx, da@xxxxxxxxxx, Joel Becker <joel.becker@xxxxxxxxxx>, Coly Li <coly.li@xxxxxxx>, David VomLehn <dvomlehn@xxxxxxxxx>, Sukadev Bhattiprolu <sukadev@xxxxxxxxxx>, Alan Cox <alan@xxxxxxxxxxxxxxx>, Serge Hallyn <serue@xxxxxxxxxx>, Tyler Hicks <tyhicks@xxxxxxxxxxxxxxxxxx>, Dustin Kirkland <kirkland@xxxxxxxxxxxxx>, Boaz Harrosh <bharrosh@xxxxxxxxxxx>, Benny Halevy <bhalevy@xxxxxxxxxxx>, Jan Kara <jack@xxxxxxx>, Andreas Dilger <adilger@xxxxxxx>, "Theodore Ts'o" <tytso@xxxxxxx>, OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>, Denis Karpov <ext-denis.2.karpov@xxxxxxxxx>, Miklos Szeredi <miklos@xxxxxxxxxx>, Csaba Henk <csaba@xxxxxxxxxxx>, Tejun Heo <tj@xxxxxxxxxx>, Jens Axboe <jens.axboe@xxxxxxxxxx>, Steven Whitehouse <swhiteho@xxxxxxxxxx>, Jeff Dike <jdike@xxxxxxxxxxx>, KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxxxxxxx>, Nick Piggin <npiggin@xxxxxxx>, Wolfgang Illmeyer <wolfgang@xxxxxxxxxxxx>, Mikulas Patocka <mikulas@xxxxxxxxxxxxxxxxxxxxxxxx>, Alessio Igor Bogani <abogani@xxxxxxxxxx>, Roel Kluin <roel.kluin@xxxxxxxxx>, William Irwin <wli@xxxxxxxxxxxxxx>, Mel Gorman <mel@xxxxxxxxx>, David Woodhouse <dwmw2@xxxxxxxxxxxxx>, Dave Kleikamp <shaggy@xxxxxxxxxxxxxxxxxx>, Masayuki Hamaguchi <m-hamaguchi@xxxxxxxxxxxxx>, Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>, Petr Vandrovec <vandrove@xxxxxxxxxx>, Thomas Gleixner <tglx@xxxxxxxxxxxxx>, Chuck Lever <chuck.lever@xxxxxxxxxx>, "J. Bruce Fields" <bfields@xxxxxxxxxxxx>, Neil Brown <neilb@xxxxxxx>, KONISHI Ryusuke <konishi.ryusuke@xxxxxxxxxxxxx>, Jiro SEKIBA <jir@xxxxxxxxx>, Anton Altaparmakov <aia21@xxxxxxxxxx>, Mark Fasheh <mfasheh@xxxxxxxx>, Sunil Mushran <sunil.mushran@xxxxxxxxxx>, Bob Copeland <me@xxxxxxxxxxxxxxx>, Anders Larsen <al@xxxxxxxxxxx>, Wu Fengguang <fengguang.wu@xxxxxxxxx>, Matt Mackall <mpm@xxxxxxxxxxx>, Jeff Mahoney <jeffm@xxxxxxxx>, Bernd Schmidt <bernd.schmidt@xxxxxxxxxx>, Julia Lawall <julia@xxxxxxx>, Phillip Lougher <phillip@xxxxxxxxxxxxxxxxxxx>, "Eric W. Biederman" <ebiederm@xxxxxxxxxxxxxxxxxx>, Arte m Bityutskiy <dedekind@xxxxxxxxxxxxx>, Adrian Hunter <adrian.hunter@xxxxxxxxx>, Marcin Slusarz <marcin.slusarz@xxxxxxxxx>, Pekka Enberg <penberg@xxxxxxxxxxxxxx>, Clemens Ladisch <clemens@xxxxxxxxxx>, Evgeniy Dushistov <dushistov@xxxxxxx>, Alex Elder <aelder@xxxxxxx>, xfs-masters@xxxxxxxxxxx, Dave Chinner <david@xxxxxxxxxxxxx>, Eric Sandeen <sandeen@xxxxxxxxxxx>, Niv Sardi <xaiki@xxxxxxx>, Felix Blyakher <felixb@xxxxxxx>, v9fs-developer@xxxxxxxxxxxxxxxxxxxxx, linux-afs@xxxxxxxxxxxxxxxxxxx, autofs@xxxxxxxxxxxxxxxx, linux-btrfs@xxxxxxxxxxxxxxx, linux-cifs-client@xxxxxxxxxxxxxxx, samba-technical@xxxxxxxxxxxxxxx, codalist@xxxxxxxxxxxxxxxxxxxxxxxx, ecryptfs-devel@xxxxxxxxxxxxxxxxxxx, osd-dev@xxxxxxxxxxxx, linux-ext4@xxxxxxxxxxxxxxx, fuse-devel@xxxxxxxxxxxxxxxxxxxxx, cluster-devel@xxxxxxxxxx, user-mode-linux-devel@xxxxxxxxxxxxxxxxxxxxx, user-mode-linux-user@xxxxxxxxxxxxxxxxxxxxx, linux-mtd@xxxxxxxxxxxxxxxxxxx, jfs-discussion@xxxxxxxxxxxxxxxxxxxxx, linux-nfs@xxxxxxxxxxxxxxx, users@xxxxxxxxx, linux-ntfs-dev@xxxxxxxxxxxxxxxxxxxxx, ocfs2-devel@xxxxxxxxxxxxxx, linux-karma-devel@xxxxxxxxxxxxxxxxxxxxx, reiserfs-devel@xxxxxxxxxxxxxxx, xfs@xxxxxxxxxxx
In-reply-to: <1257156307-24175-1-git-send-email-jblunck@xxxxxxx>
References: <1257156307-24175-1-git-send-email-jblunck@xxxxxxx>
I've read through all the code formerly covered by the BKL inside
do_kern_mount() and have satisfied myself that it doesn't need the BKL
any more.

do_kern_mount() is already called without the BKL when mounting the rootfs
and in nfsctl. do_kern_mount() calls vfs_kern_mount(), which is called
from various places without BKL: simple_pin_fs(), nfs_do_clone_mount()
through nfs_follow_mountpoint(), afs_mntpt_do_automount() through
afs_mntpt_follow_link(). Both later functions are actually the filesystems
follow_link inode operation. vfs_kern_mount() is calling the specified
get_sb function and lets the filesystem do its job by calling the given
fill_super function.

Therefore I think it is safe to push down the BKL from the VFS to the
low-level filesystems get_sb/fill_super operation.

Signed-off-by: Jan Blunck <jblunck@xxxxxxx>
Cc: Matthew Wilcox <matthew@xxxxxx>
---
 fs/9p/vfs_super.c            |    9 ++++++++-
 fs/adfs/super.c              |    8 +++++++-
 fs/affs/super.c              |    9 ++++++++-
 fs/afs/super.c               |    5 +++++
 fs/autofs4/inode.c           |    4 ++++
 fs/befs/linuxvfs.c           |    4 ++++
 fs/bfs/inode.c               |    9 ++++++++-
 fs/binfmt_misc.c             |    6 +++++-
 fs/btrfs/super.c             |    8 +++++++-
 fs/cifs/cifsfs.c             |   12 ++++++++++--
 fs/coda/inode.c              |    8 +++++++-
 fs/configfs/mount.c          |    5 +++++
 fs/cramfs/inode.c            |    8 +++++++-
 fs/devpts/inode.c            |   13 +++++++++++--
 fs/ecryptfs/main.c           |    3 +++
 fs/efs/super.c               |   10 ++++++++--
 fs/exofs/super.c             |    7 ++++++-
 fs/ext2/super.c              |   10 ++++++++--
 fs/ext3/super.c              |    9 ++++++++-
 fs/ext4/super.c              |    9 ++++++---
 fs/fat/namei_msdos.c         |    6 +++++-
 fs/fat/namei_vfat.c          |    6 +++++-
 fs/freevxfs/vxfs_super.c     |    7 ++++++-
 fs/fuse/control.c            |    9 ++++++++-
 fs/fuse/inode.c              |    5 +++++
 fs/gfs2/ops_fstype.c         |    9 +++++++++
 fs/hfs/super.c               |    8 +++++++-
 fs/hfsplus/super.c           |    8 +++++++-
 fs/hostfs/hostfs_kern.c      |    4 ++++
 fs/hpfs/super.c              |    8 +++++++-
 fs/hppfs/hppfs.c             |    4 ++++
 fs/hugetlbfs/inode.c         |   12 ++++++++++--
 fs/isofs/inode.c             |    8 +++++++-
 fs/jffs2/super.c             |   11 +++++++++--
 fs/jfs/super.c               |   14 ++++++++++++--
 fs/libfs.c                   |   10 +++++++++-
 fs/minix/inode.c             |    8 +++++++-
 fs/namespace.c               |    2 --
 fs/ncpfs/inode.c             |    8 +++++++-
 fs/nfs/super.c               |   19 +++++++++++++++++++
 fs/nfsd/nfsctl.c             |    7 ++++++-
 fs/nilfs2/super.c            |    9 ++++++++-
 fs/ntfs/super.c              |    5 +++++
 fs/ocfs2/dlm/dlmfs.c         |    8 +++++++-
 fs/ocfs2/super.c             |    5 +++++
 fs/omfs/inode.c              |    7 ++++++-
 fs/openpromfs/inode.c        |    4 ++++
 fs/proc/root.c               |    9 ++++++++-
 fs/qnx4/inode.c              |    8 +++++++-
 fs/ramfs/inode.c             |    5 +++++
 fs/reiserfs/super.c          |    4 ++++
 fs/romfs/super.c             |    9 ++++++++-
 fs/smbfs/inode.c             |    5 +++++
 fs/squashfs/super.c          |    6 ++++++
 fs/sysfs/mount.c             |    6 ++++++
 fs/sysv/super.c              |   24 +++++++++++++++++++-----
 fs/ubifs/super.c             |    5 +++++
 fs/udf/super.c               |    8 +++++++-
 fs/ufs/super.c               |    5 +++++
 fs/xfs/linux-2.6/xfs_super.c |    4 ++++
 60 files changed, 412 insertions(+), 53 deletions(-)

diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 14a8644..4156a0c 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -106,11 +106,15 @@ static int v9fs_get_sb(struct file_system_type *fs_type, 
int flags,
        struct p9_fid *fid;
        int retval = 0;
 
+       lock_kernel();
+
        P9_DPRINTK(P9_DEBUG_VFS, " \n");
 
        v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
-       if (!v9ses)
+       if (!v9ses) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        fid = v9fs_session_init(v9ses, dev_name, data);
        if (IS_ERR(fid)) {
@@ -155,6 +159,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, 
int flags,
 
 P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
        simple_set_mnt(mnt, sb);
+       unlock_kernel();
        return 0;
 
 free_stat:
@@ -167,12 +172,14 @@ clunk_fid:
 close_session:
        v9fs_session_close(v9ses);
        kfree(v9ses);
+       unlock_kernel();
        return retval;
 
 release_sb:
        p9stat_free(st);
        kfree(st);
        deactivate_locked_super(sb);
+       unlock_kernel();
        return retval;
 }
 
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 6910a98..e94f111 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -351,11 +351,15 @@ static int adfs_fill_super(struct super_block *sb, void 
*data, int silent)
        struct adfs_sb_info *asb;
        struct inode *root;
 
+       lock_kernel();
+
        sb->s_flags |= MS_NODIRATIME;
 
        asb = kzalloc(sizeof(*asb), GFP_KERNEL);
-       if (!asb)
+       if (!asb) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = asb;
 
        /* set default options */
@@ -473,6 +477,7 @@ static int adfs_fill_super(struct super_block *sb, void 
*data, int silent)
                goto error;
        } else
                sb->s_root->d_op = &adfs_dentry_operations;
+       unlock_kernel();
        return 0;
 
 error_free_bh:
@@ -480,6 +485,7 @@ error_free_bh:
 error:
        sb->s_fs_info = NULL;
        kfree(asb);
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 104fdcb..135f0d3 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -298,6 +298,8 @@ static int affs_fill_super(struct super_block *sb, void 
*data, int silent)
        u8                       sig[4];
        int                      ret = -EINVAL;
 
+       lock_kernel();
+
        save_mount_options(sb, data);
 
        pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no 
options");
@@ -307,8 +309,10 @@ static int affs_fill_super(struct super_block *sb, void 
*data, int silent)
        sb->s_flags |= MS_NODIRATIME;
 
        sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = sbi;
        mutex_init(&sbi->s_bmlock);
 
@@ -316,6 +320,7 @@ static int affs_fill_super(struct super_block *sb, void 
*data, int silent)
                                &blocksize,&sbi->s_prefix,
                                sbi->s_volume, &mount_flags)) {
                printk(KERN_ERR "AFFS: Error parsing options\n");
+               unlock_kernel();
                return -EINVAL;
        }
        /* N.B. after this point s_prefix must be released */
@@ -486,6 +491,7 @@ got_root:
        sb->s_root->d_op = &affs_dentry_operations;
 
        pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
+       unlock_kernel();
        return 0;
 
        /*
@@ -500,6 +506,7 @@ out_error_noinode:
        kfree(sbi->s_prefix);
        kfree(sbi);
        sb->s_fs_info = NULL;
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/afs/super.c b/fs/afs/super.c
index e1ea1c2..108fb3e 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -294,12 +294,15 @@ static int afs_fill_super(struct super_block *sb, void 
*data)
        struct inode *inode = NULL;
        int ret;
 
+       lock_kernel();
+
        _enter("");
 
        /* allocate a superblock info record */
        as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
        if (!as) {
                _leave(" = -ENOMEM");
+               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -329,6 +332,7 @@ static int afs_fill_super(struct super_block *sb, void 
*data)
        sb->s_root = root;
 
        _leave(" = 0");
+       unlock_kernel();
        return 0;
 
 error_inode:
@@ -342,6 +346,7 @@ error:
        sb->s_fs_info = NULL;
 
        _leave(" = %d", ret);
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 69c8142..3adaba9 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -323,6 +323,8 @@ int autofs4_fill_super(struct super_block *s, void *data, 
int silent)
        struct autofs_sb_info *sbi;
        struct autofs_info *ino;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi)
                goto fail_unlock;
@@ -418,6 +420,7 @@ int autofs4_fill_super(struct super_block *s, void *data, 
int silent)
         * Success! Install the root dentry now to indicate completion.
         */
        s->s_root = root;
+       unlock_kernel();
        return 0;
        
        /*
@@ -439,6 +442,7 @@ fail_free:
        kfree(sbi);
        s->s_fs_info = NULL;
 fail_unlock:
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 33baf27..f2aa193 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -759,6 +759,8 @@ befs_fill_super(struct super_block *sb, void *data, int 
silent)
        const unsigned long sb_block = 0;
        const off_t x86_sb_off = 512;
 
+       lock_kernel();
+
        save_mount_options(sb, data);
 
        sb->s_fs_info = kmalloc(sizeof (*befs_sb), GFP_KERNEL);
@@ -867,6 +869,7 @@ befs_fill_super(struct super_block *sb, void *data, int 
silent)
                befs_sb->nls = load_nls_default();
        }
 
+       unlock_kernel();
        return 0;
 /*****************/
       unacquire_bh:
@@ -877,6 +880,7 @@ befs_fill_super(struct super_block *sb, void *data, int 
silent)
 
       unacquire_none:
        sb->s_fs_info = NULL;
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 6f60336..4bff506 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -356,9 +356,13 @@ static int bfs_fill_super(struct super_block *s, void 
*data, int silent)
        long ret = -EINVAL;
        unsigned long i_sblock, i_eblock, i_eoff, s_size;
 
+       lock_kernel();
+
        info = kzalloc(sizeof(*info), GFP_KERNEL);
-       if (!info)
+       if (!info) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = info;
 
        sb_set_blocksize(s, BFS_BSIZE);
@@ -463,6 +467,7 @@ static int bfs_fill_super(struct super_block *s, void 
*data, int silent)
                        kfree(info->si_imap);
                        kfree(info);
                        s->s_fs_info = NULL;
+                       unlock_kernel();
                        return -EIO;
                }
 
@@ -484,12 +489,14 @@ static int bfs_fill_super(struct super_block *s, void 
*data, int silent)
        } 
        dump_imap("read_super", s);
        mutex_init(&info->bfs_lock);
+       unlock_kernel();
        return 0;
 
 out:
        brelse(bh);
        kfree(info);
        s->s_fs_info = NULL;
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index c4e8353..ca0e22d 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -695,9 +695,13 @@ static int bm_fill_super(struct super_block * sb, void * 
data, int silent)
                [3] = {"register", &bm_register_operations, S_IWUSR},
                /* last one */ {""}
        };
-       int err = simple_fill_super(sb, 0x42494e4d, bm_files);
+       int err;
+
+       lock_kernel();
+       err = simple_fill_super(sb, 0x42494e4d, bm_files);
        if (!err)
                sb->s_op = &s_ops;
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 752a546..e5cd2cf 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -480,13 +480,17 @@ static int btrfs_get_sb(struct file_system_type *fs_type, 
int flags,
        fmode_t mode = FMODE_READ;
        int error = 0;
 
+       lock_kernel();
+
        if (!(flags & MS_RDONLY))
                mode |= FMODE_WRITE;
 
        error = btrfs_parse_early_options(data, mode, fs_type,
                                          &subvol_name, &fs_devices);
-       if (error)
+       if (error) {
+               unlock_kernel();
                return error;
+       }
 
        error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
        if (error)
@@ -555,6 +559,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, 
int flags,
        mnt->mnt_root = root;
 
        kfree(subvol_name);
+       unlock_kernel();
        return 0;
 
 error_s:
@@ -563,6 +568,7 @@ error_close_devices:
        btrfs_close_devices(fs_devices);
 error_free_subvol_name:
        kfree(subvol_name);
+       unlock_kernel();
        return error;
 }
 
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9a5e4f5..09ccb9d 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -596,22 +596,30 @@ cifs_get_sb(struct file_system_type *fs_type,
            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);
+       struct super_block *sb;
+
+       lock_kernel();
+
+       sb = sget(fs_type, NULL, set_anon_super, NULL);
 
        cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
 
-       if (IS_ERR(sb))
+       if (IS_ERR(sb)) {
+               unlock_kernel();
                return PTR_ERR(sb);
+       }
 
        sb->s_flags = flags;
 
        rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
        if (rc) {
                deactivate_locked_super(sb);
+               unlock_kernel();
                return rc;
        }
        sb->s_flags |= MS_ACTIVE;
        simple_set_mnt(mnt, sb);
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 830f51a..d081fc5 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -147,6 +147,8 @@ static int coda_fill_super(struct super_block *sb, void 
*data, int silent)
        int error;
        int idx;
 
+       lock_kernel();
+
        idx = get_device_index((struct coda_mount_data *) data);
 
        /* Ignore errors in data, for backward compatibility */
@@ -158,11 +160,13 @@ static int coda_fill_super(struct super_block *sb, void 
*data, int silent)
        vc = &coda_comms[idx];
        if (!vc->vc_inuse) {
                printk("coda_read_super: No pseudo device\n");
+               unlock_kernel();
                return -EINVAL;
        }
 
         if ( vc->vc_sb ) {
                printk("coda_read_super: Device already mounted\n");
+               unlock_kernel();
                return -EBUSY;
        }
 
@@ -196,7 +200,8 @@ static int coda_fill_super(struct super_block *sb, void 
*data, int silent)
        sb->s_root = d_alloc_root(root);
        if (!sb->s_root)
                goto error;
-        return 0;
+       unlock_kernel();
+       return 0;
 
  error:
        if (root)
@@ -204,6 +209,7 @@ static int coda_fill_super(struct super_block *sb, void 
*data, int silent)
        if (vc)
                vc->vc_sb = NULL;
 
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index 8421cea..5b2e06e 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -71,6 +71,8 @@ static int configfs_fill_super(struct super_block *sb, void 
*data, int silent)
        struct inode *inode;
        struct dentry *root;
 
+       lock_kernel();
+
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
        sb->s_magic = CONFIGFS_MAGIC;
@@ -87,6 +89,7 @@ static int configfs_fill_super(struct super_block *sb, void 
*data, int silent)
                inc_nlink(inode);
        } else {
                pr_debug("configfs: could not get root inode\n");
+               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -94,12 +97,14 @@ static int configfs_fill_super(struct super_block *sb, void 
*data, int silent)
        if (!root) {
                pr_debug("%s: could not get root dentry!\n",__func__);
                iput(inode);
+               unlock_kernel();
                return -ENOMEM;
        }
        config_group_init(&configfs_root_group);
        configfs_root_group.cg_item.ci_dentry = root;
        root->d_fsdata = &configfs_root;
        sb->s_root = root;
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index dd3634e..13e696a 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -227,11 +227,15 @@ static int cramfs_fill_super(struct super_block *sb, void 
*data, int silent)
        struct cramfs_sb_info *sbi;
        struct inode *root;
 
+       lock_kernel();
+
        sb->s_flags |= MS_RDONLY;
 
        sbi = kzalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = sbi;
 
        /* Invalidate the read buffers on mount: think disk change.. */
@@ -308,10 +312,12 @@ static int cramfs_fill_super(struct super_block *sb, void 
*data, int silent)
                iput(root);
                goto out;
        }
+       unlock_kernel();
        return 0;
 out:
        kfree(sbi);
        sb->s_fs_info = NULL;
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index d5f8c96..e206eef 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -24,6 +24,7 @@
 #include <linux/parser.h>
 #include <linux/fsnotify.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h> /* just for lock_kernel() */
 
 #define DEVPTS_DEFAULT_MODE 0600
 /*
@@ -363,17 +364,23 @@ static int devpts_get_sb(struct file_system_type *fs_type,
        struct pts_mount_opts opts;
        struct super_block *s;
 
+       lock_kernel();
+
        error = parse_mount_options(data, PARSE_MOUNT, &opts);
-       if (error)
+       if (error) {
+               unlock_kernel();
                return error;
+       }
 
        if (opts.newinstance)
                s = sget(fs_type, NULL, set_anon_super, NULL);
        else
                s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL);
 
-       if (IS_ERR(s))
+       if (IS_ERR(s)) {
+               unlock_kernel();
                return PTR_ERR(s);
+       }
 
        if (!s->s_root) {
                s->s_flags = flags;
@@ -391,6 +398,7 @@ static int devpts_get_sb(struct file_system_type *fs_type,
        if (error)
                goto out_dput;
 
+       unlock_kernel();
        return 0;
 
 out_dput:
@@ -398,6 +406,7 @@ out_dput:
 
 out_undo_sget:
        deactivate_locked_super(s);
+       unlock_kernel();
        return error;
 }
 
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index c6ac85d..fdc7bda 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -600,6 +600,8 @@ static int ecryptfs_get_sb(struct file_system_type 
*fs_type, int flags,
        int rc;
        struct super_block *sb;
 
+       lock_kernel();
+
        rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt);
        if (rc < 0) {
                printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc);
@@ -621,6 +623,7 @@ out_abort:
        dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */
        deactivate_locked_super(sb);
 out:
+       unlock_kernel();
        return rc;
 }
 
diff --git a/fs/efs/super.c b/fs/efs/super.c
index f049428..0981141 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -249,9 +249,13 @@ static int efs_fill_super(struct super_block *s, void *d, 
int silent)
        struct inode *root;
        int ret = -EINVAL;
 
-       sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL);
-       if (!sb)
+       lock_kernel();
+
+       sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL);
+       if (!sb) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = sb;
  
        s->s_magic              = EFS_SUPER_MAGIC;
@@ -319,12 +323,14 @@ static int efs_fill_super(struct super_block *s, void *d, 
int silent)
                goto out_no_fs;
        }
 
+       unlock_kernel();
        return 0;
 
 out_no_fs_ul:
 out_no_fs:
        s->s_fs_info = NULL;
        kfree(sb);
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 9f500de..ea045b8 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -297,9 +297,13 @@ static int exofs_fill_super(struct super_block *sb, void 
*data, int silent)
        struct osd_obj_id obj;
        int ret;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = sbi;
 
        /* use mount options to fill superblock */
@@ -399,6 +403,7 @@ static int exofs_fill_super(struct super_block *sb, void 
*data, int silent)
 out:
        if (or)
                osd_end_request(or);
+       unlock_kernel();
        return ret;
 
 free_sbi:
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 1a9ffee..5af1775 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -745,15 +745,18 @@ static int ext2_fill_super(struct super_block *sb, void 
*data, int silent)
        __le32 features;
        int err;
 
+       lock_kernel();
+
+       err = -ENOMEM;
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi)
-               return -ENOMEM;
+               goto failed_unlock;
 
        sbi->s_blockgroup_lock =
                kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
        if (!sbi->s_blockgroup_lock) {
                kfree(sbi);
-               return -ENOMEM;
+               goto failed_unlock;
        }
        sb->s_fs_info = sbi;
        sbi->s_sb_block = sb_block;
@@ -1063,6 +1066,7 @@ static int ext2_fill_super(struct super_block *sb, void 
*data, int silent)
                ext2_warning(sb, __func__,
                        "mounting ext3 filesystem as ext2");
        ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
+       unlock_kernel();
        return 0;
 
 cantfind_ext2:
@@ -1086,6 +1090,8 @@ failed_sbi:
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
+failed_unlock:
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 7a520a8..38261a5 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1568,14 +1568,19 @@ static int ext3_fill_super (struct super_block *sb, 
void *data, int silent)
        __le32 features;
        int err;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sbi->s_blockgroup_lock =
                kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
        if (!sbi->s_blockgroup_lock) {
                kfree(sbi);
+               unlock_kernel();
                return -ENOMEM;
        }
        sb->s_fs_info = sbi;
@@ -1992,6 +1997,7 @@ static int ext3_fill_super (struct super_block *sb, void 
*data, int silent)
                "writeback");
 
        lock_kernel();
+       unlock_kernel();
        return 0;
 
 cantfind_ext3:
@@ -2022,6 +2028,7 @@ out_fail:
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
        lock_kernel();
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 312211e..9db81d2 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2328,14 +2328,19 @@ static int ext4_fill_super(struct super_block *sb, void 
*data, int silent)
        int err;
        unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sbi->s_blockgroup_lock =
                kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
        if (!sbi->s_blockgroup_lock) {
                kfree(sbi);
+               unlock_kernel();
                return -ENOMEM;
        }
        sb->s_fs_info = sbi;
@@ -2913,7 +2918,6 @@ no_journal:
 
        ext4_msg(sb, KERN_INFO, "mounted filesystem with%s", descr);
 
-       lock_kernel();
        return 0;
 
 cantfind_ext4:
@@ -2959,7 +2963,6 @@ out_fail:
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
-       lock_kernel();
        return ret;
 }
 
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index bbc94ae..31dd072 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -662,12 +662,16 @@ static int msdos_fill_super(struct super_block *sb, void 
*data, int silent)
 {
        int res;
 
+       lock_kernel();
        res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0);
-       if (res)
+       if (res) {
+               unlock_kernel();
                return res;
+       }
 
        sb->s_flags |= MS_NOATIME;
        sb->s_root->d_op = &msdos_dentry_operations;
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index f565f24..12961b8 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -1044,15 +1044,19 @@ static int vfat_fill_super(struct super_block *sb, void 
*data, int silent)
 {
        int res;
 
+       lock_kernel();
        res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1);
-       if (res)
+       if (res) {
+               unlock_kernel();
                return res;
+       }
 
        if (MSDOS_SB(sb)->options.name_check != 's')
                sb->s_root->d_op = &vfat_ci_dentry_ops;
        else
                sb->s_root->d_op = &vfat_dentry_ops;
 
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 1e8af93..b8b7821 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -148,7 +148,7 @@ static int vxfs_remount(struct super_block *sb, int *flags, 
char *data)
  *   The superblock on success, else %NULL.
  *
  * Locking:
- *   We are under the bkl and @sbp->s_lock.
+ *   We are under @sbp->s_lock.
  */
 static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 {
@@ -159,11 +159,14 @@ static int vxfs_fill_super(struct super_block *sbp, void 
*dp, int silent)
        struct inode *root;
        int ret = -EINVAL;
 
+       lock_kernel();
+
        sbp->s_flags |= MS_RDONLY;
 
        infp = kzalloc(sizeof(*infp), GFP_KERNEL);
        if (!infp) {
                printk(KERN_WARNING "vxfs: unable to allocate incore 
superblock\n");
+               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -236,6 +239,7 @@ static int vxfs_fill_super(struct super_block *sbp, void 
*dp, int silent)
                goto out_free_ilist;
        }
 
+       unlock_kernel();
        return 0;
        
 out_free_ilist:
@@ -245,6 +249,7 @@ out_free_ilist:
 out:
        brelse(bp);
        kfree(infp);
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 3773fd6..8d769f7 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -10,6 +10,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/smp_lock.h> /* just for lock_kernel() */
 
 #define FUSE_CTL_SUPER_MAGIC 0x65735543
 
@@ -297,9 +298,13 @@ static int fuse_ctl_fill_super(struct super_block *sb, 
void *data, int silent)
        struct fuse_conn *fc;
        int err;
 
+       lock_kernel();
+
        err = simple_fill_super(sb, FUSE_CTL_SUPER_MAGIC, &empty_descr);
-       if (err)
+       if (err) {
+               unlock_kernel();
                return err;
+       }
 
        mutex_lock(&fuse_mutex);
        BUG_ON(fuse_control_sb);
@@ -309,10 +314,12 @@ static int fuse_ctl_fill_super(struct super_block *sb, 
void *data, int silent)
                if (err) {
                        fuse_control_sb = NULL;
                        mutex_unlock(&fuse_mutex);
+                       unlock_kernel();
                        return err;
                }
        }
        mutex_unlock(&fuse_mutex);
+       unlock_kernel();
 
        return 0;
 }
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 1a822ce..5690279 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -20,6 +20,7 @@
 #include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/exportfs.h>
+#include <linux/smp_lock.h> /* Only for lock_kernel() */
 
 MODULE_AUTHOR("Miklos Szeredi <miklos@xxxxxxxxxx>");
 MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -919,6 +920,8 @@ static int fuse_fill_super(struct super_block *sb, void 
*data, int silent)
        int err;
        int is_bdev = sb->s_bdev != NULL;
 
+       lock_kernel();
+
        err = -EINVAL;
        if (sb->s_flags & MS_MANDLOCK)
                goto err;
@@ -1022,6 +1025,7 @@ static int fuse_fill_super(struct super_block *sb, void 
*data, int silent)
 
        fuse_send_init(fc, init_req);
 
+       unlock_kernel();
        return 0;
 
  err_unlock:
@@ -1036,6 +1040,7 @@ static int fuse_fill_super(struct super_block *sb, void 
*data, int silent)
  err_fput:
        fput(file);
  err:
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 52fb6c0..76415fe 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1120,9 +1120,12 @@ static int fill_super(struct super_block *sb, void 
*data, int silent)
        struct gfs2_holder mount_gh;
        int error;
 
+       lock_kernel();
+
        sdp = init_sbd(sb);
        if (!sdp) {
                printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
+               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -1211,6 +1214,7 @@ static int fill_super(struct super_block *sb, void *data, 
int silent)
 
        gfs2_glock_dq_uninit(&mount_gh);
        gfs2_online_uevent(sdp);
+       unlock_kernel();
        return 0;
 
 fail_threads:
@@ -1240,6 +1244,7 @@ fail:
        gfs2_delete_debugfs_file(sdp);
        kfree(sdp);
        sb->s_fs_info = NULL;
+       unlock_kernel();
        return error;
 }
 
@@ -1268,10 +1273,12 @@ static int gfs2_get_sb_meta(struct file_system_type 
*fs_type, int flags,
        struct path path;
        int error;
 
+       lock_kernel();
        error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
        if (error) {
                printk(KERN_WARNING "GFS2: path_lookup on %s returned error 
%d\n",
                       dev_name, error);
+               unlock_kernel();
                return error;
        }
        s = sget(&gfs2_fs_type, test_meta_super, set_meta_super,
@@ -1279,11 +1286,13 @@ static int gfs2_get_sb_meta(struct file_system_type 
*fs_type, int flags,
        path_put(&path);
        if (IS_ERR(s)) {
                printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
+               unlock_kernel();
                return PTR_ERR(s);
        }
        sdp = s->s_fs_info;
        mnt->mnt_sb = s;
        mnt->mnt_root = dget(sdp->sd_master_dir);
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index f7fcbe4..a2e19ff 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -381,9 +381,13 @@ static int hfs_fill_super(struct super_block *sb, void 
*data, int silent)
        struct inode *root_inode;
        int res;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = sbi;
        INIT_HLIST_HEAD(&sbi->rsrc_inodes);
 
@@ -429,6 +433,7 @@ static int hfs_fill_super(struct super_block *sb, void 
*data, int silent)
        sb->s_root->d_op = &hfs_dentry_operations;
 
        /* everything's okay */
+       unlock_kernel();
        return 0;
 
 bail_iput:
@@ -437,6 +442,7 @@ bail_no_root:
        printk(KERN_ERR "hfs: get root inode failed.\n");
 bail:
        hfs_mdb_put(sb);
+       unlock_kernel();
        return res;
 }
 
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 43022f3..824f57a 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -312,9 +312,13 @@ static int hfsplus_fill_super(struct super_block *sb, void 
*data, int silent)
        struct nls_table *nls = NULL;
        int err = -EINVAL;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sb->s_fs_info = sbi;
        INIT_HLIST_HEAD(&sbi->rsrc_inodes);
@@ -459,11 +463,13 @@ static int hfsplus_fill_super(struct super_block *sb, 
void *data, int silent)
 out:
        unload_nls(sbi->nls);
        sbi->nls = nls;
+       unlock_kernel();
        return 0;
 
 cleanup:
        hfsplus_put_super(sb);
        unload_nls(nls);
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 032604e..5eb2c26 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -968,6 +968,8 @@ static int hostfs_fill_sb_common(struct super_block *sb, 
void *d, int silent)
        char *host_root_path, *req_root = d;
        int err;
 
+       lock_kernel();
+
        sb->s_blocksize = 1024;
        sb->s_blocksize_bits = 10;
        sb->s_magic = HOSTFS_SUPER_MAGIC;
@@ -1016,6 +1018,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, 
void *d, int silent)
                goto out;
        }
 
+       unlock_kernel();
        return 0;
 
 out_put:
@@ -1023,6 +1026,7 @@ out_put:
 out_free:
        kfree(host_root_path);
 out:
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index f2feaa0..a7b348a 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -477,11 +477,15 @@ static int hpfs_fill_super(struct super_block *s, void 
*options, int silent)
 
        int o;
 
+       lock_kernel();
+
        save_mount_options(s, options);
 
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = sbi;
 
        sbi->sb_bmp_dir = NULL;
@@ -666,6 +670,7 @@ static int hpfs_fill_super(struct super_block *s, void 
*options, int silent)
                        root->i_blocks = 5;
                hpfs_brelse4(&qbh);
        }
+       unlock_kernel();
        return 0;
 
 bail4: brelse(bh2);
@@ -677,6 +682,7 @@ bail0:
        kfree(sbi->sb_cp_table);
        s->s_fs_info = NULL;
        kfree(sbi);
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index a5089a6..6263973 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -712,6 +712,8 @@ static int hppfs_fill_super(struct super_block *sb, void 
*d, int silent)
        struct vfsmount *proc_mnt;
        int err = -ENOENT;
 
+       lock_kernel();
+
        proc_mnt = do_kern_mount("proc", 0, "proc", NULL);
        if (IS_ERR(proc_mnt))
                goto out;
@@ -731,6 +733,7 @@ static int hppfs_fill_super(struct super_block *sb, void 
*d, int silent)
        if (!sb->s_root)
                goto out_iput;
 
+       unlock_kernel();
        return 0;
 
  out_iput:
@@ -738,6 +741,7 @@ static int hppfs_fill_super(struct super_block *sb, void 
*d, int silent)
  out_mntput:
        mntput(proc_mnt);
  out:
+       unlock_kernel();
        return(err);
 }
 
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 87a1258..53be2b9 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -32,6 +32,7 @@
 #include <linux/security.h>
 #include <linux/ima.h>
 #include <linux/magic.h>
+#include <linux/smp_lock.h> /* Only for lock_kernel() */
 
 #include <asm/uaccess.h>
 
@@ -824,6 +825,7 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, 
int silent)
        struct hugetlbfs_config config;
        struct hugetlbfs_sb_info *sbinfo;
 
+       lock_kernel();
        save_mount_options(sb, data);
 
        config.nr_blocks = -1; /* No limit on size by default */
@@ -833,12 +835,16 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, 
int silent)
        config.mode = 0755;
        config.hstate = &default_hstate;
        ret = hugetlbfs_parse_options(data, &config);
-       if (ret)
+       if (ret) {
+               unlock_kernel();
                return ret;
+       }
 
        sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
-       if (!sbinfo)
+       if (!sbinfo) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = sbinfo;
        sbinfo->hstate = config.hstate;
        spin_lock_init(&sbinfo->stat_lock);
@@ -863,9 +869,11 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, 
int silent)
                goto out_free;
        }
        sb->s_root = root;
+       unlock_kernel();
        return 0;
 out_free:
        kfree(sbinfo);
+       unlock_kernel();
        return -ENOMEM;
 }
 
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 6b4dcd4..7c501d5 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -571,11 +571,15 @@ static int isofs_fill_super(struct super_block *s, void 
*data, int silent)
        int table, error = -EINVAL;
        unsigned int vol_desc_start;
 
+       lock_kernel();
+
        save_mount_options(s, data);
 
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = sbi;
 
        if (!parse_options((char *)data, &opt))
@@ -895,6 +899,7 @@ root_found:
 
        kfree(opt.iocharset);
 
+       unlock_kernel();
        return 0;
 
        /*
@@ -934,6 +939,7 @@ out_freesbi:
        kfree(opt.iocharset);
        kfree(sbi);
        s->s_fs_info = NULL;
+       unlock_kernel();
        return error;
 }
 
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 9a80e8e..622bd51 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -148,14 +148,19 @@ static const struct super_operations 
jffs2_super_operations =
 static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct jffs2_sb_info *c;
+       int ret;
+
+       lock_kernel();
 
        D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():"
                  " New superblock for device %d (\"%s\")\n",
                  sb->s_mtd->index, sb->s_mtd->name));
 
        c = kzalloc(sizeof(*c), GFP_KERNEL);
-       if (!c)
+       if (!c) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        c->mtd = sb->s_mtd;
        c->os_priv = sb;
@@ -177,7 +182,9 @@ static int jffs2_fill_super(struct super_block *sb, void 
*data, int silent)
 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
 #endif
-       return jffs2_do_fill_super(sb, data, silent);
+       ret = jffs2_do_fill_super(sb, data, silent);
+       unlock_kernel();
+       return ret;
 }
 
 static int jffs2_get_sb(struct file_system_type *fs_type,
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 2234c73..329d7b6 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -425,14 +425,20 @@ static int jfs_fill_super(struct super_block *sb, void 
*data, int silent)
        s64 newLVSize = 0;
        int flag, ret = -EINVAL;
 
+       lock_kernel();
+
        jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
 
-       if (!new_valid_dev(sb->s_bdev->bd_dev))
+       if (!new_valid_dev(sb->s_bdev->bd_dev)) {
+               unlock_kernel();
                return -EOVERFLOW;
+       }
 
        sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = sbi;
        sbi->sb = sb;
        sbi->uid = sbi->gid = sbi->umask = -1;
@@ -442,6 +448,7 @@ static int jfs_fill_super(struct super_block *sb, void 
*data, int silent)
 
        if (!parse_options((char *) data, sb, &newLVSize, &flag)) {
                kfree(sbi);
+               unlock_kernel();
                return -EINVAL;
        }
        sbi->flag = flag;
@@ -452,6 +459,7 @@ static int jfs_fill_super(struct super_block *sb, void 
*data, int silent)
 
        if (newLVSize) {
                printk(KERN_ERR "resize option for remount only\n");
+               unlock_kernel();
                return -EINVAL;
        }
 
@@ -527,6 +535,7 @@ static int jfs_fill_super(struct super_block *sb, void 
*data, int silent)
        sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);
 #endif
        sb->s_time_gran = 1;
+       unlock_kernel();
        return 0;
 
 out_no_root:
@@ -548,6 +557,7 @@ out_kfree:
        if (sbi->nls_tab)
                unload_nls(sbi->nls_tab);
        kfree(sbi);
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/libfs.c b/fs/libfs.c
index 219576c..3484040 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -11,6 +11,7 @@
 #include <linux/exportfs.h>
 #include <linux/writeback.h>
 #include <linux/buffer_head.h>
+#include <linux/smp_lock.h> /* Only for lock_kernel() */
 
 #include <asm/uaccess.h>
 
@@ -422,6 +423,8 @@ int simple_fill_super(struct super_block *s, int magic, 
struct tree_descr *files
        struct dentry *dentry;
        int i;
 
+       lock_kernel();
+
        s->s_blocksize = PAGE_CACHE_SIZE;
        s->s_blocksize_bits = PAGE_CACHE_SHIFT;
        s->s_magic = magic;
@@ -429,8 +432,10 @@ int simple_fill_super(struct super_block *s, int magic, 
struct tree_descr *files
        s->s_time_gran = 1;
 
        inode = new_inode(s);
-       if (!inode)
+       if (!inode) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        /*
         * because the root inode is 1, the files array must not contain an
         * entry at index 1
@@ -444,6 +449,7 @@ int simple_fill_super(struct super_block *s, int magic, 
struct tree_descr *files
        root = d_alloc_root(inode);
        if (!root) {
                iput(inode);
+               unlock_kernel();
                return -ENOMEM;
        }
        for (i = 0; !files->name || files->name[0]; i++, files++) {
@@ -469,10 +475,12 @@ int simple_fill_super(struct super_block *s, int magic, 
struct tree_descr *files
                d_add(dentry, inode);
        }
        s->s_root = root;
+       unlock_kernel();
        return 0;
 out:
        d_genocide(root);
        dput(root);
+       unlock_kernel();
        return -ENOMEM;
 }
 
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 74ea82d..b8aa0a6 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -147,9 +147,13 @@ static int minix_fill_super(struct super_block *s, void 
*data, int silent)
        struct minix_sb_info *sbi;
        int ret = -EINVAL;
 
+       lock_kernel();
+
        sbi = kzalloc(sizeof(struct minix_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = sbi;
 
        BUILD_BUG_ON(32 != sizeof (struct minix_inode));
@@ -265,6 +269,7 @@ static int minix_fill_super(struct super_block *s, void 
*data, int silent)
        else if (sbi->s_mount_state & MINIX_ERROR_FS)
                printk("MINIX-fs: mounting file system with errors, "
                        "running fsck is recommended\n");
+       unlock_kernel();
        return 0;
 
 out_iput:
@@ -314,6 +319,7 @@ out_bad_sb:
 out:
        s->s_fs_info = NULL;
        kfree(sbi);
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/namespace.c b/fs/namespace.c
index bdc3cb4..3f95497 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1647,9 +1647,7 @@ static int do_new_mount(struct path *path, char *type, 
int flags,
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       lock_kernel();
        mnt = do_kern_mount(type, flags, name, data);
-       unlock_kernel();
        if (IS_ERR(mnt))
                return PTR_ERR(mnt);
 
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index cf98da1..a020d86 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -445,10 +445,14 @@ static int ncp_fill_super(struct super_block *sb, void 
*raw_data, int silent)
 #endif
        struct ncp_entry_info finfo;
 
+       lock_kernel();
+
        data.wdog_pid = NULL;
        server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
-       if (!server)
+       if (!server) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = server;
 
        error = -EFAULT;
@@ -695,6 +699,7 @@ static int ncp_fill_super(struct super_block *sb, void 
*raw_data, int silent)
         if (!sb->s_root)
                goto out_no_root;
        sb->s_root->d_op = &ncp_root_dentry_operations;
+       unlock_kernel();
        return 0;
 
 out_no_root:
@@ -729,6 +734,7 @@ out:
        put_pid(data.wdog_pid);
        sb->s_fs_info = NULL;
        kfree(server);
+       unlock_kernel();
        return error;
 }
 
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 90be551..1f97aad 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1877,6 +1877,8 @@ nfs_remount(struct super_block *sb, int *flags, char 
*raw_data)
                                           options->version <= 6))))
                return 0;
 
+       lock_kernel();
+
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
@@ -2184,6 +2186,7 @@ out:
 out_free_fh:
        kfree(mntfh);
        kfree(data);
+       unlock_kernel();
        return error;
 
 out_err_nosb:
@@ -2227,6 +2230,8 @@ static int nfs_xdev_get_sb(struct file_system_type 
*fs_type, int flags,
        };
        int error;
 
+       lock_kernel();
+
        dprintk("--> nfs_xdev_get_sb()\n");
 
        /* create a new volume representation */
@@ -2281,17 +2286,20 @@ static int nfs_xdev_get_sb(struct file_system_type 
*fs_type, int flags,
        security_sb_clone_mnt_opts(data->sb, s);
 
        dprintk("<-- nfs_xdev_get_sb() = 0\n");
+       unlock_kernel();
        return 0;
 
 out_err_nosb:
        nfs_free_server(server);
 out_err_noserver:
        dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);
+       unlock_kernel();
        return error;
 
 error_splat_super:
        deactivate_locked_super(s);
        dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
+       unlock_kernel();
        return error;
 }
 
@@ -2475,6 +2483,8 @@ static int nfs4_remote_get_sb(struct file_system_type 
*fs_type,
        };
        int error = -ENOMEM;
 
+       lock_kernel();
+
        mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
        if (data == NULL || mntfh == NULL)
                goto out_free_fh;
@@ -2534,6 +2544,7 @@ out:
        security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
        kfree(mntfh);
+       unlock_kernel();
        return error;
 
 out_free:
@@ -2794,6 +2805,8 @@ static int nfs4_remote_referral_get_sb(struct 
file_system_type *fs_type,
        };
        int error;
 
+       lock_kernel();
+
        dprintk("--> nfs4_referral_get_sb()\n");
 
        /* create a new volume representation */
@@ -2847,17 +2860,20 @@ static int nfs4_remote_referral_get_sb(struct 
file_system_type *fs_type,
        security_sb_clone_mnt_opts(data->sb, s);
 
        dprintk("<-- nfs4_referral_get_sb() = 0\n");
+       unlock_kernel();
        return 0;
 
 out_err_nosb:
        nfs_free_server(server);
 out_err_noserver:
        dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
+       unlock_kernel();
        return error;
 
 error_splat_super:
        deactivate_locked_super(s);
        dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
+       unlock_kernel();
        return error;
 }
 
@@ -2873,6 +2889,8 @@ static int nfs4_referral_get_sb(struct file_system_type 
*fs_type,
        struct vfsmount *root_mnt;
        int error;
 
+       lock_kernel();
+
        dprintk("--> nfs4_referral_get_sb()\n");
 
        export_path = data->mnt_path;
@@ -2890,6 +2908,7 @@ static int nfs4_referral_get_sb(struct file_system_type 
*fs_type,
 out:
        dprintk("<-- nfs4_referral_get_sb() = %d%s\n", error,
                        error != 0 ? " [error]" : "");
+       unlock_kernel();
        return error;
 }
 
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 5c01fc1..dcaef52 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1347,7 +1347,12 @@ static int nfsd_fill_super(struct super_block * sb, void 
* data, int silent)
 #endif
                /* last one */ {""}
        };
-       return simple_fill_super(sb, 0x6e667364, nfsd_files);
+       int ret;
+
+       lock_kernel();
+       ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
+       unlock_kernel();
+       return ret;
 }
 
 static int nfsd_get_sb(struct file_system_type *fs_type,
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 644e667..3448ec3 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -1059,9 +1059,13 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        struct the_nilfs *nilfs;
        int err, need_to_close = 1;
 
+       lock_kernel();
+
        sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type);
-       if (IS_ERR(sd.bdev))
+       if (IS_ERR(sd.bdev)) {
+               unlock_kernel();
                return PTR_ERR(sd.bdev);
+       }
 
        /*
         * To get mount instance using sget() vfs-routine, NILFS needs
@@ -1142,6 +1146,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        if (need_to_close)
                close_bdev_exclusive(sd.bdev, flags);
        simple_set_mnt(mnt, s);
+       unlock_kernel();
        return 0;
 
  failed_unlock:
@@ -1150,6 +1155,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
  failed:
        close_bdev_exclusive(sd.bdev, flags);
 
+       unlock_kernel();
        return err;
 
  cancel_new:
@@ -1163,6 +1169,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
         * We must finish all post-cleaning before this call;
         * put_nilfs() needs the block device.
         */
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 80b0477..ab09c02 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2723,6 +2723,8 @@ static int ntfs_fill_super(struct super_block *sb, void 
*opt, const int silent)
        struct inode *tmp_ino;
        int blocksize, result;
 
+       lock_kernel();
+
        /*
         * We do a pretty difficult piece of bootstrap by reading the
         * MFT (and other metadata) from disk into memory. We'll only
@@ -2746,6 +2748,7 @@ static int ntfs_fill_super(struct super_block *sb, void 
*opt, const int silent)
                        ntfs_error(sb, "Allocation of NTFS volume structure "
                                        "failed. Aborting mount...");
                lockdep_on();
+               unlock_kernel();
                return -ENOMEM;
        }
        /* Initialize ntfs_volume structure. */
@@ -2933,6 +2936,7 @@ static int ntfs_fill_super(struct super_block *sb, void 
*opt, const int silent)
                sb->s_export_op = &ntfs_export_ops;
                lock_kernel();
                lockdep_on();
+               unlock_kernel();
                return 0;
        }
        ntfs_error(sb, "Failed to allocate root directory.");
@@ -3053,6 +3057,7 @@ err_out_now:
        kfree(vol);
        ntfs_debug("Failed, returning -EINVAL.");
        lockdep_on();
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index 02bf178..58ce813 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -528,21 +528,27 @@ static int dlmfs_fill_super(struct super_block * sb,
        struct inode * inode;
        struct dentry * root;
 
+       lock_kernel();
+
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
        sb->s_magic = DLMFS_MAGIC;
        sb->s_op = &dlmfs_ops;
        inode = dlmfs_get_root_inode(sb);
-       if (!inode)
+       if (!inode) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        root = d_alloc_root(inode);
        if (!root) {
                iput(inode);
+               unlock_kernel();
                return -ENOMEM;
        }
        sb->s_root = root;
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index c0e48ae..fab815f 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -986,6 +986,8 @@ static int ocfs2_fill_super(struct super_block *sb, void 
*data, int silent)
        char nodestr[8];
        struct ocfs2_blockcheck_stats stats;
 
+       lock_kernel();
+
        mlog_entry("%p, %p, %i", sb, data, silent);
 
        if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
@@ -1172,6 +1174,7 @@ static int ocfs2_fill_super(struct super_block *sb, void 
*data, int silent)
                        atomic_set(&osb->vol_state, VOLUME_DISABLED);
                        wake_up(&osb->osb_mount_event);
                        mlog_exit(status);
+                       unlock_kernel();
                        return status;
                }
        }
@@ -1186,6 +1189,7 @@ static int ocfs2_fill_super(struct super_block *sb, void 
*data, int silent)
        ocfs2_orphan_scan_start(osb);
 
        mlog_exit(status);
+       unlock_kernel();
        return status;
 
 read_super_error:
@@ -1201,6 +1205,7 @@ read_super_error:
        }
 
        mlog_exit(status);
+       unlock_kernel();
        return status;
 }
 
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index f3b7c15..ddfbb22 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -416,11 +416,15 @@ static int omfs_fill_super(struct super_block *sb, void 
*data, int silent)
        sector_t start;
        int ret = -EINVAL;
 
+       lock_kernel();
+
        save_mount_options(sb, (char *) data);
 
        sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sb->s_fs_info = sbi;
 
@@ -525,6 +529,7 @@ out_brelse_bh2:
 out_brelse_bh:
        brelse(bh);
 end:
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index ffcd04f..50dc4be 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -386,6 +386,8 @@ static int openprom_fill_super(struct super_block *s, void 
*data, int silent)
        struct op_inode_info *oi;
        int ret;
 
+       lock_kernel();
+
        s->s_flags |= MS_NOATIME;
        s->s_blocksize = 1024;
        s->s_blocksize_bits = 10;
@@ -405,6 +407,7 @@ static int openprom_fill_super(struct super_block *s, void 
*data, int silent)
        s->s_root = d_alloc_root(root_inode);
        if (!s->s_root)
                goto out_no_root_dentry;
+       unlock_kernel();
        return 0;
 
 out_no_root_dentry:
@@ -412,6 +415,7 @@ out_no_root_dentry:
        ret = -ENOMEM;
 out_no_root:
        printk("openprom_fill_super: get root inode failed\n");
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/proc/root.c b/fs/proc/root.c
index b080b79..6384680 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,6 +18,7 @@
 #include <linux/bitops.h>
 #include <linux/mount.h>
 #include <linux/pid_namespace.h>
+#include <linux/smp_lock.h> /* For lock_kernel() only */
 
 #include "internal.h"
 
@@ -43,6 +44,8 @@ static int proc_get_sb(struct file_system_type *fs_type,
        struct pid_namespace *ns;
        struct proc_inode *ei;
 
+       lock_kernel();
+
        if (proc_mnt) {
                /* Seed the root directory with a pid so it doesn't need
                 * to be special in base.c.  I would do this earlier but
@@ -60,14 +63,17 @@ static int proc_get_sb(struct file_system_type *fs_type,
                ns = current->nsproxy->pid_ns;
 
        sb = sget(fs_type, proc_test_super, proc_set_super, ns);
-       if (IS_ERR(sb))
+       if (IS_ERR(sb)) {
+               unlock_kernel();
                return PTR_ERR(sb);
+       }
 
        if (!sb->s_root) {
                sb->s_flags = flags;
                err = proc_fill_super(sb);
                if (err) {
                        deactivate_locked_super(sb);
+                       unlock_kernel();
                        return err;
                }
 
@@ -83,6 +89,7 @@ static int proc_get_sb(struct file_system_type *fs_type,
        }
 
        simple_set_mnt(mnt, sb);
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index d2cd179..18640ce 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -253,9 +253,13 @@ static int qnx4_fill_super(struct super_block *s, void 
*data, int silent)
        struct qnx4_sb_info *qs;
        int ret = -EINVAL;
 
+       lock_kernel();
+
        qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
-       if (!qs)
+       if (!qs) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = qs;
 
        sb_set_blocksize(s, QNX4_BLOCK_SIZE);
@@ -303,6 +307,7 @@ static int qnx4_fill_super(struct super_block *s, void 
*data, int silent)
 
        brelse(bh);
 
+       unlock_kernel();
        return 0;
 
       outi:
@@ -312,6 +317,7 @@ static int qnx4_fill_super(struct super_block *s, void 
*data, int silent)
       outnobh:
        kfree(qs);
        s->s_fs_info = NULL;
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index a6090aa..9b3983f 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/parser.h>
 #include <linux/magic.h>
+#include <linux/smp_lock.h> /* Only for lock_kernel() */
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -220,6 +221,8 @@ static int ramfs_fill_super(struct super_block * sb, void * 
data, int silent)
        struct dentry *root;
        int err;
 
+       lock_kernel();
+
        save_mount_options(sb, data);
 
        fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
@@ -253,11 +256,13 @@ static int ramfs_fill_super(struct super_block * sb, void 
* data, int silent)
                goto fail;
        }
 
+       unlock_kernel();
        return 0;
 fail:
        kfree(fsi);
        sb->s_fs_info = NULL;
        iput(inode);
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index f0ad05f..f32bf62 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1608,6 +1608,8 @@ static int reiserfs_fill_super(struct super_block *s, 
void *data, int silent)
        char *qf_names[MAXQUOTAS] = {};
        unsigned int qfmt = 0;
 
+       lock_kernel();
+
        save_mount_options(s, data);
 
        sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
@@ -1852,6 +1854,7 @@ static int reiserfs_fill_super(struct super_block *s, 
void *data, int silent)
        init_waitqueue_head(&(sbi->s_wait));
        spin_lock_init(&sbi->bitmap_lock);
 
+       unlock_kernel();
        return (0);
 
 error:
@@ -1872,6 +1875,7 @@ error:
        kfree(sbi);
 
        s->s_fs_info = NULL;
+       unlock_kernel();
        return errval;
 }
 
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index c117fa8..7342617 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -468,6 +468,8 @@ static int romfs_fill_super(struct super_block *sb, void 
*data, int silent)
        size_t len;
        int ret;
 
+       lock_kernel();
+
 #ifdef CONFIG_BLOCK
        if (!sb->s_mtd) {
                sb_set_blocksize(sb, ROMBSIZE);
@@ -484,8 +486,10 @@ static int romfs_fill_super(struct super_block *sb, void 
*data, int silent)
 
        /* read the image superblock and check it */
        rsb = kmalloc(512, GFP_KERNEL);
-       if (!rsb)
+       if (!rsb) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sb->s_fs_info = (void *) 512;
        ret = romfs_dev_read(sb, 0, rsb, 512);
@@ -535,15 +539,18 @@ static int romfs_fill_super(struct super_block *sb, void 
*data, int silent)
        if (!sb->s_root)
                goto error_i;
 
+       unlock_kernel();
        return 0;
 
 error_i:
        iput(root);
 error:
+       unlock_kernel();
        return -EINVAL;
 error_rsb_inval:
        ret = -EINVAL;
 error_rsb:
+       unlock_kernel();
        return ret;
 }
 
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 1c4c8f0..c3c9044 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -500,6 +500,8 @@ static int smb_fill_super(struct super_block *sb, void 
*raw_data, int silent)
        void *mem;
        static int warn_count;
 
+       lock_kernel();
+
        if (warn_count < 5) {
                warn_count++;
                printk(KERN_EMERG "smbfs is deprecated and will be removed"
@@ -615,6 +617,7 @@ static int smb_fill_super(struct super_block *sb, void 
*raw_data, int silent)
 
        smb_new_dentry(sb->s_root);
 
+       unlock_kernel();
        return 0;
 
 out_no_root:
@@ -635,9 +638,11 @@ out_wrong_data:
 out_no_data:
        printk(KERN_ERR "smb_fill_super: missing data argument\n");
 out_fail:
+       unlock_kernel();
        return -EINVAL;
 out_no_server:
        printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n");
+       unlock_kernel();
        return -ENOMEM;
 }
 
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 6c197ef..23cea83 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -78,11 +78,14 @@ static int squashfs_fill_super(struct super_block *sb, void 
*data, int silent)
        u64 lookup_table_start;
        int err;
 
+       lock_kernel();
+
        TRACE("Entered squashfs_fill_superblock\n");
 
        sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
        if (sb->s_fs_info == NULL) {
                ERROR("Failed to allocate squashfs_sb_info\n");
+               unlock_kernel();
                return -ENOMEM;
        }
        msblk = sb->s_fs_info;
@@ -286,6 +289,7 @@ allocate_root:
 
        TRACE("Leaving squashfs_fill_super\n");
        kfree(sblk);
+       unlock_kernel();
        return 0;
 
 failed_mount:
@@ -299,12 +303,14 @@ failed_mount:
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
        kfree(sblk);
+       unlock_kernel();
        return err;
 
 failure:
        kfree(msblk->stream.workspace);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
+       unlock_kernel();
        return -ENOMEM;
 }
 
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 4974995..2e5a870 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/magic.h>
+#include <linux/smp_lock.h> /* Only for lock_kernel() */
 
 #include "sysfs.h"
 
@@ -45,6 +46,8 @@ static int sysfs_fill_super(struct super_block *sb, void 
*data, int silent)
        struct inode *inode;
        struct dentry *root;
 
+       lock_kernel();
+
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
        sb->s_magic = SYSFS_MAGIC;
@@ -58,6 +61,7 @@ static int sysfs_fill_super(struct super_block *sb, void 
*data, int silent)
        mutex_unlock(&sysfs_mutex);
        if (!inode) {
                pr_debug("sysfs: could not get root inode\n");
+               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -66,10 +70,12 @@ static int sysfs_fill_super(struct super_block *sb, void 
*data, int silent)
        if (!root) {
                pr_debug("%s: could not get root dentry!\n",__func__);
                iput(inode);
+               unlock_kernel();
                return -ENOMEM;
        }
        root->d_fsdata = &sysfs_root;
        sb->s_root = root;
+       unlock_kernel();
        return 0;
 }
 
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index 5a903da..145d949 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -357,7 +357,9 @@ static int sysv_fill_super(struct super_block *sb, void 
*data, int silent)
        struct sysv_sb_info *sbi;
        unsigned long blocknr;
        int size = 0, i;
-       
+
+       lock_kernel();
+
        BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block));
        BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block));
        BUILD_BUG_ON(512 != sizeof (struct sysv2_super_block));
@@ -365,8 +367,10 @@ static int sysv_fill_super(struct super_block *sb, void 
*data, int silent)
        BUILD_BUG_ON(64 != sizeof (struct sysv_inode));
 
        sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sbi->s_sb = sb;
        sbi->s_block_base = 0;
@@ -409,8 +413,10 @@ static int sysv_fill_super(struct super_block *sb, void 
*data, int silent)
        if (bh && bh1) {
                sbi->s_bh1 = bh1;
                sbi->s_bh2 = bh;
-               if (complete_read_super(sb, silent, size))
+               if (complete_read_super(sb, silent, size)) {
+                       unlock_kernel();
                        return 0;
+               }
        }
 
        brelse(bh1);
@@ -419,6 +425,7 @@ static int sysv_fill_super(struct super_block *sb, void 
*data, int silent)
        printk("oldfs: cannot read superblock\n");
 failed:
        kfree(sbi);
+       unlock_kernel();
        return -EINVAL;
 
 Eunknown:
@@ -442,14 +449,18 @@ static int v7_fill_super(struct super_block *sb, void 
*data, int silent)
        struct v7_super_block *v7sb;
        struct sysv_inode *v7i;
 
+       lock_kernel();
+
        if (440 != sizeof (struct v7_super_block))
                panic("V7 FS: bad super-block size");
        if (64 != sizeof (struct sysv_inode))
                panic("sysv fs: bad i-node size");
 
        sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sbi->s_sb = sb;
        sbi->s_block_base = 0;
@@ -487,13 +498,16 @@ static int v7_fill_super(struct super_block *sb, void 
*data, int silent)
 
        sbi->s_bh1 = bh;
        sbi->s_bh2 = bh;
-       if (complete_read_super(sb, silent, 1))
+       if (complete_read_super(sb, silent, 1)) {
+               unlock_kernel();
                return 0;
+       }
 
 failed:
        brelse(bh2);
        brelse(bh);
        kfree(sbi);
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 333e181..04a0fc9 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2029,6 +2029,8 @@ static int ubifs_get_sb(struct file_system_type *fs_type, 
int flags,
        struct super_block *sb;
        int err;
 
+       lock_kernel();
+
        dbg_gen("name %s, flags %#x", name, flags);
 
        /*
@@ -2040,6 +2042,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, 
int flags,
        if (IS_ERR(ubi)) {
                ubifs_err("cannot open \"%s\", error %d",
                          name, (int)PTR_ERR(ubi));
+               unlock_kernel();
                return PTR_ERR(ubi);
        }
        ubi_get_volume_info(ubi, &vi);
@@ -2077,12 +2080,14 @@ static int ubifs_get_sb(struct file_system_type 
*fs_type, int flags,
        ubi_close_volume(ubi);
 
        simple_set_mnt(mnt, sb);
+       unlock_kernel();
        return 0;
 
 out_deact:
        deactivate_locked_super(sb);
 out_close:
        ubi_close_volume(ubi);
+       unlock_kernel();
        return err;
 }
 
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 9d1b8c2..fa6f8db 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1866,6 +1866,8 @@ static int udf_fill_super(struct super_block *sb, void 
*options, int silent)
        struct kernel_lb_addr rootdir, fileset;
        struct udf_sb_info *sbi;
 
+       lock_kernel();
+
        uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
        uopt.uid = -1;
        uopt.gid = -1;
@@ -1874,8 +1876,10 @@ static int udf_fill_super(struct super_block *sb, void 
*options, int silent)
        uopt.dmode = UDF_INVALID_MODE;
 
        sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sb->s_fs_info = sbi;
 
@@ -2021,6 +2025,7 @@ static int udf_fill_super(struct super_block *sb, void 
*options, int silent)
                goto error_out;
        }
        sb->s_maxbytes = MAX_LFS_FILESIZE;
+       unlock_kernel();
        return 0;
 
 error_out:
@@ -2041,6 +2046,7 @@ error_out:
        kfree(sbi);
        sb->s_fs_info = NULL;
 
+       unlock_kernel();
        return -EINVAL;
 }
 
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 5faed79..31ad198 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -646,6 +646,8 @@ static int ufs_fill_super(struct super_block *sb, void 
*data, int silent)
        unsigned maxsymlen;
        int ret = -EINVAL;
 
+       lock_kernel();
+
        uspi = NULL;
        ubh = NULL;
        flags = 0;
@@ -1107,6 +1109,7 @@ magic_found:
                        goto failed;
 
        UFSD("EXIT\n");
+       unlock_kernel();
        return 0;
 
 dalloc_failed:
@@ -1118,10 +1121,12 @@ failed:
        kfree(sbi);
        sb->s_fs_info = NULL;
        UFSD("EXIT (FAILED)\n");
+       unlock_kernel();
        return ret;
 
 failed_nomem:
        UFSD("EXIT (NOMEM)\n");
+       unlock_kernel();
        return -ENOMEM;
 }
 
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 18a4b8e..7426166 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1412,6 +1412,8 @@ xfs_fs_fill_super(
        int                     flags = 0, error = ENOMEM;
        char                    *mtpt = NULL;
 
+       lock_kernel();
+
        mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL);
        if (!mp)
                goto out;
@@ -1506,6 +1508,7 @@ xfs_fs_fill_super(
        kfree(mtpt);
 
        xfs_itrace_exit(XFS_I(sb->s_root->d_inode));
+       unlock_kernel();
        return 0;
 
  out_filestream_unmount:
@@ -1522,6 +1525,7 @@ xfs_fs_fill_super(
        kfree(mtpt);
        kfree(mp);
  out:
+       unlock_kernel();
        return -error;
 
  fail_vnrele:
-- 
1.6.4.2

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 01/27] BKL: Push down BKL from do_new_mount() to the filesystems get_sb/fill_super operation, Jan Blunck <=