lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1240646945-7970-1-git-send-email-abogani@texware.it>
Date:	Sat, 25 Apr 2009 10:09:05 +0200
From:	Alessio Igor Bogani <abogani@...ware.it>
To:	Alexander Viro <viro@...iv.linux.org.uk>
Cc:	Jonathan Corbet <corbet@....net>,
	Frédéric Weisbecker <fweisbec@...il.com>,
	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	LKML <linux-kernel@...r.kernel.org>,
	LFSDEV <linux-fsdevel@...r.kernel.org>,
	Matthew Wilcox <matthew@....cx>, Ingo Molnar <mingo@...e.hu>,
	Alessio Igor Bogani <abogani@...ware.it>
Subject: [PATCH vfs-2.6:for-next] vfs: remount_fs BKL pushdown

Push BKL down into ->remount_fs()

Signed-off-by: Alessio Igor Bogani <abogani@...ware.it>
---
 drivers/isdn/capi/capifs.c       |    5 +++++
 drivers/staging/pohmelfs/inode.c |   11 +++++++++--
 drivers/usb/core/inode.c         |    5 +++++
 fs/adfs/super.c                  |    9 ++++++++-
 fs/affs/super.c                  |   12 ++++++++++--
 fs/befs/linuxvfs.c               |    7 ++++++-
 fs/btrfs/super.c                 |   22 +++++++++++++++++-----
 fs/cifs/cifsfs.c                 |    2 ++
 fs/coda/inode.c                  |    2 ++
 fs/cramfs/inode.c                |    3 +++
 fs/devpts/inode.c                |   10 ++++++++--
 fs/efs/super.c                   |    3 +++
 fs/ext2/super.c                  |   18 ++++++++++++++----
 fs/ext3/super.c                  |    7 ++++++-
 fs/ext4/super.c                  |    7 ++++++-
 fs/fat/inode.c                   |    5 ++++-
 fs/freevxfs/vxfs_super.c         |    3 +++
 fs/fuse/inode.c                  |    6 +++++-
 fs/gfs2/ops_super.c              |   27 +++++++++++++++++++++------
 fs/hfs/super.c                   |    7 ++++++-
 fs/hfsplus/super.c               |   12 ++++++++++--
 fs/hpfs/super.c                  |    8 +++++++-
 fs/isofs/inode.c                 |    3 +++
 fs/jffs2/fs.c                    |   11 +++++++++--
 fs/jfs/super.c                   |   27 ++++++++++++++++++++++-----
 fs/minix/inode.c                 |   14 +++++++++++---
 fs/namespace.c                   |    2 --
 fs/ncpfs/inode.c                 |    2 ++
 fs/nfs/super.c                   |   20 +++++++++++++++-----
 fs/nilfs2/super.c                |   10 ++++++++--
 fs/ntfs/super.c                  |   18 ++++++++++++++++--
 fs/ocfs2/super.c                 |    7 ++++++-
 fs/openpromfs/inode.c            |    3 +++
 fs/qnx4/inode.c                  |    3 +++
 fs/reiserfs/super.c              |   12 ++++++++++--
 fs/romfs/super.c                 |    3 +++
 fs/smbfs/inode.c                 |    2 ++
 fs/squashfs/super.c              |    3 +++
 fs/super.c                       |    4 ----
 fs/sysv/inode.c                  |    7 ++++++-
 fs/ubifs/super.c                 |   13 +++++++++++--
 fs/udf/super.c                   |   13 ++++++++++---
 fs/ufs/super.c                   |   11 ++++++++++-
 fs/xfs/linux-2.6/xfs_super.c     |    7 ++++++-
 kernel/cgroup.c                  |    9 +++++++--
 mm/shmem.c                       |   13 ++++++++++---
 46 files changed, 336 insertions(+), 72 deletions(-)

diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index b129409..1cc98da 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/sched.h>	/* current */
+#include <linux/smp_lock.h>
 
 #include "capifs.h"
 
@@ -54,6 +55,8 @@ static int capifs_remount(struct super_block *s, int *flags, char *data)
 	char *this_char;
 	char *new_opt = kstrdup(data, GFP_KERNEL);
 
+	lock_kernel();
+
 	this_char = NULL;
 	while ((this_char = strsep(&data, ",")) != NULL) {
 		int n;
@@ -71,6 +74,7 @@ static int capifs_remount(struct super_block *s, int *flags, char *data)
 		else {
 			kfree(new_opt);
 			printk("capifs: called with bogus options\n");
+			unlock_kernel();
 			return -EINVAL;
 		}
 	}
@@ -84,6 +88,7 @@ static int capifs_remount(struct super_block *s, int *flags, char *data)
 	config.gid     = gid;
 	config.mode    = mode;
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index b2eaf90..c951d7e 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -30,6 +30,7 @@
 #include <linux/statfs.h>
 #include <linux/writeback.h>
 #include <linux/quotaops.h>
+#include <linux/smp_lock.h>
 
 #include "netfs.h"
 
@@ -1475,8 +1476,12 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb, int re
 static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
 {
 	int err;
-	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-	unsigned long old_sb_flags = sb->s_flags;
+	struct pohmelfs_sb *psb;
+	unsigned long old_sb_flags;
+
+	lock_kernel();
+	psb = POHMELFS_SB(sb);
+	old_sb_flags = sb->s_flags;
 
 	err = pohmelfs_parse_options(data, psb, 1);
 	if (err)
@@ -1484,10 +1489,12 @@ static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
 
 	if (!(*flags & MS_RDONLY))
 		sb->s_flags &= ~MS_RDONLY;
+	unlock_kernel();
 	return 0;
 
 err_out_restore:
 	sb->s_flags = old_sb_flags;
+	unlock_kernel();
 	return err;
 }
 
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index dff5760..2e8ca41 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -39,6 +39,7 @@
 #include <linux/parser.h>
 #include <linux/notifier.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 #include <asm/byteorder.h>
 #include "usb.h"
 #include "hcd.h"
