aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-11-23 00:29:32 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-02-07 02:16:30 -0500
commita67d7c5f5d25d0b13a4dfb182697135b014fa478 (patch)
tree6afad71ef304075afd957ea227c584f0580558be /fs/xfs
parent3ed6526441053d79b85d206b14d75125e6f51cc2 (diff)
[XFS] Move platform specific mount option parse out of core XFS code
Mount option parsing is platform specific. Move it out of core code into the platform specific superblock operation file. SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:30012a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c430
-rw-r--r--fs/xfs/xfs_vfsops.c430
-rw-r--r--fs/xfs/xfs_vfsops.h3
3 files changed, 430 insertions, 433 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index c430b44dde4b..70024a24692d 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -50,6 +50,7 @@
50#include "xfs_vnodeops.h" 50#include "xfs_vnodeops.h"
51#include "xfs_vfsops.h" 51#include "xfs_vfsops.h"
52#include "xfs_version.h" 52#include "xfs_version.h"
53#include "xfs_log_priv.h"
53 54
54#include <linux/namei.h> 55#include <linux/namei.h>
55#include <linux/init.h> 56#include <linux/init.h>
@@ -88,6 +89,435 @@ xfs_args_allocate(
88 return args; 89 return args;
89} 90}
90 91
92#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
93#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
94#define MNTOPT_LOGDEV "logdev" /* log device */
95#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
96#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
97#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
98#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
99#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
100#define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */
101#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
102#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
103#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
104#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
105#define MNTOPT_GRPID "grpid" /* group-ID from parent directory */
106#define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */
107#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
108#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
109#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
110#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
111#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
112 * unwritten extent conversion */
113#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
114#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
115#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
116#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
117#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
118#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
119#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
120 * in stat(). */
121#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
122#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
123#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
124#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
125#define MNTOPT_NOQUOTA "noquota" /* no quotas */
126#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
127#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
128#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
129#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
130#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
131#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
132#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
133#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
134#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
135#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
136#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
137#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
138#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
139
140STATIC unsigned long
141suffix_strtoul(char *s, char **endp, unsigned int base)
142{
143 int last, shift_left_factor = 0;
144 char *value = s;
145
146 last = strlen(value) - 1;
147 if (value[last] == 'K' || value[last] == 'k') {
148 shift_left_factor = 10;
149 value[last] = '\0';
150 }
151 if (value[last] == 'M' || value[last] == 'm') {
152 shift_left_factor = 20;
153 value[last] = '\0';
154 }
155 if (value[last] == 'G' || value[last] == 'g') {
156 shift_left_factor = 30;
157 value[last] = '\0';
158 }
159
160 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
161}
162
163STATIC int
164xfs_parseargs(
165 struct xfs_mount *mp,
166 char *options,
167 struct xfs_mount_args *args,
168 int update)
169{
170 char *this_char, *value, *eov;
171 int dsunit, dswidth, vol_dsunit, vol_dswidth;
172 int iosize;
173 int ikeep = 0;
174
175 args->flags |= XFSMNT_BARRIER;
176 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
177
178 if (!options)
179 goto done;
180
181 iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
182
183 while ((this_char = strsep(&options, ",")) != NULL) {
184 if (!*this_char)
185 continue;
186 if ((value = strchr(this_char, '=')) != NULL)
187 *value++ = 0;
188
189 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
190 if (!value || !*value) {
191 cmn_err(CE_WARN,
192 "XFS: %s option requires an argument",
193 this_char);
194 return EINVAL;
195 }
196 args->logbufs = simple_strtoul(value, &eov, 10);
197 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
198 if (!value || !*value) {
199 cmn_err(CE_WARN,
200 "XFS: %s option requires an argument",
201 this_char);
202 return EINVAL;
203 }
204 args->logbufsize = suffix_strtoul(value, &eov, 10);
205 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
206 if (!value || !*value) {
207 cmn_err(CE_WARN,
208 "XFS: %s option requires an argument",
209 this_char);
210 return EINVAL;
211 }
212 strncpy(args->logname, value, MAXNAMELEN);
213 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
214 if (!value || !*value) {
215 cmn_err(CE_WARN,
216 "XFS: %s option requires an argument",
217 this_char);
218 return EINVAL;
219 }
220 strncpy(args->mtpt, value, MAXNAMELEN);
221 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
222 if (!value || !*value) {
223 cmn_err(CE_WARN,
224 "XFS: %s option requires an argument",
225 this_char);
226 return EINVAL;
227 }
228 strncpy(args->rtname, value, MAXNAMELEN);
229 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
230 if (!value || !*value) {
231 cmn_err(CE_WARN,
232 "XFS: %s option requires an argument",
233 this_char);
234 return EINVAL;
235 }
236 iosize = simple_strtoul(value, &eov, 10);
237 args->flags |= XFSMNT_IOSIZE;
238 args->iosizelog = (uint8_t) iosize;
239 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
240 if (!value || !*value) {
241 cmn_err(CE_WARN,
242 "XFS: %s option requires an argument",
243 this_char);
244 return EINVAL;
245 }
246 iosize = suffix_strtoul(value, &eov, 10);
247 args->flags |= XFSMNT_IOSIZE;
248 args->iosizelog = ffs(iosize) - 1;
249 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
250 !strcmp(this_char, MNTOPT_BSDGROUPS)) {
251 mp->m_flags |= XFS_MOUNT_GRPID;
252 } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
253 !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
254 mp->m_flags &= ~XFS_MOUNT_GRPID;
255 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
256 args->flags |= XFSMNT_WSYNC;
257 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
258 args->flags |= XFSMNT_OSYNCISOSYNC;
259 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
260 args->flags |= XFSMNT_NORECOVERY;
261 } else if (!strcmp(this_char, MNTOPT_INO64)) {
262 args->flags |= XFSMNT_INO64;
263#if !XFS_BIG_INUMS
264 cmn_err(CE_WARN,
265 "XFS: %s option not allowed on this system",
266 this_char);
267 return EINVAL;
268#endif
269 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
270 args->flags |= XFSMNT_NOALIGN;
271 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
272 args->flags |= XFSMNT_SWALLOC;
273 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
274 if (!value || !*value) {
275 cmn_err(CE_WARN,
276 "XFS: %s option requires an argument",
277 this_char);
278 return EINVAL;
279 }
280 dsunit = simple_strtoul(value, &eov, 10);
281 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
282 if (!value || !*value) {
283 cmn_err(CE_WARN,
284 "XFS: %s option requires an argument",
285 this_char);
286 return EINVAL;
287 }
288 dswidth = simple_strtoul(value, &eov, 10);
289 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
290 args->flags &= ~XFSMNT_32BITINODES;
291#if !XFS_BIG_INUMS
292 cmn_err(CE_WARN,
293 "XFS: %s option not allowed on this system",
294 this_char);
295 return EINVAL;
296#endif
297 } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
298 args->flags |= XFSMNT_NOUUID;
299 } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
300 args->flags |= XFSMNT_BARRIER;
301 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
302 args->flags &= ~XFSMNT_BARRIER;
303 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
304 ikeep = 1;
305 args->flags &= ~XFSMNT_IDELETE;
306 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
307 args->flags |= XFSMNT_IDELETE;
308 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
309 args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
310 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
311 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
312 } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
313 args->flags |= XFSMNT_ATTR2;
314 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
315 args->flags &= ~XFSMNT_ATTR2;
316 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
317 args->flags2 |= XFSMNT2_FILESTREAMS;
318 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
319 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
320 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
321 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
322 !strcmp(this_char, MNTOPT_UQUOTA) ||
323 !strcmp(this_char, MNTOPT_USRQUOTA)) {
324 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
325 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
326 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
327 args->flags |= XFSMNT_UQUOTA;
328 args->flags &= ~XFSMNT_UQUOTAENF;
329 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
330 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
331 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
332 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
333 args->flags |= XFSMNT_PQUOTA;
334 args->flags &= ~XFSMNT_PQUOTAENF;
335 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
336 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
337 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
338 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
339 args->flags |= XFSMNT_GQUOTA;
340 args->flags &= ~XFSMNT_GQUOTAENF;
341 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
342 args->flags |= XFSMNT_DMAPI;
343 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
344 args->flags |= XFSMNT_DMAPI;
345 } else if (!strcmp(this_char, MNTOPT_DMI)) {
346 args->flags |= XFSMNT_DMAPI;
347 } else if (!strcmp(this_char, "ihashsize")) {
348 cmn_err(CE_WARN,
349 "XFS: ihashsize no longer used, option is deprecated.");
350 } else if (!strcmp(this_char, "osyncisdsync")) {
351 /* no-op, this is now the default */
352 cmn_err(CE_WARN,
353 "XFS: osyncisdsync is now the default, option is deprecated.");
354 } else if (!strcmp(this_char, "irixsgid")) {
355 cmn_err(CE_WARN,
356 "XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
357 } else {
358 cmn_err(CE_WARN,
359 "XFS: unknown mount option [%s].", this_char);
360 return EINVAL;
361 }
362 }
363
364 if (args->flags & XFSMNT_NORECOVERY) {
365 if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {
366 cmn_err(CE_WARN,
367 "XFS: no-recovery mounts must be read-only.");
368 return EINVAL;
369 }
370 }
371
372 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
373 cmn_err(CE_WARN,
374 "XFS: sunit and swidth options incompatible with the noalign option");
375 return EINVAL;
376 }
377
378 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
379 cmn_err(CE_WARN,
380 "XFS: cannot mount with both project and group quota");
381 return EINVAL;
382 }
383
384 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
385 printk("XFS: %s option needs the mount point option as well\n",
386 MNTOPT_DMAPI);
387 return EINVAL;
388 }
389
390 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
391 cmn_err(CE_WARN,
392 "XFS: sunit and swidth must be specified together");
393 return EINVAL;
394 }
395
396 if (dsunit && (dswidth % dsunit != 0)) {
397 cmn_err(CE_WARN,
398 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
399 dswidth, dsunit);
400 return EINVAL;
401 }
402
403 /*
404 * Applications using DMI filesystems often expect the
405 * inode generation number to be monotonically increasing.
406 * If we delete inode chunks we break this assumption, so
407 * keep unused inode chunks on disk for DMI filesystems
408 * until we come up with a better solution.
409 * Note that if "ikeep" or "noikeep" mount options are
410 * supplied, then they are honored.
411 */
412 if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
413 args->flags |= XFSMNT_IDELETE;
414
415 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
416 if (dsunit) {
417 args->sunit = dsunit;
418 args->flags |= XFSMNT_RETERR;
419 } else {
420 args->sunit = vol_dsunit;
421 }
422 dswidth ? (args->swidth = dswidth) :
423 (args->swidth = vol_dswidth);
424 } else {
425 args->sunit = args->swidth = 0;
426 }
427
428done:
429 if (args->flags & XFSMNT_32BITINODES)
430 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
431 if (args->flags2)
432 args->flags |= XFSMNT_FLAGS2;
433 return 0;
434}
435
436struct proc_xfs_info {
437 int flag;
438 char *str;
439};
440
441STATIC int
442xfs_showargs(
443 struct xfs_mount *mp,
444 struct seq_file *m)
445{
446 static struct proc_xfs_info xfs_info_set[] = {
447 /* the few simple ones we can get from the mount struct */
448 { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
449 { XFS_MOUNT_INO64, "," MNTOPT_INO64 },
450 { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
451 { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC },
452 { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
453 { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
454 { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
455 { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 },
456 { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
457 { XFS_MOUNT_DMAPI, "," MNTOPT_DMAPI },
458 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
459 { 0, NULL }
460 };
461 static struct proc_xfs_info xfs_info_unset[] = {
462 /* the few simple ones we can get from the mount struct */
463 { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP },
464 { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO },
465 { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER },
466 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE },
467 { 0, NULL }
468 };
469 struct proc_xfs_info *xfs_infop;
470
471 for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) {
472 if (mp->m_flags & xfs_infop->flag)
473 seq_puts(m, xfs_infop->str);
474 }
475 for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) {
476 if (!(mp->m_flags & xfs_infop->flag))
477 seq_puts(m, xfs_infop->str);
478 }
479
480 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
481 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
482 (int)(1 << mp->m_writeio_log) >> 10);
483
484 if (mp->m_logbufs > 0)
485 seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
486 if (mp->m_logbsize > 0)
487 seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
488
489 if (mp->m_logname)
490 seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
491 if (mp->m_rtname)
492 seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
493
494 if (mp->m_dalign > 0)
495 seq_printf(m, "," MNTOPT_SUNIT "=%d",
496 (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
497 if (mp->m_swidth > 0)
498 seq_printf(m, "," MNTOPT_SWIDTH "=%d",
499 (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
500
501 if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
502 seq_puts(m, "," MNTOPT_USRQUOTA);
503 else if (mp->m_qflags & XFS_UQUOTA_ACCT)
504 seq_puts(m, "," MNTOPT_UQUOTANOENF);
505
506 if (mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
507 seq_puts(m, "," MNTOPT_PRJQUOTA);
508 else if (mp->m_qflags & XFS_PQUOTA_ACCT)
509 seq_puts(m, "," MNTOPT_PQUOTANOENF);
510
511 if (mp->m_qflags & (XFS_GQUOTA_ACCT|XFS_OQUOTA_ENFD))
512 seq_puts(m, "," MNTOPT_GRPQUOTA);
513 else if (mp->m_qflags & XFS_GQUOTA_ACCT)
514 seq_puts(m, "," MNTOPT_GQUOTANOENF);
515
516 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
517 seq_puts(m, "," MNTOPT_NOQUOTA);
518
519 return 0;
520}
91__uint64_t 521__uint64_t
92xfs_max_file_offset( 522xfs_max_file_offset(
93 unsigned int blockshift) 523 unsigned int blockshift)
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index aa310875c88c..b8e16a6952be 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1461,433 +1461,3 @@ xfs_vget(
1461 return 0; 1461 return 0;
1462} 1462}
1463 1463
1464
1465#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
1466#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
1467#define MNTOPT_LOGDEV "logdev" /* log device */
1468#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
1469#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
1470#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
1471#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
1472#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
1473#define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */
1474#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
1475#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
1476#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
1477#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
1478#define MNTOPT_GRPID "grpid" /* group-ID from parent directory */
1479#define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */
1480#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
1481#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
1482#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
1483#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
1484#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
1485 * unwritten extent conversion */
1486#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
1487#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
1488#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
1489#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
1490#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
1491#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
1492#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
1493 * in stat(). */
1494#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
1495#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1496#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
1497#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
1498#define MNTOPT_NOQUOTA "noquota" /* no quotas */
1499#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
1500#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
1501#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
1502#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
1503#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
1504#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
1505#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
1506#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
1507#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
1508#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
1509#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
1510#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
1511#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
1512
1513STATIC unsigned long
1514suffix_strtoul(char *s, char **endp, unsigned int base)
1515{
1516 int last, shift_left_factor = 0;
1517 char *value = s;
1518
1519 last = strlen(value) - 1;
1520 if (value[last] == 'K' || value[last] == 'k') {
1521 shift_left_factor = 10;
1522 value[last] = '\0';
1523 }
1524 if (value[last] == 'M' || value[last] == 'm') {
1525 shift_left_factor = 20;
1526 value[last] = '\0';
1527 }
1528 if (value[last] == 'G' || value[last] == 'g') {
1529 shift_left_factor = 30;
1530 value[last] = '\0';
1531 }
1532
1533 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1534}
1535
1536int
1537xfs_parseargs(
1538 struct xfs_mount *mp,
1539 char *options,
1540 struct xfs_mount_args *args,
1541 int update)
1542{
1543 char *this_char, *value, *eov;
1544 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1545 int iosize;
1546 int ikeep = 0;
1547
1548 args->flags |= XFSMNT_BARRIER;
1549 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1550
1551 if (!options)
1552 goto done;
1553
1554 iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
1555
1556 while ((this_char = strsep(&options, ",")) != NULL) {
1557 if (!*this_char)
1558 continue;
1559 if ((value = strchr(this_char, '=')) != NULL)
1560 *value++ = 0;
1561
1562 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1563 if (!value || !*value) {
1564 cmn_err(CE_WARN,
1565 "XFS: %s option requires an argument",
1566 this_char);
1567 return EINVAL;
1568 }
1569 args->logbufs = simple_strtoul(value, &eov, 10);
1570 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1571 if (!value || !*value) {
1572 cmn_err(CE_WARN,
1573 "XFS: %s option requires an argument",
1574 this_char);
1575 return EINVAL;
1576 }
1577 args->logbufsize = suffix_strtoul(value, &eov, 10);
1578 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1579 if (!value || !*value) {
1580 cmn_err(CE_WARN,
1581 "XFS: %s option requires an argument",
1582 this_char);
1583 return EINVAL;
1584 }
1585 strncpy(args->logname, value, MAXNAMELEN);
1586 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1587 if (!value || !*value) {
1588 cmn_err(CE_WARN,
1589 "XFS: %s option requires an argument",
1590 this_char);
1591 return EINVAL;
1592 }
1593 strncpy(args->mtpt, value, MAXNAMELEN);
1594 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1595 if (!value || !*value) {
1596 cmn_err(CE_WARN,
1597 "XFS: %s option requires an argument",
1598 this_char);
1599 return EINVAL;
1600 }
1601 strncpy(args->rtname, value, MAXNAMELEN);
1602 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1603 if (!value || !*value) {
1604 cmn_err(CE_WARN,
1605 "XFS: %s option requires an argument",
1606 this_char);
1607 return EINVAL;
1608 }
1609 iosize = simple_strtoul(value, &eov, 10);
1610 args->flags |= XFSMNT_IOSIZE;
1611 args->iosizelog = (uint8_t) iosize;
1612 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1613 if (!value || !*value) {
1614 cmn_err(CE_WARN,
1615 "XFS: %s option requires an argument",
1616 this_char);
1617 return EINVAL;
1618 }
1619 iosize = suffix_strtoul(value, &eov, 10);
1620 args->flags |= XFSMNT_IOSIZE;
1621 args->iosizelog = ffs(iosize) - 1;
1622 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
1623 !strcmp(this_char, MNTOPT_BSDGROUPS)) {
1624 mp->m_flags |= XFS_MOUNT_GRPID;
1625 } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
1626 !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
1627 mp->m_flags &= ~XFS_MOUNT_GRPID;
1628 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
1629 args->flags |= XFSMNT_WSYNC;
1630 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
1631 args->flags |= XFSMNT_OSYNCISOSYNC;
1632 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
1633 args->flags |= XFSMNT_NORECOVERY;
1634 } else if (!strcmp(this_char, MNTOPT_INO64)) {
1635 args->flags |= XFSMNT_INO64;
1636#if !XFS_BIG_INUMS
1637 cmn_err(CE_WARN,
1638 "XFS: %s option not allowed on this system",
1639 this_char);
1640 return EINVAL;
1641#endif
1642 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
1643 args->flags |= XFSMNT_NOALIGN;
1644 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
1645 args->flags |= XFSMNT_SWALLOC;
1646 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1647 if (!value || !*value) {
1648 cmn_err(CE_WARN,
1649 "XFS: %s option requires an argument",
1650 this_char);
1651 return EINVAL;
1652 }
1653 dsunit = simple_strtoul(value, &eov, 10);
1654 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1655 if (!value || !*value) {
1656 cmn_err(CE_WARN,
1657 "XFS: %s option requires an argument",
1658 this_char);
1659 return EINVAL;
1660 }
1661 dswidth = simple_strtoul(value, &eov, 10);
1662 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
1663 args->flags &= ~XFSMNT_32BITINODES;
1664#if !XFS_BIG_INUMS
1665 cmn_err(CE_WARN,
1666 "XFS: %s option not allowed on this system",
1667 this_char);
1668 return EINVAL;
1669#endif
1670 } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
1671 args->flags |= XFSMNT_NOUUID;
1672 } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
1673 args->flags |= XFSMNT_BARRIER;
1674 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
1675 args->flags &= ~XFSMNT_BARRIER;
1676 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
1677 ikeep = 1;
1678 args->flags &= ~XFSMNT_IDELETE;
1679 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
1680 args->flags |= XFSMNT_IDELETE;
1681 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
1682 args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
1683 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
1684 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1685 } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
1686 args->flags |= XFSMNT_ATTR2;
1687 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
1688 args->flags &= ~XFSMNT_ATTR2;
1689 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
1690 args->flags2 |= XFSMNT2_FILESTREAMS;
1691 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
1692 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
1693 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
1694 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
1695 !strcmp(this_char, MNTOPT_UQUOTA) ||
1696 !strcmp(this_char, MNTOPT_USRQUOTA)) {
1697 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
1698 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
1699 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
1700 args->flags |= XFSMNT_UQUOTA;
1701 args->flags &= ~XFSMNT_UQUOTAENF;
1702 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
1703 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
1704 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
1705 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
1706 args->flags |= XFSMNT_PQUOTA;
1707 args->flags &= ~XFSMNT_PQUOTAENF;
1708 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
1709 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
1710 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
1711 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
1712 args->flags |= XFSMNT_GQUOTA;
1713 args->flags &= ~XFSMNT_GQUOTAENF;
1714 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
1715 args->flags |= XFSMNT_DMAPI;
1716 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
1717 args->flags |= XFSMNT_DMAPI;
1718 } else if (!strcmp(this_char, MNTOPT_DMI)) {
1719 args->flags |= XFSMNT_DMAPI;
1720 } else if (!strcmp(this_char, "ihashsize")) {
1721 cmn_err(CE_WARN,
1722 "XFS: ihashsize no longer used, option is deprecated.");
1723 } else if (!strcmp(this_char, "osyncisdsync")) {
1724 /* no-op, this is now the default */
1725 cmn_err(CE_WARN,
1726 "XFS: osyncisdsync is now the default, option is deprecated.");
1727 } else if (!strcmp(this_char, "irixsgid")) {
1728 cmn_err(CE_WARN,
1729 "XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
1730 } else {
1731 cmn_err(CE_WARN,
1732 "XFS: unknown mount option [%s].", this_char);
1733 return EINVAL;
1734 }
1735 }
1736
1737 if (args->flags & XFSMNT_NORECOVERY) {
1738 if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {
1739 cmn_err(CE_WARN,
1740 "XFS: no-recovery mounts must be read-only.");
1741 return EINVAL;
1742 }
1743 }
1744
1745 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
1746 cmn_err(CE_WARN,
1747 "XFS: sunit and swidth options incompatible with the noalign option");
1748 return EINVAL;
1749 }
1750
1751 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
1752 cmn_err(CE_WARN,
1753 "XFS: cannot mount with both project and group quota");
1754 return EINVAL;
1755 }
1756
1757 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
1758 printk("XFS: %s option needs the mount point option as well\n",
1759 MNTOPT_DMAPI);
1760 return EINVAL;
1761 }
1762
1763 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1764 cmn_err(CE_WARN,
1765 "XFS: sunit and swidth must be specified together");
1766 return EINVAL;
1767 }
1768
1769 if (dsunit && (dswidth % dsunit != 0)) {
1770 cmn_err(CE_WARN,
1771 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
1772 dswidth, dsunit);
1773 return EINVAL;
1774 }
1775
1776 /*
1777 * Applications using DMI filesystems often expect the
1778 * inode generation number to be monotonically increasing.
1779 * If we delete inode chunks we break this assumption, so
1780 * keep unused inode chunks on disk for DMI filesystems
1781 * until we come up with a better solution.
1782 * Note that if "ikeep" or "noikeep" mount options are
1783 * supplied, then they are honored.
1784 */
1785 if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
1786 args->flags |= XFSMNT_IDELETE;
1787
1788 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
1789 if (dsunit) {
1790 args->sunit = dsunit;
1791 args->flags |= XFSMNT_RETERR;
1792 } else {
1793 args->sunit = vol_dsunit;
1794 }
1795 dswidth ? (args->swidth = dswidth) :
1796 (args->swidth = vol_dswidth);
1797 } else {
1798 args->sunit = args->swidth = 0;
1799 }
1800
1801done:
1802 if (args->flags & XFSMNT_32BITINODES)
1803 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
1804 if (args->flags2)
1805 args->flags |= XFSMNT_FLAGS2;
1806 return 0;
1807}
1808
1809struct proc_xfs_info {
1810 int flag;
1811 char *str;
1812};
1813
1814int
1815xfs_showargs(
1816 struct xfs_mount *mp,
1817 struct seq_file *m)
1818{
1819 static struct proc_xfs_info xfs_info_set[] = {
1820 /* the few simple ones we can get from the mount struct */
1821 { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
1822 { XFS_MOUNT_INO64, "," MNTOPT_INO64 },
1823 { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
1824 { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC },
1825 { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
1826 { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
1827 { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
1828 { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 },
1829 { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
1830 { XFS_MOUNT_DMAPI, "," MNTOPT_DMAPI },
1831 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
1832 { 0, NULL }
1833 };
1834 static struct proc_xfs_info xfs_info_unset[] = {
1835 /* the few simple ones we can get from the mount struct */
1836 { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP },
1837 { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO },
1838 { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER },
1839 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE },
1840 { 0, NULL }
1841 };
1842 struct proc_xfs_info *xfs_infop;
1843
1844 for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) {
1845 if (mp->m_flags & xfs_infop->flag)
1846 seq_puts(m, xfs_infop->str);
1847 }
1848 for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) {
1849 if (!(mp->m_flags & xfs_infop->flag))
1850 seq_puts(m, xfs_infop->str);
1851 }
1852
1853 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
1854 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
1855 (int)(1 << mp->m_writeio_log) >> 10);
1856
1857 if (mp->m_logbufs > 0)
1858 seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
1859 if (mp->m_logbsize > 0)
1860 seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
1861
1862 if (mp->m_logname)
1863 seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
1864 if (mp->m_rtname)
1865 seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
1866
1867 if (mp->m_dalign > 0)
1868 seq_printf(m, "," MNTOPT_SUNIT "=%d",
1869 (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
1870 if (mp->m_swidth > 0)
1871 seq_printf(m, "," MNTOPT_SWIDTH "=%d",
1872 (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
1873
1874 if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
1875 seq_puts(m, "," MNTOPT_USRQUOTA);
1876 else if (mp->m_qflags & XFS_UQUOTA_ACCT)
1877 seq_puts(m, "," MNTOPT_UQUOTANOENF);
1878
1879 if (mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
1880 seq_puts(m, "," MNTOPT_PRJQUOTA);
1881 else if (mp->m_qflags & XFS_PQUOTA_ACCT)
1882 seq_puts(m, "," MNTOPT_PQUOTANOENF);
1883
1884 if (mp->m_qflags & (XFS_GQUOTA_ACCT|XFS_OQUOTA_ENFD))
1885 seq_puts(m, "," MNTOPT_GRPQUOTA);
1886 else if (mp->m_qflags & XFS_GQUOTA_ACCT)
1887 seq_puts(m, "," MNTOPT_GQUOTANOENF);
1888
1889 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
1890 seq_puts(m, "," MNTOPT_NOQUOTA);
1891
1892 return 0;
1893}
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h
index 38ed10397e07..bf1c083513dd 100644
--- a/fs/xfs/xfs_vfsops.h
+++ b/fs/xfs/xfs_vfsops.h
@@ -16,9 +16,6 @@ int xfs_mntupdate(struct xfs_mount *mp, int *flags,
16int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp); 16int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp);
17int xfs_sync(struct xfs_mount *mp, int flags); 17int xfs_sync(struct xfs_mount *mp, int flags);
18int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid); 18int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid);
19int xfs_parseargs(struct xfs_mount *mp, char *options,
20 struct xfs_mount_args *args, int update);
21int xfs_showargs(struct xfs_mount *mp, struct seq_file *m);
22void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, 19void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
23 int lnnum); 20 int lnnum);
24void xfs_attr_quiesce(struct xfs_mount *mp); 21void xfs_attr_quiesce(struct xfs_mount *mp);