aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/mount.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/mount.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/mount.c')
-rw-r--r--fs/gfs2/mount.c111
1 files changed, 19 insertions, 92 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