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.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
new file mode 100644
index 000000000000..3e42697aafc7
--- /dev/null
+++ b/fs/gfs2/mount.c
@@ -0,0 +1,211 @@
1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 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 v.2.
8 */
9
10#include <linux/sched.h>
11#include <linux/slab.h>
12#include <linux/spinlock.h>
13#include <linux/completion.h>
14#include <linux/buffer_head.h>
15#include <asm/semaphore.h>
16
17#include "gfs2.h"
18#include "mount.h"
19#include "sys.h"
20
21/**
22 * gfs2_mount_args - Parse mount options
23 * @sdp:
24 * @data:
25 *
26 * Return: errno
27 */
28
29int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
30{
31 struct gfs2_args *args = &sdp->sd_args;
32 char *data = data_arg;
33 char *options, *o, *v;
34 int error = 0;
35
36 if (!remount) {
37 /* If someone preloaded options, use those instead */
38 spin_lock(&gfs2_sys_margs_lock);
39 if (gfs2_sys_margs) {
40 data = gfs2_sys_margs;
41 gfs2_sys_margs = NULL;
42 }
43 spin_unlock(&gfs2_sys_margs_lock);
44
45 /* Set some defaults */
46 args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
47 args->ar_quota = GFS2_QUOTA_DEFAULT;
48 args->ar_data = GFS2_DATA_DEFAULT;
49 }
50
51 /* Split the options into tokens with the "," character and
52 process them */
53
54 for (options = data; (o = strsep(&options, ",")); ) {
55 if (!*o)
56 continue;
57
58 v = strchr(o, '=');
59 if (v)
60 *v++ = 0;
61
62 if (!strcmp(o, "lockproto")) {
63 if (!v)
64 goto need_value;
65 if (remount && strcmp(v, args->ar_lockproto))
66 goto cant_remount;
67 strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN);
68 args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0;
69 }
70
71 else if (!strcmp(o, "locktable")) {
72 if (!v)
73 goto need_value;
74 if (remount && strcmp(v, args->ar_locktable))
75 goto cant_remount;
76 strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN);
77 args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0;
78 }
79
80 else if (!strcmp(o, "hostdata")) {
81 if (!v)
82 goto need_value;
83 if (remount && strcmp(v, args->ar_hostdata))
84 goto cant_remount;
85 strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN);
86 args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0;
87 }
88
89 else if (!strcmp(o, "spectator")) {
90 if (remount && !args->ar_spectator)
91 goto cant_remount;
92 args->ar_spectator = 1;
93 sdp->sd_vfs->s_flags |= MS_RDONLY;
94 }
95
96 else if (!strcmp(o, "ignore_local_fs")) {
97 if (remount && !args->ar_ignore_local_fs)
98 goto cant_remount;
99 args->ar_ignore_local_fs = 1;
100 }
101
102 else if (!strcmp(o, "localflocks")) {
103 if (remount && !args->ar_localflocks)
104 goto cant_remount;
105 args->ar_localflocks = 1;
106 }
107
108 else if (!strcmp(o, "localcaching")) {
109 if (remount && !args->ar_localcaching)
110 goto cant_remount;
111 args->ar_localcaching = 1;
112 }
113
114 else if (!strcmp(o, "debug"))
115 args->ar_debug = 1;
116
117 else if (!strcmp(o, "nodebug"))
118 args->ar_debug = 0;
119
120 else if (!strcmp(o, "upgrade")) {
121 if (remount && !args->ar_upgrade)
122 goto cant_remount;
123 args->ar_upgrade = 1;
124 }
125
126 else if (!strcmp(o, "num_glockd")) {
127 unsigned int x;
128 if (!v)
129 goto need_value;
130 sscanf(v, "%u", &x);
131 if (remount && x != args->ar_num_glockd)
132 goto cant_remount;
133 if (!x || x > GFS2_GLOCKD_MAX) {
134 fs_info(sdp, "0 < num_glockd <= %u (not %u)\n",
135 GFS2_GLOCKD_MAX, x);
136 error = -EINVAL;
137 break;
138 }
139 args->ar_num_glockd = x;
140 }
141
142 else if (!strcmp(o, "acl")) {
143 args->ar_posix_acl = 1;
144 sdp->sd_vfs->s_flags |= MS_POSIXACL;
145 }
146
147 else if (!strcmp(o, "noacl")) {
148 args->ar_posix_acl = 0;
149 sdp->sd_vfs->s_flags &= ~MS_POSIXACL;
150 }
151
152 else if (!strcmp(o, "quota")) {
153 if (!v)
154 goto need_value;
155 if (!strcmp(v, "off"))
156 args->ar_quota = GFS2_QUOTA_OFF;
157 else if (!strcmp(v, "account"))
158 args->ar_quota = GFS2_QUOTA_ACCOUNT;
159 else if (!strcmp(v, "on"))
160 args->ar_quota = GFS2_QUOTA_ON;
161 else {
162 fs_info(sdp, "invalid value for quota\n");
163 error = -EINVAL;
164 break;
165 }
166 }
167
168 else if (!strcmp(o, "suiddir"))
169 args->ar_suiddir = 1;
170
171 else if (!strcmp(o, "nosuiddir"))
172 args->ar_suiddir = 0;
173
174 else if (!strcmp(o, "data")) {
175 if (!v)
176 goto need_value;
177 if (!strcmp(v, "writeback"))
178 args->ar_data = GFS2_DATA_WRITEBACK;
179 else if (!strcmp(v, "ordered"))
180 args->ar_data = GFS2_DATA_ORDERED;
181 else {
182 fs_info(sdp, "invalid value for data\n");
183 error = -EINVAL;
184 break;
185 }
186 }
187
188 else {
189 fs_info(sdp, "unknown option: %s\n", o);
190 error = -EINVAL;
191 break;
192 }
193 }
194
195 if (error)
196 fs_info(sdp, "invalid mount option(s)\n");
197
198 if (data != data_arg)
199 kfree(data);
200
201 return error;
202
203 need_value:
204 fs_info(sdp, "need value for option %s\n", o);
205 return -EINVAL;
206
207 cant_remount:
208 fs_info(sdp, "can't remount with option %s\n", o);
209 return -EINVAL;
210}
211