@@ -260,14 +261,18 @@ static int remount(struct super_block *sb, int *flags, char *data)
 	if (ignore_mount)
 		return 0;
 
+	lock_kernel();
+
 	if (parse_options(sb, data)) {
 		printk(KERN_WARNING "usbfs: mount parameter error.\n");
+		unlock_kernel();
 		return -EINVAL;
 	}
 
 	if (usbfs_mount && usbfs_mount->mnt_sb)
 		update_sb(usbfs_mount->mnt_sb);
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index dd9becc..4cd1c9d 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -22,6 +22,7 @@
 #include <linux/bitops.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -213,8 +214,14 @@ static int parse_options(struct super_block *sb, char *options)
 
 static int adfs_remount(struct super_block *sb, int *flags, char *data)
 {
+	int ret;
+
+	lock_kernel();
 	*flags |= MS_NODIRATIME;
-	return parse_options(sb, data);
+	ret = parse_options(sb, data);
+	unlock_kernel();
+
+	return ret;
 }
 
 static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf)
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 5ce695e..a0d0a38 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -16,6 +16,7 @@
 #include <linux/parser.h>
 #include <linux/magic.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include "affs.h"
 
 extern struct timezone sys_tz;
@@ -486,7 +487,7 @@ out_error_noinode:
 static int
 affs_remount(struct super_block *sb, int *flags, char *data)
 {
-	struct affs_sb_info	*sbi = AFFS_SB(sb);
+	struct affs_sb_info	*sbi;
 	int			 blocksize;
 	uid_t			 uid;
 	gid_t			 gid;
@@ -499,12 +500,16 @@ affs_remount(struct super_block *sb, int *flags, char *data)
 
 	pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
 
+	lock_kernel();
+
+	sbi = AFFS_SB(sb);
 	*flags |= MS_NODIRATIME;
 
 	if (!parse_options(data, &uid, &gid, &mode, &reserved, &root_block,
 			   &blocksize, &sbi->s_prefix, sbi->s_volume,
 			   &mount_flags)) {
 		kfree(new_opts);
+		unlock_kernel();
 		return -EINVAL;
 	}
 	kfree(sb->s_options);
@@ -515,8 +520,10 @@ affs_remount(struct super_block *sb, int *flags, char *data)
 	sbi->s_uid   = uid;
 	sbi->s_gid   = gid;
 
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 	if (*flags & MS_RDONLY) {
 		sb->s_dirt = 1;
 		while (sb->s_dirt)
@@ -525,6 +532,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
 	} else
 		res = affs_init_bitmap(sb, flags);
 
+	unlock_kernel();
 	return res;
 }
 
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 76afd0d..6046286 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -15,6 +15,7 @@
 #include <linux/vfs.h>
 #include <linux/parser.h>
 #include <linux/namei.h>
+#include <linux/smp_lock.h>
 
 #include "befs.h"
 #include "btree.h"
