/*
* XFS filesystem operations.
*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
strcpy(mp->m_fsname, ap->fsname);
- /*
- * Pull in the 'wsync' and 'ino64' mount options before we do the real
- * work of mounting and recovery. The arg pointer will
- * be NULL when we are being called from the root mount code.
- */
if (ap->flags & XFSMNT_WSYNC)
mp->m_flags |= XFS_MOUNT_WSYNC;
#if XFS_BIG_INUMS
mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
}
+
+ if (ap->flags & XFSMNT_IHASHSIZE)
+ mp->m_flags |= XFS_MOUNT_IHASHSIZE;
+
if (ap->flags & XFSMNT_IDELETE)
mp->m_flags |= XFS_MOUNT_IDELETE;
+ if (ap->flags & XFSMNT_DIRSYNC)
+ mp->m_flags |= XFS_MOUNT_DIRSYNC;
+
/*
* no recovery flag requires a read-only mount
*/
#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
+#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
#define MNTOPT_TAGXID "tagxid" /* context xid tagging for inodes */
+STATIC unsigned long
+suffix_strtoul(const char *cp, char **endp, unsigned int base)
+{
+ int last, shift_left_factor = 0;
+ char *value = (char *)cp;
+
+ last = strlen(value) - 1;
+ if (value[last] == 'K' || value[last] == 'k') {
+ shift_left_factor = 10;
+ value[last] = '\0';
+ }
+ if (value[last] == 'M' || value[last] == 'm') {
+ shift_left_factor = 20;
+ value[last] = '\0';
+ }
+ if (value[last] == 'G' || value[last] == 'g') {
+ shift_left_factor = 30;
+ value[last] = '\0';
+ }
+
+ return simple_strtoul(cp, endp, base) << shift_left_factor;
+}
int
xfs_parseargs(
if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGBUFS);
+ this_char);
return EINVAL;
}
args->logbufs = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
- int last, in_kilobytes = 0;
-
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGBSIZE);
+ this_char);
return EINVAL;
}
- last = strlen(value) - 1;
- if (value[last] == 'K' || value[last] == 'k') {
- in_kilobytes = 1;
- value[last] = '\0';
- }
- args->logbufsize = simple_strtoul(value, &eov, 10);
- if (in_kilobytes)
- args->logbufsize <<= 10;
+ args->logbufsize = suffix_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGDEV);
+ this_char);
return EINVAL;
}
strncpy(args->logname, value, MAXNAMELEN);
} else if (!strcmp(this_char, MNTOPT_MTPT)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_MTPT);
+ this_char);
return EINVAL;
}
strncpy(args->mtpt, value, MAXNAMELEN);
} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_RTDEV);
+ this_char);
return EINVAL;
}
strncpy(args->rtname, value, MAXNAMELEN);
} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_BIOSIZE);
+ this_char);
return EINVAL;
}
iosize = simple_strtoul(value, &eov, 10);
args->flags |= XFSMNT_IOSIZE;
args->iosizelog = (uint8_t) iosize;
+ } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
+ if (!value || !*value) {
+ printk("XFS: %s option requires an argument\n",
+ this_char);
+ return EINVAL;
+ }
+ iosize = suffix_strtoul(value, &eov, 10);
+ args->flags |= XFSMNT_IOSIZE;
+ args->iosizelog = ffs(iosize) - 1;
} else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- this_char);
+ this_char);
return EINVAL;
}
+ args->flags |= XFSMNT_IHASHSIZE;
args->ihashsize = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
args->flags |= XFSMNT_WSYNC;
args->flags |= XFSMNT_INO64;
#if !XFS_BIG_INUMS
printk("XFS: %s option not allowed on this system\n",
- MNTOPT_INO64);
+ this_char);
return EINVAL;
#endif
} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_SUNIT);
+ this_char);
return EINVAL;
}
dsunit = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
- MNTOPT_SWIDTH);
+ this_char);
return EINVAL;
}
dswidth = simple_strtoul(value, &eov, 10);
args->flags &= ~XFSMNT_32BITINODES;
#if !XFS_BIG_INUMS
printk("XFS: %s option not allowed on this system\n",
- MNTOPT_64BITINODE);
+ this_char);
return EINVAL;
#endif
} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
seq_puts(m, xfs_infop->str);
}
+ if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
+ seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
+
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
- seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
+ seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log);
if (mp->m_logbufs > 0)
seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);