aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/mount.c111
-rw-r--r--fs/gfs2/mount.h17
-rw-r--r--fs/gfs2/ops_fstype.c11
-rw-r--r--fs/gfs2/ops_super.c41
-rw-r--r--fs/gfs2/super.h26
5 files changed, 73 insertions, 133 deletions
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index 3cb0a44ba023..3524ae81189b 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -17,7 +17,7 @@
17 17
18#include "gfs2.h" 18#include "gfs2.h"
19#include "incore.h" 19#include "incore.h"
20#include "mount.h" 20#include "super.h"
21#include "sys.h" 21#include "sys.h"
22#include "util.h" 22#include "util.h"
23 23
@@ -77,101 +77,46 @@ static const match_table_t tokens = {
77 * Return: errno 77 * Return: errno
78 */ 78 */
79 79
80int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) 80int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
81{ 81{
82 struct gfs2_args *args = &sdp->sd_args; 82 char *o;
83 char *data = data_arg; 83 int token;
84 char *options, *o, *v; 84 substring_t tmp[MAX_OPT_ARGS];
85 int error = 0;
86
87 if (!remount) {
88 /* Set some defaults */
89 args->ar_quota = GFS2_QUOTA_DEFAULT;
90 args->ar_data = GFS2_DATA_DEFAULT;
91 }
92 85
93 /* Split the options into tokens with the "," character and 86 /* Split the options into tokens with the "," character and
94 process them */ 87 process them */
95 88
96 for (options = data; (o = strsep(&options, ",")); ) { 89 while (1) {
97 int token; 90 o = strsep(&options, ",");
98 substring_t tmp[MAX_OPT_ARGS]; 91 if (o == NULL)
99 92 break;
100 if (!*o) 93 if (*o == '\0')
101 continue; 94 continue;
102 95
103 token = match_token(o, tokens, tmp); 96 token = match_token(o, tokens, tmp);
104 switch (token) { 97 switch (token) {
105 case Opt_lockproto: 98 case Opt_lockproto:
106 v = match_strdup(&tmp[0]); 99 match_strlcpy(args->ar_lockproto, &tmp[0],
107 if (!v) { 100 GFS2_LOCKNAME_LEN);
108 fs_info(sdp, "no memory for lockproto\n");
109 error = -ENOMEM;
110 goto out_error;
111 }
112
113 if (remount && strcmp(v, args->ar_lockproto)) {
114 kfree(v);
115 goto cant_remount;
116 }
117
118 strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN);
119 args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0;
120 kfree(v);
121 break; 101 break;
122 case Opt_locktable: 102 case Opt_locktable:
123 v = match_strdup(&tmp[0]); 103 match_strlcpy(args->ar_locktable, &tmp[0],
124 if (!v) { 104 GFS2_LOCKNAME_LEN);
125 fs_info(sdp, "no memory for locktable\n");
126 error = -ENOMEM;
127 goto out_error;
128 }
129
130 if (remount && strcmp(v, args->ar_locktable)) {
131 kfree(v);
132 goto cant_remount;
133 }
134
135 strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN);
136 args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0;
137 kfree(v);
138 break; 105 break;
139 case Opt_hostdata: 106 case Opt_hostdata:
140 v = match_strdup(&tmp[0]); 107 match_strlcpy(args->ar_hostdata, &tmp[0],
141 if (!v) { 108 GFS2_LOCKNAME_LEN);
142 fs_info(sdp, "no memory for hostdata\n");
143 error = -ENOMEM;
144 goto out_error;
145 }
146
147 if (remount && strcmp(v, args->ar_hostdata)) {
148 kfree(v);
149 goto cant_remount;
150 }
151
152 strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN);
153 args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0;
154 kfree(v);
155 break; 109 break;
156 case Opt_spectator: 110 case Opt_spectator:
157 if (remount && !args->ar_spectator)
158 goto cant_remount;
159 args->ar_spectator = 1; 111 args->ar_spectator = 1;
160 sdp->sd_vfs->s_flags |= MS_RDONLY;
161 break; 112 break;
162 case Opt_ignore_local_fs: 113 case Opt_ignore_local_fs:
163 if (remount && !args->ar_ignore_local_fs)
164 goto cant_remount;
165 args->ar_ignore_local_fs = 1; 114 args->ar_ignore_local_fs = 1;
166 break; 115 break;
167 case Opt_localflocks: 116 case Opt_localflocks:
168 if (remount && !args->ar_localflocks)
169 goto cant_remount;
170 args->ar_localflocks = 1; 117 args->ar_localflocks = 1;
171 break; 118 break;
172 case Opt_localcaching: 119 case Opt_localcaching:
173 if (remount && !args->ar_localcaching)
174 goto cant_remount;
175 args->ar_localcaching = 1; 120 args->ar_localcaching = 1;
176 break; 121 break;
177 case Opt_debug: 122 case Opt_debug:
@@ -181,17 +126,13 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
181 args->ar_debug = 0; 126 args->ar_debug = 0;
182 break; 127 break;
183 case Opt_upgrade: 128 case Opt_upgrade:
184 if (remount && !args->ar_upgrade)
185 goto cant_remount;
186 args->ar_upgrade = 1; 129 args->ar_upgrade = 1;
187 break; 130 break;
188 case Opt_acl: 131 case Opt_acl:
189 args->ar_posix_acl = 1; 132 args->ar_posix_acl = 1;
190 sdp->sd_vfs->s_flags |= MS_POSIXACL;
191 break; 133 break;
192 case Opt_noacl: 134 case Opt_noacl:
193 args->ar_posix_acl = 0; 135 args->ar_posix_acl = 0;
194 sdp->sd_vfs->s_flags &= ~MS_POSIXACL;
195 break; 136 break;
196 case Opt_quota_off: 137 case Opt_quota_off:
197 args->ar_quota = GFS2_QUOTA_OFF; 138 args->ar_quota = GFS2_QUOTA_OFF;
@@ -215,29 +156,15 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
215 args->ar_data = GFS2_DATA_ORDERED; 156 args->ar_data = GFS2_DATA_ORDERED;
216 break; 157 break;
217 case Opt_meta: 158 case Opt_meta:
218 if (remount && args->ar_meta != 1)
219 goto cant_remount;
220 args->ar_meta = 1; 159 args->ar_meta = 1;
221 break; 160 break;
222 case Opt_err: 161 case Opt_err:
223 default: 162 default:
224 fs_info(sdp, "unknown option: %s\n", o); 163 fs_info(sdp, "invalid mount option: %s\n", o);
225 error = -EINVAL; 164 return -EINVAL;
226 goto out_error;
227 } 165 }
228 } 166 }
229 167
230out_error: 168 return 0;
231 if (error)
232 fs_info(sdp, "invalid mount option(s)\n");
233
234 if (data != data_arg)
235 kfree(data);
236
237 return error;
238
239cant_remount:
240 fs_info(sdp, "can't remount with option %s\n", o);
241 return -EINVAL;
242} 169}
243 170
diff --git a/fs/gfs2/mount.h b/fs/gfs2/mount.h
deleted file mode 100644
index 401288acfdf3..000000000000
--- a/fs/gfs2/mount.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License version 2.
8 */
9
10#ifndef __MOUNT_DOT_H__
11#define __MOUNT_DOT_H__
12
13struct gfs2_sbd;
14
15int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount);
16
17#endif /* __MOUNT_DOT_H__ */
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index f91eebdde581..3eb49edae542 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -25,7 +25,6 @@
25#include "glock.h" 25#include "glock.h"
26#include "glops.h" 26#include "glops.h"
27#include "inode.h" 27#include "inode.h"
28#include "mount.h"
29#include "recovery.h" 28#include "recovery.h"
30#include "rgrp.h" 29#include "rgrp.h"
31#include "super.h" 30#include "super.h"
@@ -1116,12 +1115,20 @@ static int fill_super(struct super_block *sb, void *data, int silent)
1116 return -ENOMEM; 1115 return -ENOMEM;
1117 } 1116 }
1118 1117
1119 error = gfs2_mount_args(sdp, (char *)data, 0); 1118 sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT;
1119 sdp->sd_args.ar_data = GFS2_DATA_DEFAULT;
1120
1121 error = gfs2_mount_args(sdp, &sdp->sd_args, data);
1120 if (error) { 1122 if (error) {
1121 printk(KERN_WARNING "GFS2: can't parse mount arguments\n"); 1123 printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
1122 goto fail; 1124 goto fail;
1123 } 1125 }
1124 1126
1127 if (sdp->sd_args.ar_spectator)
1128 sb->s_flags |= MS_RDONLY;
1129 if (sdp->sd_args.ar_posix_acl)
1130 sb->s_flags |= MS_POSIXACL;
1131
1125 sb->s_magic = GFS2_MAGIC; 1132 sb->s_magic = GFS2_MAGIC;
1126 sb->s_op = &gfs2_super_ops; 1133 sb->s_op = &gfs2_super_ops;
1127 sb->s_export_op = &gfs2_export_ops; 1134 sb->s_export_op = &gfs2_export_ops;
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)
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/**
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index f6b8b00ad881..91abdbedcc86 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -14,7 +14,7 @@
14#include <linux/dcache.h> 14#include <linux/dcache.h>
15#include "incore.h" 15#include "incore.h"
16 16
17void gfs2_lm_unmount(struct gfs2_sbd *sdp); 17extern void gfs2_lm_unmount(struct gfs2_sbd *sdp);
18 18
19static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) 19static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
20{ 20{
@@ -27,21 +27,23 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
27 27
28void gfs2_jindex_free(struct gfs2_sbd *sdp); 28void gfs2_jindex_free(struct gfs2_sbd *sdp);
29 29
30struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); 30extern int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *data);
31int gfs2_jdesc_check(struct gfs2_jdesc *jd);
32 31
33int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, 32extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid);
34 struct gfs2_inode **ipp); 33extern int gfs2_jdesc_check(struct gfs2_jdesc *jd);
35 34
36int gfs2_make_fs_rw(struct gfs2_sbd *sdp); 35extern int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename,
36 struct gfs2_inode **ipp);
37 37
38int gfs2_statfs_init(struct gfs2_sbd *sdp); 38extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp);
39void gfs2_statfs_change(struct gfs2_sbd *sdp,
40 s64 total, s64 free, s64 dinodes);
41int gfs2_statfs_sync(struct gfs2_sbd *sdp);
42 39
43int gfs2_freeze_fs(struct gfs2_sbd *sdp); 40extern int gfs2_statfs_init(struct gfs2_sbd *sdp);
44void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); 41extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
42 s64 dinodes);
43extern int gfs2_statfs_sync(struct gfs2_sbd *sdp);
44
45extern int gfs2_freeze_fs(struct gfs2_sbd *sdp);
46extern void gfs2_unfreeze_fs(struct gfs2_sbd *sdp);
45 47
46extern struct file_system_type gfs2_fs_type; 48extern struct file_system_type gfs2_fs_type;
47extern struct file_system_type gfs2meta_fs_type; 49extern struct file_system_type gfs2meta_fs_type;