@@ -891,8 +892,12 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
 static int
 befs_remount(struct super_block *sb, int *flags, char *data)
 {
-	if (!(*flags & MS_RDONLY))
+	lock_kernel();
+	if (!(*flags & MS_RDONLY)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index a7acfe6..9b0f51f 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -553,15 +553,22 @@ error_free_subvol_name:
 
 static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 {
-	struct btrfs_root *root = btrfs_sb(sb);
+	struct btrfs_root *root;
 	int ret;
 
+	lock_kernel();
+	root = btrfs_sb(sb);
+
 	ret = btrfs_parse_options(root, data);
-	if (ret)
+	if (ret) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 
 	if (*flags & MS_RDONLY) {
 		sb->s_flags |= MS_RDONLY;
@@ -569,11 +576,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 		ret =  btrfs_commit_super(root);
 		WARN_ON(ret);
 	} else {
-		if (root->fs_info->fs_devices->rw_devices == 0)
+		if (root->fs_info->fs_devices->rw_devices == 0) {
+			unlock_kernel();
 			return -EACCES;
+		}
 
-		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
+		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0) {
+			unlock_kernel();
 			return -EINVAL;
+		}
 
 		ret = btrfs_cleanup_reloc_trees(root);
 		WARN_ON(ret);
@@ -584,6 +595,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 		sb->s_flags &= ~MS_RDONLY;
 	}
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 355e0ef..9bb69a4 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -564,7 +564,9 @@ static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
 
 static int cifs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_NODIRATIME;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 830f51a..34de212 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -83,7 +83,9 @@ void coda_destroy_inodecache(void)
 
 static int coda_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_NOATIME;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index dd3634e..5626166 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -23,6 +23,7 @@
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
 #include <linux/mutex.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
@@ -215,7 +216,9 @@ static void cramfs_put_super(struct super_block *sb)
 
 static int cramfs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_RDONLY;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 63a4a59..a7e5b83 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -23,6 +23,7 @@
 #include <linux/parser.h>
 #include <linux/fsnotify.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 
 #define DEVPTS_SUPER_MAGIC 0x1cd1
 
@@ -221,8 +222,12 @@ static inline void update_ptmx_mode(struct pts_fs_info *fsi)
 static int devpts_remount(struct super_block *sb, int *flags, char *data)
 {
 	int err;
-	struct pts_fs_info *fsi = DEVPTS_SB(sb);
-	struct pts_mount_opts *opts = &fsi->mount_opts;
+	struct pts_fs_info *fsi;
+	struct pts_mount_opts *opts;
+
+	lock_kernel();
+	fsi = DEVPTS_SB(sb);
+	opts = &fsi->mount_opts;
 
 	err = parse_mount_options(data, PARSE_REMOUNT, opts);
 
@@ -233,6 +238,7 @@ static int devpts_remount(struct super_block *sb, int *flags, char *data)
 	 * so do this even on error return.
 	 */
 	update_ptmx_mode(fsi);
+	unlock_kernel();
 
 	return err;
 }
diff --git a/fs/efs/super.c b/fs/efs/super.c
index f049428..5cc624d 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
+#include <linux/smp_lock.h>
 
 #include "efs.h"
 #include <linux/efs_vh.h>
@@ -101,7 +102,9 @@ static void efs_put_super(struct super_block *s)
 
 static int efs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_RDONLY;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index f983225..33ad910 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1149,13 +1149,17 @@ void ext2_write_super (struct super_block * sb)
 
 static int ext2_remount (struct super_block * sb, int * flags, char * data)
 {
-	struct ext2_sb_info * sbi = EXT2_SB(sb);
+	struct ext2_sb_info * sbi;
 	struct ext2_super_block * es;
-	unsigned long old_mount_opt = sbi->s_mount_opt;
+	unsigned long old_mount_opt;
 	struct ext2_mount_options old_opts;
 	unsigned long old_sb_flags;
 	int err;
 
+	lock_kernel();
+	sbi = EXT2_SB(sb);
+	old_mount_opt = sbi->s_mount_opt;
+
 	/* Store the old options */
 	old_sb_flags = sb->s_flags;
 	old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -1191,12 +1195,16 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
 		sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
 		sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
 	}
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 	if (*flags & MS_RDONLY) {
 		if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
-		    !(sbi->s_mount_state & EXT2_VALID_FS))
+		    !(sbi->s_mount_state & EXT2_VALID_FS)) {
+			unlock_kernel();
 			return 0;
+		}
 		/*
 		 * OK, we are remounting a valid rw partition rdonly, so set
 		 * the rdonly flag and then mark the partition as valid again.
@@ -1223,12 +1231,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
 			sb->s_flags &= ~MS_RDONLY;
 	}
 	ext2_sync_super(sb, es);
+	unlock_kernel();
 	return 0;
 restore_opts:
 	sbi->s_mount_opt = old_opts.s_mount_opt;
 	sbi->s_resuid = old_opts.s_resuid;
 	sbi->s_resgid = old_opts.s_resgid;
 	sb->s_flags = old_sb_flags;
+	unlock_kernel();
 	return err;
 }
 
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 599dbfe..981fdbf 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2499,7 +2499,7 @@ static int ext3_unfreeze(struct super_block *sb)
 static int ext3_remount (struct super_block * sb, int * flags, char * data)
 {
 	struct ext3_super_block * es;
-	struct ext3_sb_info *sbi = EXT3_SB(sb);
+	struct ext3_sb_info *sbi;
 	ext3_fsblk_t n_blocks_count = 0;
 	unsigned long old_sb_flags;
 	struct ext3_mount_options old_opts;
@@ -2508,6 +2508,9 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
 	int i;
 #endif
 
+	lock_kernel();
+	sbi = EXT3_SB(sb);
+
 	/* Store the original options */
 	old_sb_flags = sb->s_flags;
 	old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -2616,6 +2619,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
 		    old_opts.s_qf_names[i] != sbi->s_qf_names[i])
 			kfree(old_opts.s_qf_names[i]);
 #endif
+	unlock_kernel();
 	return 0;
 restore_opts:
 	sb->s_flags = old_sb_flags;
@@ -2632,6 +2636,7 @@ restore_opts:
 		sbi->s_qf_names[i] = old_opts.s_qf_names[i];
 	}
 #endif
+	unlock_kernel();
 	return err;
 }
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2958f4e..3164151 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3360,7 +3360,7 @@ static int ext4_unfreeze(struct super_block *sb)
 static int ext4_remount(struct super_block *sb, int *flags, char *data)
 {
 	struct ext4_super_block *es;
-	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_sb_info *sbi;
 	ext4_fsblk_t n_blocks_count = 0;
 	unsigned long old_sb_flags;
 	struct ext4_mount_options old_opts;
@@ -3371,6 +3371,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 	int i;
 #endif
 
+	lock_kernel();
+	sbi = EXT4_SB(sb);
+
 	/* Store the original options */
 	old_sb_flags = sb->s_flags;
 	old_opts.s_mount_opt = sbi->s_mount_opt;
@@ -3514,6 +3517,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 		    old_opts.s_qf_names[i] != sbi->s_qf_names[i])
 			kfree(old_opts.s_qf_names[i]);
 #endif
+	unlock_kernel();
 	return 0;
 restore_opts:
 	sb->s_flags = old_sb_flags;
@@ -3532,6 +3536,7 @@ restore_opts:
 		sbi->s_qf_names[i] = old_opts.s_qf_names[i];
 	}
 #endif
