aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_super.c
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/linux-2.6/xfs_super.c
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/linux-2.6/xfs_super.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c430
1 files changed, 430 insertions, 0 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)