aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/mount.c')
-rw-r--r--fs/gfs2/mount.c239
1 files changed, 143 insertions, 96 deletions
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index 32caecd20300..4864659555d4 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -13,6 +13,7 @@
13#include <linux/buffer_head.h> 13#include <linux/buffer_head.h>
14#include <linux/gfs2_ondisk.h> 14#include <linux/gfs2_ondisk.h>
15#include <linux/lm_interface.h> 15#include <linux/lm_interface.h>
16#include <linux/parser.h>
16 17
17#include "gfs2.h" 18#include "gfs2.h"
18#include "incore.h" 19#include "incore.h"
@@ -20,6 +21,52 @@
20#include "sys.h" 21#include "sys.h"
21#include "util.h" 22#include "util.h"
22 23
24enum {
25 Opt_lockproto,
26 Opt_locktable,
27 Opt_hostdata,
28 Opt_spectator,
29 Opt_ignore_local_fs,
30 Opt_localflocks,
31 Opt_localcaching,
32 Opt_debug,
33 Opt_nodebug,
34 Opt_upgrade,
35 Opt_num_glockd,
36 Opt_acl,
37 Opt_noacl,
38 Opt_quota_off,
39 Opt_quota_account,
40 Opt_quota_on,
41 Opt_suiddir,
42 Opt_nosuiddir,
43 Opt_data_writeback,
44 Opt_data_ordered,
45};
46
47static match_table_t tokens = {
48 {Opt_lockproto, "lockproto=%s"},
49 {Opt_locktable, "locktable=%s"},
50 {Opt_hostdata, "hostdata=%s"},
51 {Opt_spectator, "spectator"},
52 {Opt_ignore_local_fs, "ignore_local_fs"},
53 {Opt_localflocks, "localflocks"},
54 {Opt_localcaching, "localcaching"},
55 {Opt_debug, "debug"},
56 {Opt_nodebug, "nodebug"},
57 {Opt_upgrade, "upgrade"},
58 {Opt_num_glockd, "num_glockd=%d"},
59 {Opt_acl, "acl"},
60 {Opt_noacl, "noacl"},
61 {Opt_quota_off, "quota=off"},
62 {Opt_quota_account, "quota=account"},
63 {Opt_quota_on, "quota=on"},
64 {Opt_suiddir, "suiddir"},
65 {Opt_nosuiddir, "nosuiddir"},
66 {Opt_data_writeback, "data=writeback"},
67 {Opt_data_ordered, "data=ordered"}
68};
69
23/** 70/**
24 * gfs2_mount_args - Parse mount options 71 * gfs2_mount_args - Parse mount options
25 * @sdp: 72 * @sdp:
@@ -54,146 +101,150 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
54 process them */ 101 process them */
55 102
56 for (options = data; (o = strsep(&options, ",")); ) { 103 for (options = data; (o = strsep(&options, ",")); ) {
104 int token, option;
105 substring_t tmp[MAX_OPT_ARGS];
106
57 if (!*o) 107 if (!*o)
58 continue; 108 continue;
59 109
60 v = strchr(o, '='); 110 token = match_token(o, tokens, tmp);
61 if (v) 111 switch (token) {
62 *v++ = 0; 112 case Opt_lockproto:
113 v = match_strdup(&tmp[0]);
114 if (!v) {
115 fs_info(sdp, "no memory for lockproto\n");
116 error = -ENOMEM;
117 goto out_error;
118 }
63 119
64 if (!strcmp(o, "lockproto")) { 120 if (remount && strcmp(v, args->ar_lockproto)) {
65 if (!v) 121 kfree(v);
66 goto need_value;
67 if (remount && strcmp(v, args->ar_lockproto))
68 goto cant_remount; 122 goto cant_remount;
123 }
124
69 strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN); 125 strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN);
70 args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0; 126 args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0;
71 } 127 kfree(v);
128 break;
129 case Opt_locktable:
130 v = match_strdup(&tmp[0]);
131 if (!v) {
132 fs_info(sdp, "no memory for locktable\n");
133 error = -ENOMEM;
134 goto out_error;
135 }
72 136
73 else if (!strcmp(o, "locktable")) { 137 if (remount && strcmp(v, args->ar_locktable)) {
74 if (!v) 138 kfree(v);
75 goto need_value;
76 if (remount && strcmp(v, args->ar_locktable))
77 goto cant_remount; 139 goto cant_remount;
140 }
141
78 strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN); 142 strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN);
79 args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0; 143 args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0;
80 } 144 kfree(v);
145 break;
146 case Opt_hostdata:
147 v = match_strdup(&tmp[0]);
148 if (!v) {
149 fs_info(sdp, "no memory for hostdata\n");
150 error = -ENOMEM;
151 goto out_error;
152 }
81 153
82 else if (!strcmp(o, "hostdata")) { 154 if (remount && strcmp(v, args->ar_hostdata)) {
83 if (!v) 155 kfree(v);
84 goto need_value;
85 if (remount && strcmp(v, args->ar_hostdata))
86 goto cant_remount; 156 goto cant_remount;
157 }
158
87 strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN); 159 strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN);
88 args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0; 160 args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0;
89 } 161 kfree(v);
90 162 break;
91 else if (!strcmp(o, "spectator")) { 163 case Opt_spectator:
92 if (remount && !args->ar_spectator) 164 if (remount && !args->ar_spectator)
93 goto cant_remount; 165 goto cant_remount;
94 args->ar_spectator = 1; 166 args->ar_spectator = 1;
95 sdp->sd_vfs->s_flags |= MS_RDONLY; 167 sdp->sd_vfs->s_flags |= MS_RDONLY;
96 } 168 break;
97 169 case Opt_ignore_local_fs:
98 else if (!strcmp(o, "ignore_local_fs")) {
99 if (remount && !args->ar_ignore_local_fs) 170 if (remount && !args->ar_ignore_local_fs)
100 goto cant_remount; 171 goto cant_remount;
101 args->ar_ignore_local_fs = 1; 172 args->ar_ignore_local_fs = 1;
102 } 173 break;
103 174 case Opt_localflocks:
104 else if (!strcmp(o, "localflocks")) {
105 if (remount && !args->ar_localflocks) 175 if (remount && !args->ar_localflocks)
106 goto cant_remount; 176 goto cant_remount;
107 args->ar_localflocks = 1; 177 args->ar_localflocks = 1;
108 } 178 break;
109 179 case Opt_localcaching:
110 else if (!strcmp(o, "localcaching")) {
111 if (remount && !args->ar_localcaching) 180 if (remount && !args->ar_localcaching)
112 goto cant_remount; 181 goto cant_remount;
113 args->ar_localcaching = 1; 182 args->ar_localcaching = 1;
114 } 183 break;
115 184 case Opt_debug:
116 else if (!strcmp(o, "debug"))
117 args->ar_debug = 1; 185 args->ar_debug = 1;
118 186 break;
119 else if (!strcmp(o, "nodebug")) 187 case Opt_nodebug:
120 args->ar_debug = 0; 188 args->ar_debug = 0;
121 189 break;
122 else if (!strcmp(o, "upgrade")) { 190 case Opt_upgrade:
123 if (remount && !args->ar_upgrade) 191 if (remount && !args->ar_upgrade)
124 goto cant_remount; 192 goto cant_remount;
125 args->ar_upgrade = 1; 193 args->ar_upgrade = 1;
126 } 194 break;
195 case Opt_num_glockd:
196 if ((error = match_int(&tmp[0], &option))) {
197 fs_info(sdp, "problem getting num_glockd\n");
198 goto out_error;
199 }
127 200
128 else if (!strcmp(o, "num_glockd")) { 201 if (remount && option != args->ar_num_glockd)
129 unsigned int x;
130 if (!v)
131 goto need_value;
132 sscanf(v, "%u", &x);
133 if (remount && x != args->ar_num_glockd)
134 goto cant_remount; 202 goto cant_remount;
135 if (!x || x > GFS2_GLOCKD_MAX) { 203 if (!option || option > GFS2_GLOCKD_MAX) {
136 fs_info(sdp, "0 < num_glockd <= %u (not %u)\n", 204 fs_info(sdp, "0 < num_glockd <= %u (not %u)\n",
137 GFS2_GLOCKD_MAX, x); 205 GFS2_GLOCKD_MAX, option);
138 error = -EINVAL; 206 error = -EINVAL;
139 break; 207 goto out_error;
140 } 208 }
141 args->ar_num_glockd = x; 209 args->ar_num_glockd = option;
142 } 210 break;
143 211 case Opt_acl:
144 else if (!strcmp(o, "acl")) {
145 args->ar_posix_acl = 1; 212 args->ar_posix_acl = 1;
146 sdp->sd_vfs->s_flags |= MS_POSIXACL; 213 sdp->sd_vfs->s_flags |= MS_POSIXACL;
147 } 214 break;
148 215 case Opt_noacl:
149 else if (!strcmp(o, "noacl")) {
150 args->ar_posix_acl = 0; 216 args->ar_posix_acl = 0;
151 sdp->sd_vfs->s_flags &= ~MS_POSIXACL; 217 sdp->sd_vfs->s_flags &= ~MS_POSIXACL;
152 } 218 break;
153 219 case Opt_quota_off:
154 else if (!strcmp(o, "quota")) { 220 args->ar_quota = GFS2_QUOTA_OFF;
155 if (!v) 221 break;
156 goto need_value; 222 case Opt_quota_account:
157 if (!strcmp(v, "off")) 223 args->ar_quota = GFS2_QUOTA_ACCOUNT;
158 args->ar_quota = GFS2_QUOTA_OFF; 224 break;
159 else if (!strcmp(v, "account")) 225 case Opt_quota_on:
160 args->ar_quota = GFS2_QUOTA_ACCOUNT; 226 args->ar_quota = GFS2_QUOTA_ON;
161 else if (!strcmp(v, "on")) 227 break;
162 args->ar_quota = GFS2_QUOTA_ON; 228 case Opt_suiddir:
163 else {
164 fs_info(sdp, "invalid value for quota\n");
165 error = -EINVAL;
166 break;
167 }
168 }
169
170 else if (!strcmp(o, "suiddir"))
171 args->ar_suiddir = 1; 229 args->ar_suiddir = 1;
172 230 break;
173 else if (!strcmp(o, "nosuiddir")) 231 case Opt_nosuiddir:
174 args->ar_suiddir = 0; 232 args->ar_suiddir = 0;
175 233 break;
176 else if (!strcmp(o, "data")) { 234 case Opt_data_writeback:
177 if (!v) 235 args->ar_data = GFS2_DATA_WRITEBACK;
178 goto need_value; 236 break;
179 if (!strcmp(v, "writeback")) 237 case Opt_data_ordered:
180 args->ar_data = GFS2_DATA_WRITEBACK; 238 args->ar_data = GFS2_DATA_ORDERED;
181 else if (!strcmp(v, "ordered")) 239 break;
182 args->ar_data = GFS2_DATA_ORDERED; 240 default:
183 else {
184 fs_info(sdp, "invalid value for data\n");
185 error = -EINVAL;
186 break;
187 }
188 }
189
190 else {
191 fs_info(sdp, "unknown option: %s\n", o); 241 fs_info(sdp, "unknown option: %s\n", o);
192 error = -EINVAL; 242 error = -EINVAL;
193 break; 243 goto out_error;
194 } 244 }
195 } 245 }
196 246
247out_error:
197 if (error) 248 if (error)
198 fs_info(sdp, "invalid mount option(s)\n"); 249 fs_info(sdp, "invalid mount option(s)\n");
199 250
@@ -202,10 +253,6 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
202 253
203 return error; 254 return error;
204 255
205need_value:
206 fs_info(sdp, "need value for option %s\n", o);
207 return -EINVAL;
208
209cant_remount: 256cant_remount:
210 fs_info(sdp, "can't remount with option %s\n", o); 257 fs_info(sdp, "can't remount with option %s\n", o);
211 return -EINVAL; 258 return -EINVAL;