+	unlock_kernel();
 	return err;
 }
 
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 296785a..5e266e5 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -516,8 +516,11 @@ static void __exit fat_destroy_inodecache(void)
 
 static int fat_remount(struct super_block *sb, int *flags, char *data)
 {
-	struct msdos_sb_info *sbi = MSDOS_SB(sb);
+	struct msdos_sb_info *sbi;
+	lock_kernel();
+	sbi = MSDOS_SB(sb);
 	*flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 1dacda8..ae4b2de 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -41,6 +41,7 @@
 #include <linux/stat.h>
 #include <linux/vfs.h>
 #include <linux/mount.h>
+#include <linux/smp_lock.h>
 
 #include "vxfs.h"
 #include "vxfs_extern.h"
@@ -125,7 +126,9 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
 
 static int vxfs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_RDONLY;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index d1bc4d3..e284486 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -110,9 +110,13 @@ static void fuse_clear_inode(struct inode *inode)
 
 static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
 {
-	if (*flags & MS_MANDLOCK)
+	lock_kernel();
+	if (*flags & MS_MANDLOCK) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 4580195..22e7bd3 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -20,6 +20,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/crc32.h>
 #include <linux/time.h>
+#include <linux/smp_lock.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -434,27 +435,37 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
 {
-	struct gfs2_sbd *sdp = sb->s_fs_info;
-	struct gfs2_args args = sdp->sd_args; /* Default to current settings */
+	struct gfs2_sbd *sdp;
+	struct gfs2_args args;
 	int error;
 
+	lock_kernel();
+	sdp = sb->s_fs_info;
+	args = sdp->sd_args; /* Default to current settings */
+
 	error = gfs2_mount_args(sdp, &args, data);
-	if (error)
+	if (error) {
+		unlock_kernel();
 		return error;
+	}
 
 	/* Not allowed to change locking details */
 	if (strcmp(args.ar_lockproto, sdp->sd_args.ar_lockproto) ||
 	    strcmp(args.ar_locktable, sdp->sd_args.ar_locktable) ||
-	    strcmp(args.ar_hostdata, sdp->sd_args.ar_hostdata))
+	    strcmp(args.ar_hostdata, sdp->sd_args.ar_hostdata)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 
 	/* Some flags must not be changed */
 	if (args_neq(&args, &sdp->sd_args, spectator) ||
 	    args_neq(&args, &sdp->sd_args, ignore_local_fs) ||
 	    args_neq(&args, &sdp->sd_args, localflocks) ||
 	    args_neq(&args, &sdp->sd_args, localcaching) ||
-	    args_neq(&args, &sdp->sd_args, meta))
+	    args_neq(&args, &sdp->sd_args, meta)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 
 	if (sdp->sd_args.ar_spectator)
 		*flags |= MS_RDONLY;
@@ -464,8 +475,10 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
 			error = gfs2_make_fs_ro(sdp);
 		else
 			error = gfs2_make_fs_rw(sdp);
-		if (error)
+		if (error) {
+			unlock_kernel();
 			return error;
+		}
 	}
 
 	sdp->sd_args = args;
@@ -473,6 +486,8 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
 		sb->s_flags |= MS_POSIXACL;
 	else
 		sb->s_flags &= ~MS_POSIXACL;
+
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index a36bb74..b411d0b 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -20,6 +20,7 @@
 #include <linux/parser.h>
 #include <linux/seq_file.h>
 #include <linux/vfs.h>
+#include <linux/smp_lock.h>
 
 #include "hfs_fs.h"
 #include "btree.h"
@@ -100,9 +101,12 @@ static int hfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int hfs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_NODIRATIME;
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 	if (!(*flags & MS_RDONLY)) {
 		if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) {
 			printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
@@ -115,6 +119,7 @@ static int hfs_remount(struct super_block *sb, int *flags, char *data)
 			*flags |= MS_RDONLY;
 		}
 	}
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index f2a6402..0872080 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/vfs.h>
 #include <linux/nls.h>
+#include <linux/smp_lock.h>
 
 static struct inode *hfsplus_alloc_inode(struct super_block *sb);
 static void hfsplus_destroy_inode(struct inode *inode);
@@ -241,16 +242,22 @@ static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
 {
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	lock_kernel();
+
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 	if (!(*flags & MS_RDONLY)) {
 		struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
 		struct hfsplus_sb_info sbi;
 
 		memset(&sbi, 0, sizeof(struct hfsplus_sb_info));
 		sbi.nls = HFSPLUS_SB(sb).nls;
-		if (!hfsplus_parse_options(data, &sbi))
+		if (!hfsplus_parse_options(data, &sbi)) {
+			unlock_kernel();
 			return -EINVAL;
+		}
 
 		if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
 			printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
@@ -269,6 +276,7 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
 			*flags |= MS_RDONLY;
 		}
 	}
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index fecf402..35afe67 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -13,6 +13,7 @@
 #include <linux/statfs.h>
 #include <linux/magic.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 
 /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
 
@@ -388,9 +389,12 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
 	umode_t umask;
 	int lowercase, conv, eas, chk, errs, chkdsk, timeshift;
 	int o;
-	struct hpfs_sb_info *sbi = hpfs_sb(s);
+	struct hpfs_sb_info *sbi;
 	char *new_opts = kstrdup(data, GFP_KERNEL);
 	
+	lock_kernel();
+	sbi = hpfs_sb(s);
+
 	*flags |= MS_NOATIME;
 	
 	uid = sbi->sb_uid; gid = sbi->sb_gid;
@@ -426,10 +430,12 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
 	kfree(s->s_options);
 	s->s_options = new_opts;
 
+	unlock_kernel();
 	return 0;
 
 out_err:
 	kfree(new_opts);
+	unlock_kernel();
 	return -EINVAL;
 }
 
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index b4cbe96..dae0676 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -21,6 +21,7 @@
 #include <linux/statfs.h>
 #include <linux/cdrom.h>
 #include <linux/parser.h>
+#include <linux/smp_lock.h>
 
 #include "isofs.h"
 #include "zisofs.h"
@@ -99,8 +100,10 @@ static void destroy_inodecache(void)
 
 static int isofs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	/* we probably want a lot more here */
 	*flags |= MS_RDONLY;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 249305d..a5162b3 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -20,6 +20,7 @@
 #include <linux/vmalloc.h>
 #include <linux/vfs.h>
 #include <linux/crc32.h>
