diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2009-01-06 06:52:25 -0500 |
---|---|---|
committer | Steven Whitehouse <steve@dolmen.chygwyn.com> | 2009-03-24 07:21:10 -0400 |
commit | 6f04c1c7fe9566d777fb7961391690866839e722 (patch) | |
tree | de864fb7c56ef59a799c7fddc713bdb16bb4435c /fs/gfs2/ops_super.c | |
parent | 8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (diff) |
GFS2: Fix remount argument parsing
The following patch fixes an issue relating to remount and argument
parsing. After this fix is applied, remount becomes atomic in that
it either succeeds changing the mount to the new state, or it fails
and leaves it in the old state. Previously it was possible for the
parsing of options to fail part way though and for the fs to be left
in a state where some of the new arguments had been applied, but some
had not.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_super.c')
-rw-r--r-- | fs/gfs2/ops_super.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 320323d03479..f0699ac453f7 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include "glock.h" | 27 | #include "glock.h" |
28 | #include "inode.h" | 28 | #include "inode.h" |
29 | #include "log.h" | 29 | #include "log.h" |
30 | #include "mount.h" | ||
31 | #include "quota.h" | 30 | #include "quota.h" |
32 | #include "recovery.h" | 31 | #include "recovery.h" |
33 | #include "rgrp.h" | 32 | #include "rgrp.h" |
@@ -40,6 +39,8 @@ | |||
40 | #include "bmap.h" | 39 | #include "bmap.h" |
41 | #include "meta_io.h" | 40 | #include "meta_io.h" |
42 | 41 | ||
42 | #define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x) | ||
43 | |||
43 | /** | 44 | /** |
44 | * gfs2_write_inode - Make sure the inode is stable on the disk | 45 | * gfs2_write_inode - Make sure the inode is stable on the disk |
45 | * @inode: The inode | 46 | * @inode: The inode |
@@ -435,25 +436,45 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
435 | static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | 436 | static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) |
436 | { | 437 | { |
437 | struct gfs2_sbd *sdp = sb->s_fs_info; | 438 | struct gfs2_sbd *sdp = sb->s_fs_info; |
439 | struct gfs2_args args = sdp->sd_args; /* Default to current settings */ | ||
438 | int error; | 440 | int error; |
439 | 441 | ||
440 | error = gfs2_mount_args(sdp, data, 1); | 442 | error = gfs2_mount_args(sdp, &args, data); |
441 | if (error) | 443 | if (error) |
442 | return error; | 444 | return error; |
443 | 445 | ||
446 | /* Not allowed to change locking details */ | ||
447 | if (strcmp(args.ar_lockproto, sdp->sd_args.ar_lockproto) || | ||
448 | strcmp(args.ar_locktable, sdp->sd_args.ar_locktable) || | ||
449 | strcmp(args.ar_hostdata, sdp->sd_args.ar_hostdata)) | ||
450 | return -EINVAL; | ||
451 | |||
452 | /* Some flags must not be changed */ | ||
453 | if (args_neq(&args, &sdp->sd_args, spectator) || | ||
454 | args_neq(&args, &sdp->sd_args, ignore_local_fs) || | ||
455 | args_neq(&args, &sdp->sd_args, localflocks) || | ||
456 | args_neq(&args, &sdp->sd_args, localcaching) || | ||
457 | args_neq(&args, &sdp->sd_args, meta)) | ||
458 | return -EINVAL; | ||
459 | |||
444 | if (sdp->sd_args.ar_spectator) | 460 | if (sdp->sd_args.ar_spectator) |
445 | *flags |= MS_RDONLY; | 461 | *flags |= MS_RDONLY; |
446 | else { | 462 | |
447 | if (*flags & MS_RDONLY) { | 463 | if ((sb->s_flags ^ *flags) & MS_RDONLY) { |
448 | if (!(sb->s_flags & MS_RDONLY)) | 464 | if (*flags & MS_RDONLY) |
449 | error = gfs2_make_fs_ro(sdp); | 465 | error = gfs2_make_fs_ro(sdp); |
450 | } else if (!(*flags & MS_RDONLY) && | 466 | else |
451 | (sb->s_flags & MS_RDONLY)) { | ||
452 | error = gfs2_make_fs_rw(sdp); | 467 | error = gfs2_make_fs_rw(sdp); |
453 | } | 468 | if (error) |
469 | return error; | ||
454 | } | 470 | } |
455 | 471 | ||
456 | return error; | 472 | sdp->sd_args = args; |
473 | if (sdp->sd_args.ar_posix_acl) | ||
474 | sb->s_flags |= MS_POSIXACL; | ||
475 | else | ||
476 | sb->s_flags &= ~MS_POSIXACL; | ||
477 | return 0; | ||
457 | } | 478 | } |
458 | 479 | ||
459 | /** | 480 | /** |