aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_super.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2009-01-06 06:52:25 -0500
committerSteven Whitehouse <steve@dolmen.chygwyn.com>2009-03-24 07:21:10 -0400
commit6f04c1c7fe9566d777fb7961391690866839e722 (patch)
treede864fb7c56ef59a799c7fddc713bdb16bb4435c /fs/gfs2/ops_super.c
parent8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (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.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 320323d0347..f0699ac453f 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)
435static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) 436static 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/**