+#include <linux/smp_lock.h>
 #include "nodelist.h"
 
 static int jffs2_flash_setup(struct jffs2_sb_info *c);
@@ -378,10 +379,15 @@ void jffs2_dirty_inode(struct inode *inode)
 
 int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
 {
-	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+	struct jffs2_sb_info *c;
 
-	if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
+	lock_kernel();
+	c = JFFS2_SB_INFO(sb);
+
+	if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return -EROFS;
+	}
 
 	/* We stop if it was running, then restart if it needs to.
 	   This also catches the case where it was stopped and this
@@ -399,6 +405,7 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
 
 	*flags |= MS_NOATIME;
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 6f21adf..8c87e95 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -32,6 +32,7 @@
 #include <linux/crc32.h>
 #include <asm/uaccess.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 
 #include "jfs_incore.h"
 #include "jfs_filsys.h"
@@ -369,20 +370,28 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
 {
 	s64 newLVSize = 0;
 	int rc = 0;
-	int flag = JFS_SBI(sb)->flag;
+	int flag;
+	int ret;
+
+	lock_kernel();
+	flag = JFS_SBI(sb)->flag;
 
 	if (!parse_options(data, sb, &newLVSize, &flag)) {
+		unlock_kernel();
 		return -EINVAL;
 	}
 	if (newLVSize) {
 		if (sb->s_flags & MS_RDONLY) {
 			printk(KERN_ERR
 		  "JFS: resize requires volume to be mounted read-write\n");
+			unlock_kernel();
 			return -EROFS;
 		}
 		rc = jfs_extendfs(sb, newLVSize, 0);
-		if (rc)
+		if (rc) {
+			unlock_kernel();
 			return rc;
+		}
 	}
 
 	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
@@ -393,23 +402,31 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
 		truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0);
 
 		JFS_SBI(sb)->flag = flag;
-		return jfs_mount_rw(sb, 1);
+		ret = jfs_mount_rw(sb, 1);
+		unlock_kernel();
+		return ret;
 	}
 	if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
 		rc = jfs_umount_rw(sb);
 		JFS_SBI(sb)->flag = flag;
+		unlock_kernel();
 		return rc;
 	}
 	if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
 		if (!(sb->s_flags & MS_RDONLY)) {
 			rc = jfs_umount_rw(sb);
-			if (rc)
+			if (rc) {
+				unlock_kernel();
 				return rc;
+			}
 			JFS_SBI(sb)->flag = flag;
-			return jfs_mount_rw(sb, 1);
+			ret = jfs_mount_rw(sb, 1);
+			unlock_kernel();
+			return ret;
 		}
 	JFS_SBI(sb)->flag = flag;
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index daad3c2..3ea2a5a 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/vfs.h>
+#include <linux/smp_lock.h>
 
 static int minix_write_inode(struct inode * inode, int wait);
 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
@@ -104,16 +105,22 @@ static const struct super_operations minix_sops = {
 
 static int minix_remount (struct super_block * sb, int * flags, char * data)
 {
-	struct minix_sb_info * sbi = minix_sb(sb);
+	struct minix_sb_info * sbi;
 	struct minix_super_block * ms;
 
+	lock_kernel();
+	sbi = minix_sb(sb);
 	ms = sbi->s_ms;
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 	if (*flags & MS_RDONLY) {
 		if (ms->s_state & MINIX_VALID_FS ||
-		    !(sbi->s_mount_state & MINIX_VALID_FS))
+		    !(sbi->s_mount_state & MINIX_VALID_FS)) {
+			unlock_kernel();
 			return 0;
+		}
 		/* Mounting a rw partition read-only. */
 		if (sbi->s_version != MINIX_V3)
 			ms->s_state = sbi->s_mount_state;
@@ -135,6 +142,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
 			printk("MINIX-fs warning: remounting fs with errors, "
 				"running fsck is recommended\n");
 	}
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/namespace.c b/fs/namespace.c
index 2b55ed3..3a4615b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1092,9 +1092,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
 		 */
 		down_write(&sb->s_umount);
 		if (!(sb->s_flags & MS_RDONLY)) {
-			lock_kernel();
 			retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
-			unlock_kernel();
 		}
 		up_write(&sb->s_umount);
 		return retval;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index d642f0e..5b6c11e 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -91,7 +91,9 @@ static void destroy_inodecache(void)
 
 static int ncp_remount(struct super_block *sb, int *flags, char* data)
 {
+	lock_kernel();
 	*flags |= MS_NODIRATIME;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 1679a16..0a54d02 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1792,10 +1792,15 @@ static int
 nfs_remount(struct super_block *sb, int *flags, char *raw_data)
 {
 	int error;
-	struct nfs_server *nfss = sb->s_fs_info;
+	struct nfs_server *nfss;
 	struct nfs_parsed_mount_data *data;
-	struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data;
-	struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
+	struct nfs_mount_data *options;
+	struct nfs4_mount_data *options4;
+
+	lock_kernel();
+	nfss = sb->s_fs_info;
+	options = (struct nfs_mount_data *)raw_data;
+	options4 = (struct nfs4_mount_data *)raw_data;
 	u32 nfsvers = nfss->nfs_client->rpc_ops->version;
 
 	/*
@@ -1806,12 +1811,16 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
 	 */
 	if ((nfsvers == 4 && (!options4 || options4->version == 1)) ||
 	    (nfsvers <= 3 && (!options || (options->version >= 1 &&
-					   options->version <= 6))))
+					   options->version <= 6)))) {
+		unlock_kernel();
 		return 0;
+	}
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (data == NULL)
+	if (data == NULL) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 
 	/* fill out struct with values from existing mount */
 	data->flags = nfss->flags;
