diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-05-06 10:43:07 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-11 21:36:08 -0400 |
commit | bbd6851a3213a525128473e978b692ab6ac11aba (patch) | |
tree | 8ebddebadd8992871ab98456187cb00849a82058 | |
parent | 6cfd0148425e528b859b26e436b01f23f6926224 (diff) |
Push lock_super() into the ->remount_fs() of filesystems that care about it
Note that since we can't run into contention between remount_fs and write_super
(due to exclusion on s_umount), we have to care only about filesystems that
touch lock_super() on their own. Out of those ext3, ext4, hpfs, sysv and ufs
do need it; fat doesn't since its ->remount_fs() only accesses assign-once
data (basically, it's "we have no atime on directories and only have atime on
files for vfat; force nodiratime and possibly noatime into *flags").
[folded a build fix from hch]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/ext3/super.c | 3 | ||||
-rw-r--r-- | fs/ext4/super.c | 3 | ||||
-rw-r--r-- | fs/hpfs/super.c | 3 | ||||
-rw-r--r-- | fs/super.c | 2 | ||||
-rw-r--r-- | fs/sysv/inode.c | 2 | ||||
-rw-r--r-- | fs/ufs/super.c | 11 |
6 files changed, 21 insertions, 3 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 546b8d732bf2..e213a2613a56 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2491,6 +2491,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2491 | #endif | 2491 | #endif |
2492 | 2492 | ||
2493 | /* Store the original options */ | 2493 | /* Store the original options */ |
2494 | lock_super(sb); | ||
2494 | old_sb_flags = sb->s_flags; | 2495 | old_sb_flags = sb->s_flags; |
2495 | old_opts.s_mount_opt = sbi->s_mount_opt; | 2496 | old_opts.s_mount_opt = sbi->s_mount_opt; |
2496 | old_opts.s_resuid = sbi->s_resuid; | 2497 | old_opts.s_resuid = sbi->s_resuid; |
@@ -2598,6 +2599,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2598 | old_opts.s_qf_names[i] != sbi->s_qf_names[i]) | 2599 | old_opts.s_qf_names[i] != sbi->s_qf_names[i]) |
2599 | kfree(old_opts.s_qf_names[i]); | 2600 | kfree(old_opts.s_qf_names[i]); |
2600 | #endif | 2601 | #endif |
2602 | unlock_super(sb); | ||
2601 | return 0; | 2603 | return 0; |
2602 | restore_opts: | 2604 | restore_opts: |
2603 | sb->s_flags = old_sb_flags; | 2605 | sb->s_flags = old_sb_flags; |
@@ -2614,6 +2616,7 @@ restore_opts: | |||
2614 | sbi->s_qf_names[i] = old_opts.s_qf_names[i]; | 2616 | sbi->s_qf_names[i] = old_opts.s_qf_names[i]; |
2615 | } | 2617 | } |
2616 | #endif | 2618 | #endif |
2619 | unlock_super(sb); | ||
2617 | return err; | 2620 | return err; |
2618 | } | 2621 | } |
2619 | 2622 | ||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1d4180b86772..a9c683425929 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3421,6 +3421,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3421 | #endif | 3421 | #endif |
3422 | 3422 | ||
3423 | /* Store the original options */ | 3423 | /* Store the original options */ |
3424 | lock_super(sb); | ||
3424 | old_sb_flags = sb->s_flags; | 3425 | old_sb_flags = sb->s_flags; |
3425 | old_opts.s_mount_opt = sbi->s_mount_opt; | 3426 | old_opts.s_mount_opt = sbi->s_mount_opt; |
3426 | old_opts.s_resuid = sbi->s_resuid; | 3427 | old_opts.s_resuid = sbi->s_resuid; |
@@ -3554,6 +3555,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3554 | old_opts.s_qf_names[i] != sbi->s_qf_names[i]) | 3555 | old_opts.s_qf_names[i] != sbi->s_qf_names[i]) |
3555 | kfree(old_opts.s_qf_names[i]); | 3556 | kfree(old_opts.s_qf_names[i]); |
3556 | #endif | 3557 | #endif |
3558 | unlock_super(sb); | ||
3557 | return 0; | 3559 | return 0; |
3558 | 3560 | ||
3559 | restore_opts: | 3561 | restore_opts: |
@@ -3573,6 +3575,7 @@ restore_opts: | |||
3573 | sbi->s_qf_names[i] = old_opts.s_qf_names[i]; | 3575 | sbi->s_qf_names[i] = old_opts.s_qf_names[i]; |
3574 | } | 3576 | } |
3575 | #endif | 3577 | #endif |
3578 | unlock_super(sb); | ||
3576 | return err; | 3579 | return err; |
3577 | } | 3580 | } |
3578 | 3581 | ||
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 437a32e9deac..f68193cf0811 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -398,6 +398,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) | |||
398 | 398 | ||
399 | *flags |= MS_NOATIME; | 399 | *flags |= MS_NOATIME; |
400 | 400 | ||
401 | lock_super(s); | ||
401 | uid = sbi->sb_uid; gid = sbi->sb_gid; | 402 | uid = sbi->sb_uid; gid = sbi->sb_gid; |
402 | umask = 0777 & ~sbi->sb_mode; | 403 | umask = 0777 & ~sbi->sb_mode; |
403 | lowercase = sbi->sb_lowercase; conv = sbi->sb_conv; | 404 | lowercase = sbi->sb_lowercase; conv = sbi->sb_conv; |
@@ -430,9 +431,11 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) | |||
430 | 431 | ||
431 | replace_mount_options(s, new_opts); | 432 | replace_mount_options(s, new_opts); |
432 | 433 | ||
434 | unlock_super(s); | ||
433 | return 0; | 435 | return 0; |
434 | 436 | ||
435 | out_err: | 437 | out_err: |
438 | unlock_super(s); | ||
436 | kfree(new_opts); | 439 | kfree(new_opts); |
437 | return -EINVAL; | 440 | return -EINVAL; |
438 | } | 441 | } |
diff --git a/fs/super.c b/fs/super.c index bdd7158b785e..2a49fed77453 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -556,9 +556,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
556 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); | 556 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); |
557 | 557 | ||
558 | if (sb->s_op->remount_fs) { | 558 | if (sb->s_op->remount_fs) { |
559 | lock_super(sb); | ||
560 | retval = sb->s_op->remount_fs(sb, &flags, data); | 559 | retval = sb->s_op->remount_fs(sb, &flags, data); |
561 | unlock_super(sb); | ||
562 | if (retval) | 560 | if (retval) |
563 | return retval; | 561 | return retval; |
564 | } | 562 | } |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index a8189864c241..e0a39f1fb88e 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -61,10 +61,12 @@ clean: | |||
61 | static int sysv_remount(struct super_block *sb, int *flags, char *data) | 61 | static int sysv_remount(struct super_block *sb, int *flags, char *data) |
62 | { | 62 | { |
63 | struct sysv_sb_info *sbi = SYSV_SB(sb); | 63 | struct sysv_sb_info *sbi = SYSV_SB(sb); |
64 | lock_super(sb); | ||
64 | if (sbi->s_forced_ro) | 65 | if (sbi->s_forced_ro) |
65 | *flags |= MS_RDONLY; | 66 | *flags |= MS_RDONLY; |
66 | if (!(*flags & MS_RDONLY)) | 67 | if (!(*flags & MS_RDONLY)) |
67 | sb->s_dirt = 1; | 68 | sb->s_dirt = 1; |
69 | unlock_super(sb); | ||
68 | return 0; | 70 | return 0; |
69 | } | 71 | } |
70 | 72 | ||
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 2b4d2b6234df..a5ecabfdc976 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -1181,6 +1181,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1181 | unsigned new_mount_opt, ufstype; | 1181 | unsigned new_mount_opt, ufstype; |
1182 | unsigned flags; | 1182 | unsigned flags; |
1183 | 1183 | ||
1184 | lock_super(sb); | ||
1184 | uspi = UFS_SB(sb)->s_uspi; | 1185 | uspi = UFS_SB(sb)->s_uspi; |
1185 | flags = UFS_SB(sb)->s_flags; | 1186 | flags = UFS_SB(sb)->s_flags; |
1186 | usb1 = ubh_get_usb_first(uspi); | 1187 | usb1 = ubh_get_usb_first(uspi); |
@@ -1193,17 +1194,21 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1193 | ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE; | 1194 | ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE; |
1194 | new_mount_opt = 0; | 1195 | new_mount_opt = 0; |
1195 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); | 1196 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); |
1196 | if (!ufs_parse_options (data, &new_mount_opt)) | 1197 | if (!ufs_parse_options (data, &new_mount_opt)) { |
1198 | unlock_super(sb); | ||
1197 | return -EINVAL; | 1199 | return -EINVAL; |
1200 | } | ||
1198 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { | 1201 | if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) { |
1199 | new_mount_opt |= ufstype; | 1202 | new_mount_opt |= ufstype; |
1200 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { | 1203 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { |
1201 | printk("ufstype can't be changed during remount\n"); | 1204 | printk("ufstype can't be changed during remount\n"); |
1205 | unlock_super(sb); | ||
1202 | return -EINVAL; | 1206 | return -EINVAL; |
1203 | } | 1207 | } |
1204 | 1208 | ||
1205 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { | 1209 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { |
1206 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1210 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1211 | unlock_super(sb); | ||
1207 | return 0; | 1212 | return 0; |
1208 | } | 1213 | } |
1209 | 1214 | ||
@@ -1228,6 +1233,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1228 | #ifndef CONFIG_UFS_FS_WRITE | 1233 | #ifndef CONFIG_UFS_FS_WRITE |
1229 | printk("ufs was compiled with read-only support, " | 1234 | printk("ufs was compiled with read-only support, " |
1230 | "can't be mounted as read-write\n"); | 1235 | "can't be mounted as read-write\n"); |
1236 | unlock_super(sb); | ||
1231 | return -EINVAL; | 1237 | return -EINVAL; |
1232 | #else | 1238 | #else |
1233 | if (ufstype != UFS_MOUNT_UFSTYPE_SUN && | 1239 | if (ufstype != UFS_MOUNT_UFSTYPE_SUN && |
@@ -1236,16 +1242,19 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1236 | ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && | 1242 | ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && |
1237 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { | 1243 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { |
1238 | printk("this ufstype is read-only supported\n"); | 1244 | printk("this ufstype is read-only supported\n"); |
1245 | unlock_super(sb); | ||
1239 | return -EINVAL; | 1246 | return -EINVAL; |
1240 | } | 1247 | } |
1241 | if (!ufs_read_cylinder_structures(sb)) { | 1248 | if (!ufs_read_cylinder_structures(sb)) { |
1242 | printk("failed during remounting\n"); | 1249 | printk("failed during remounting\n"); |
1250 | unlock_super(sb); | ||
1243 | return -EPERM; | 1251 | return -EPERM; |
1244 | } | 1252 | } |
1245 | sb->s_flags &= ~MS_RDONLY; | 1253 | sb->s_flags &= ~MS_RDONLY; |
1246 | #endif | 1254 | #endif |
1247 | } | 1255 | } |
1248 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1256 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1257 | unlock_super(sb); | ||
1249 | return 0; | 1258 | return 0; |
1250 | } | 1259 | } |
1251 | 1260 | ||