@@ -1837,6 +1846,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
 	error = nfs_compare_remount_data(nfss, data);
 out:
 	kfree(data);
+	unlock_kernel();
 	return error;
 }
 
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 6989b03..5082ae2 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -891,13 +891,17 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
 
 static int nilfs_remount(struct super_block *sb, int *flags, char *data)
 {
-	struct nilfs_sb_info *sbi = NILFS_SB(sb);
+	struct nilfs_sb_info *sbi;
 	struct nilfs_super_block *sbp;
-	struct the_nilfs *nilfs = sbi->s_nilfs;
+	struct the_nilfs *nilfs;
 	unsigned long old_sb_flags;
 	struct nilfs_mount_options old_opts;
 	int err;
 
+	lock_kernel();
+	sbi = NILFS_SB(sb);
+	nilfs = sbi->s_nilfs;
+
 	old_sb_flags = sb->s_flags;
 	old_opts.mount_opt = sbi->s_mount_opt;
 	old_opts.snapshot_cno = sbi->s_snapshot_cno;
@@ -977,6 +981,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
 		up(&sb->s_bdev->bd_mount_sem);
 	}
  out:
+	unlock_kernel();
 	return 0;
 
  rw_remount_failed:
@@ -985,6 +990,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
 	sb->s_flags = old_sb_flags;
 	sbi->s_mount_opt = old_opts.mount_opt;
 	sbi->s_snapshot_cno = old_opts.snapshot_cno;
+	unlock_kernel();
 	return err;
 }
 
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index f76951d..8c8f5e4 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -440,9 +440,12 @@ static inline int ntfs_clear_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags)
  */
 static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 {
-	ntfs_volume *vol = NTFS_SB(sb);
+	ntfs_volume *vol;
 
 	ntfs_debug("Entering with remount options string: %s", opt);
+
+	lock_kernel();
+	vol = NTFS_SB(sb);
 #ifndef NTFS_RW
 	/* For read-only compiled driver, enforce read-only flag. */
 	*flags |= MS_RDONLY;
@@ -466,15 +469,18 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 		if (NVolErrors(vol)) {
 			ntfs_error(sb, "Volume has errors and is read-only%s",
 					es);
+			unlock_kernel();
 			return -EROFS;
 		}
 		if (vol->vol_flags & VOLUME_IS_DIRTY) {
 			ntfs_error(sb, "Volume is dirty and read-only%s", es);
+			unlock_kernel();
 			return -EROFS;
 		}
 		if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
 			ntfs_error(sb, "Volume has been modified by chkdsk "
 					"and is read-only%s", es);
+			unlock_kernel();
 			return -EROFS;
 		}
 		if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
@@ -482,11 +488,13 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 					"(0x%x) and is read-only%s",
 					(unsigned)le16_to_cpu(vol->vol_flags),
 					es);
+			unlock_kernel();
 			return -EROFS;
 		}
 		if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
 			ntfs_error(sb, "Failed to set dirty bit in volume "
 					"information flags%s", es);
+			unlock_kernel();
 			return -EROFS;
 		}
 #if 0
@@ -506,18 +514,21 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 			ntfs_error(sb, "Failed to empty journal $LogFile%s",
 					es);
 			NVolSetErrors(vol);
+			unlock_kernel();
 			return -EROFS;
 		}
 		if (!ntfs_mark_quotas_out_of_date(vol)) {
 			ntfs_error(sb, "Failed to mark quotas out of date%s",
 					es);
 			NVolSetErrors(vol);
+			unlock_kernel();
 			return -EROFS;
 		}
 		if (!ntfs_stamp_usnjrnl(vol)) {
 			ntfs_error(sb, "Failed to stamp transation log "
 					"($UsnJrnl)%s", es);
 			NVolSetErrors(vol);
+			unlock_kernel();
 			return -EROFS;
 		}
 	} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
@@ -533,8 +544,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 
 	// TODO: Deal with *flags.
 
-	if (!parse_options(vol, opt))
+	if (!parse_options(vol, opt)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
+	unlock_kernel();
 	ntfs_debug("Done.");
 	return 0;
 }
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 79ff8d9..bee1336 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -42,6 +42,7 @@
 #include <linux/mount.h>
 #include <linux/seq_file.h>
 #include <linux/quotaops.h>
+#include <linux/smp_lock.h>
 
 #define MLOG_MASK_PREFIX ML_SUPER
 #include <cluster/masklog.h>
@@ -593,7 +594,10 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
 	int incompat_features;
 	int ret = 0;
 	struct mount_options parsed_options;
-	struct ocfs2_super *osb = OCFS2_SB(sb);
+	struct ocfs2_super *osb;
+
+	lock_kernel();
+	osb = OCFS2_SB(sb);
 
 	if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
 		ret = -EINVAL;
@@ -698,6 +702,7 @@ unlock_osb:
 			ocfs2_set_journal_params(osb);
 	}
 out:
+	unlock_kernel();
 	return ret;
 }
 
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index ffcd04f..6552755 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/magic.h>
+#include <linux/smp_lock.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
@@ -369,7 +370,9 @@ static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
 
 static int openprom_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_NOATIME;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index fe1f0f3..6ad86a7 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -146,17 +146,20 @@ static int qnx4_remount(struct super_block *sb, int *flags, char *data)
 {
 	struct qnx4_sb_info *qs;
 
+	lock_kernel();
 	qs = qnx4_sb(sb);
 	qs->Version = QNX4_VERSION;
 #ifndef CONFIG_QNX4FS_RW
 	*flags |= MS_RDONLY;
 #endif
 	if (*flags & MS_RDONLY) {
+		unlock_kernel();
 		return 0;
 	}
 
 	mark_buffer_dirty(qs->sb_buf);
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 0ae6486..d8a6843 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -28,6 +28,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/crc32.h>
+#include <linux/smp_lock.h>
 
 struct file_system_type reiserfs_fs_type;
 
@@ -1181,17 +1182,22 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
 	struct reiserfs_super_block *rs;
 	struct reiserfs_transaction_handle th;
 	unsigned long blocks;
-	unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
+	unsigned long mount_options;
 	unsigned long safe_mask = 0;
 	unsigned int commit_max_age = (unsigned int)-1;
-	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	struct reiserfs_journal *journal;
 	char *new_opts = kstrdup(arg, GFP_KERNEL);
 	int err;
 	char *qf_names[MAXQUOTAS];
 	unsigned int qfmt = 0;
 #ifdef CONFIG_QUOTA
 	int i;
+#endif
 
+	lock_kernel();
+	mount_options = REISERFS_SB(s)->s_mount_opt;
+	journal = SB_JOURNAL(s);
+#ifdef CONFIG_QUOTA
 	memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names));
 #endif
 
@@ -1318,10 +1324,12 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
 out_ok:
 	kfree(s->s_options);
 	s->s_options = new_opts;
+	unlock_kernel();
 	return 0;
 
 out_err:
 	kfree(new_opts);
+	unlock_kernel();
 	return err;
 }
 
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 10ca7d9..a35fc9f 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -72,6 +72,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/uaccess.h>
+#include <linux/smp_lock.h>
 #include "internal.h"
 
 static struct kmem_cache *romfs_inode_cachep;
@@ -427,7 +428,9 @@ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
  */
 static int romfs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_RDONLY;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index fc27fbf..e26eeb6 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -93,7 +93,9 @@ static void destroy_inodecache(void)
 
 static int smb_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_NODIRATIME;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index ffa6edc..40a3610 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -36,6 +36,7 @@
 #include <linux/module.h>
 #include <linux/zlib.h>
 #include <linux/magic.h>
+#include <linux/smp_lock.h>
 
 #include "squashfs_fs.h"
 #include "squashfs_fs_sb.h"
@@ -321,7 +322,9 @@ static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int squashfs_remount(struct super_block *sb, int *flags, char *data)
 {
+	lock_kernel();
 	*flags |= MS_RDONLY;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/super.c b/fs/super.c
index 786fe7d..29d9343 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -686,13 +686,9 @@ static void do_emergency_remount(struct work_struct *work)
 		down_read(&sb->s_umount);
 		if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) {
 			/*
-			 * ->remount_fs needs lock_kernel().
-			 *
 			 * What lock protects sb->s_flags??
 			 */
-			lock_kernel();
 			do_remount_sb(sb, MS_RDONLY, NULL, 1);
-			unlock_kernel();
 		}
 		drop_super(sb);
 		spin_lock(&sb_lock);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index da20b48..41c3c10 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -28,6 +28,7 @@
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
 #include <linux/namei.h>
+#include <linux/smp_lock.h>
 #include <asm/byteorder.h>
 #include "sysv.h"
 
@@ -60,11 +61,15 @@ clean:
 
 static int sysv_remount(struct super_block *sb, int *flags, char *data)
 {
-	struct sysv_sb_info *sbi = SYSV_SB(sb);
+	struct sysv_sb_info *sbi;
+
+	lock_kernel();
+	sbi = SYSV_SB(sb);
 	if (sbi->s_forced_ro)
 		*flags |= MS_RDONLY;
 	if (!(*flags & MS_RDONLY))
 		sb->s_dirt = 1;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index faa44f9..5c74c4d 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,7 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
+#include <linux/smp_lock.h>
 #include "ubifs.h"
 
 /*
@@ -1758,27 +1759,34 @@ static void ubifs_put_super(struct super_block *sb)
 static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 {
 	int err;
-	struct ubifs_info *c = sb->s_fs_info;
+	struct ubifs_info *c;
 
 	dbg_gen("old flags %#lx, new flags %#x", sb->s_flags, *flags);
 
+	lock_kernel();
+	c = sb->s_fs_info;
 	err = ubifs_parse_options(c, data, 1);
 	if (err) {
 		ubifs_err("invalid or unknown remount parameter");
+		unlock_kernel();
 		return err;
 	}
 
 	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
 		if (c->ro_media) {
 			ubifs_msg("cannot re-mount due to prior errors");
+			unlock_kernel();
 			return -EROFS;
 		}
 		err = ubifs_remount_rw(c);
-		if (err)
+		if (err) {
+			unlock_kernel();
 			return err;
+		}
 	} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
 		if (c->ro_media) {
 			ubifs_msg("cannot re-mount due to prior errors");
+			unlock_kernel();
 			return -EROFS;
 		}
 		ubifs_remount_ro(c);
@@ -1793,6 +1801,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 	}
 
 	ubifs_assert(c->lst.taken_empty_lebs > 0);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 72348cc..ae50550 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -556,8 +556,10 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
 static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
 {
 	struct udf_options uopt;
-	struct udf_sb_info *sbi = UDF_SB(sb);
+	struct udf_sb_info *sbi;
 
+	lock_kernel();
+	sbi = UDF_SB(sb);
 	uopt.flags = sbi->s_flags;
 	uopt.uid   = sbi->s_uid;
 	uopt.gid   = sbi->s_gid;
@@ -565,8 +567,10 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
 	uopt.fmode = sbi->s_fmode;
 	uopt.dmode = sbi->s_dmode;
 
-	if (!udf_parse_options(options, &uopt, true))
+	if (!udf_parse_options(options, &uopt, true)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 
 	sbi->s_flags = uopt.flags;
 	sbi->s_uid   = uopt.uid;
@@ -581,13 +585,16 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
 			*flags |= MS_RDONLY;
 	}
 
-	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+		unlock_kernel();
 		return 0;
+	}
 	if (*flags & MS_RDONLY)
 		udf_close_lvid(sb);
 	else
 		udf_open_lvid(sb);
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 6035929..faaebd6 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1172,6 +1172,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
 	unsigned new_mount_opt, ufstype;
 	unsigned flags;
 	
+	lock_kernel();
 	uspi = UFS_SB(sb)->s_uspi;
 	flags = UFS_SB(sb)->s_flags;
 	usb1 = ubh_get_usb_first(uspi);
@@ -1184,17 +1185,21 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
 	ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
 	new_mount_opt = 0;
 	ufs_set_opt (new_mount_opt, ONERROR_LOCK);
-	if (!ufs_parse_options (data, &new_mount_opt))
+	if (!ufs_parse_options (data, &new_mount_opt)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 	if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
 		new_mount_opt |= ufstype;
 	} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
 		printk("ufstype can't be changed during remount\n");
+		unlock_kernel();
 		return -EINVAL;
 	}
 
 	if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
 		UFS_SB(sb)->s_mount_opt = new_mount_opt;
+		unlock_kernel();
 		return 0;
 	}
 	
@@ -1219,6 +1224,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
 #ifndef CONFIG_UFS_FS_WRITE
 		printk("ufs was compiled with read-only support, "
 		"can't be mounted as read-write\n");
+		unlock_kernel();
 		return -EINVAL;
 #else
 		if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
@@ -1227,16 +1233,19 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
 		    ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
 		    ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
 			printk("this ufstype is read-only supported\n");
+			unlock_kernel();
 			return -EINVAL;
 		}
 		if (!ufs_read_cylinder_structures(sb)) {
 			printk("failed during remounting\n");
+			unlock_kernel();
 			return -EPERM;
 		}
 		sb->s_flags &= ~MS_RDONLY;
 #endif
 	}
 	UFS_SB(sb)->s_mount_opt = new_mount_opt;
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index bb68526..1b5660b 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -67,6 +67,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/parser.h>
+#include <linux/smp_lock.h>
 
 static struct super_operations xfs_super_operations;
 static kmem_zone_t *xfs_ioend_zone;
@@ -1206,11 +1207,13 @@ xfs_fs_remount(
 	int			*flags,
 	char			*options)
 {
-	struct xfs_mount	*mp = XFS_M(sb);
+	struct xfs_mount	*mp;
 	substring_t		args[MAX_OPT_ARGS];
 	char			*p;
 	int			error;
 
+	lock_kernel();
+	mp = XFS_M(sb);
 	while ((p = strsep(&options, ",")) != NULL) {
 		int token;
 
@@ -1275,6 +1278,7 @@ xfs_fs_remount(
 			if (error) {
 				cmn_err(CE_WARN,
 					"XFS: failed to write sb changes");
+				unlock_kernel();
 				return error;
 			}
 			mp->m_update_flags = 0;
@@ -1288,6 +1292,7 @@ xfs_fs_remount(
 		mp->m_flags |= XFS_MOUNT_RDONLY;
 	}
 
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 382109b..5510422 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -46,6 +46,7 @@
 #include <linux/cgroupstats.h>
 #include <linux/hash.h>
 #include <linux/namei.h>
+#include <linux/smp_lock.h>
 
 #include <asm/atomic.h>
 
@@ -896,10 +897,13 @@ static int parse_cgroupfs_options(char *data,
 static int cgroup_remount(struct super_block *sb, int *flags, char *data)
 {
 	int ret = 0;
-	struct cgroupfs_root *root = sb->s_fs_info;
-	struct cgroup *cgrp = &root->top_cgroup;
+	struct cgroupfs_root *root;
+	struct cgroup *cgrp;
 	struct cgroup_sb_opts opts;
 
+	lock_kernel();
+	root = sb->s_fs_info;
+	cgrp = &root->top_cgroup;
 	mutex_lock(&cgrp->dentry->d_inode->i_mutex);
 	mutex_lock(&cgroup_mutex);
 
@@ -927,6 +931,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
 	kfree(opts.release_agent);
 	mutex_unlock(&cgroup_mutex);
 	mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+	unlock_kernel();
 	return ret;
 }
 
diff --git a/mm/shmem.c b/mm/shmem.c
index f9cb20e..863cb5b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/swap.h>
 #include <linux/ima.h>
+#include <linux/smp_lock.h>
 
 static struct vfsmount *shm_mnt;
 
@@ -2227,14 +2228,19 @@ bad_val:
 
 static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
 {
-	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-	struct shmem_sb_info config = *sbinfo;
+	struct shmem_sb_info *sbinfo;
+	struct shmem_sb_info config;
 	unsigned long blocks;
 	unsigned long inodes;
 	int error = -EINVAL;
 
-	if (shmem_parse_options(data, &config, true))
+	lock_kernel();
+	sbinfo = SHMEM_SB(sb);
+	config = *sbinfo;
+	if (shmem_parse_options(data, &config, true)) {
+		unlock_kernel();
 		return error;
+	}
 
 	spin_lock(&sbinfo->stat_lock);
 	blocks = sbinfo->max_blocks - sbinfo->free_blocks;
@@ -2264,6 +2270,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
 	sbinfo->mpol        = config.mpol;	/* transfers initial ref */
 out:
 	spin_unlock(&sbinfo->stat_lock);
+	unlock_kernel();
 	return error;
 }
 
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