summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux/xfs_lrw.c27
-rw-r--r--fs/xfs/linux/xfs_lrw.h2
-rw-r--r--fs/xfs/linux/xfs_super.c251
-rw-r--r--fs/xfs/linux/xfs_super.h2
-rw-r--r--fs/xfs/linux/xfs_vfs.c15
-rw-r--r--fs/xfs/linux/xfs_vfs.h8
-rw-r--r--fs/xfs/xfs_vfsops.c275
7 files changed, 297 insertions, 283 deletions
diff --git a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
index cab83b4049b3..ccd7cbd3283b 100644
--- a/fs/xfs/linux/xfs_lrw.c
+++ b/fs/xfs/linux/xfs_lrw.c
@@ -857,33 +857,6 @@ XFS_bflush(xfs_buftarg_t *target)
pagebuf_delwri_flush(target, PBDF_WAIT, NULL);
}
-
-/* Push all fs state out to disk
- */
-
-void
-XFS_log_write_unmount_ro(bhv_desc_t *bdp)
-{
- xfs_mount_t *mp;
- int pincount = 0;
- int count = 0;
- int error;
-
- mp = XFS_BHVTOM(bdp);
- pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount);
- xfs_finish_reclaim_all(mp);
-
- do {
- VFS_SYNC(XFS_MTOVFS(mp), SYNC_ATTR|SYNC_WAIT, NULL, error);
- pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount);
- if (pincount == 0) {delay(50); count++;}
- } while (count < 2);
-
- /* Ok now write out an unmount record */
- xfs_log_unmount_write(mp);
- xfs_unmountfs_writesb(mp);
-}
-
/*
* If the underlying (log or data) device is readonly, there are some
* operations that cannot proceed.
diff --git a/fs/xfs/linux/xfs_lrw.h b/fs/xfs/linux/xfs_lrw.h
index feb917ab1771..b85c45520fd9 100644
--- a/fs/xfs/linux/xfs_lrw.h
+++ b/fs/xfs/linux/xfs_lrw.h
@@ -76,8 +76,6 @@ extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-extern void XFS_log_write_unmount_ro(struct bhv_desc *);
-
#define XFS_FSB_TO_DB_IO(io,fsb) \
(((io)->io_flags & XFS_IOCORE_RT) ? \
XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index d3da2cf7821c..7b3da4c76f02 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -42,22 +42,6 @@ STATIC struct super_operations linvfs_sops;
STATIC struct export_operations linvfs_export_ops;
STATIC kmem_cache_t * linvfs_inode_cachep;
-#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
-#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
-#define MNTOPT_LOGDEV "logdev" /* log device */
-#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
-#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
-#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
-#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
-#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
-#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
-#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
-#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
-#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
-#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
-#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
-#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
-
STATIC struct xfs_mount_args *
args_allocate(
struct super_block *sb)
@@ -78,221 +62,6 @@ args_allocate(
return args;
}
-int
-xfs_parseargs(
- struct bhv_desc *bhv,
- char *options,
- struct xfs_mount_args *args,
- int update)
-{
- struct vfs *vfsp = bhvtovfs(bhv);
- char *this_char, *value, *eov;
- int dsunit, dswidth, vol_dsunit, vol_dswidth;
- int iosize;
-
- if (!options)
- return 0;
-
- iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
-
- while ((this_char = strsep(&options, ",")) != NULL) {
- if (!*this_char)
- continue;
- if ((value = strchr(this_char, '=')) != NULL)
- *value++ = 0;
-
- if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
- if (!value || !*value) {
- printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGBUFS);
- 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);
- 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;
- } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
- if (!value || !*value) {
- printk("XFS: %s option requires an argument\n",
- MNTOPT_LOGDEV);
- 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);
- 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);
- 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);
- return -EINVAL;
- }
- iosize = simple_strtoul(value, &eov, 10);
- args->flags |= XFSMNT_IOSIZE;
- args->iosizelog = (uint8_t) iosize;
- } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
- args->flags |= XFSMNT_WSYNC;
- } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
- args->flags |= XFSMNT_OSYNCISOSYNC;
- } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
- args->flags |= XFSMNT_NORECOVERY;
- } else if (!strcmp(this_char, MNTOPT_INO64)) {
- args->flags |= XFSMNT_INO64;
-#ifndef XFS_BIG_FILESYSTEMS
- printk("XFS: %s option not allowed on this system\n",
- MNTOPT_INO64);
- return -EINVAL;
-#endif
- } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
- args->flags |= XFSMNT_NOALIGN;
- } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
- if (!value || !*value) {
- printk("XFS: %s option requires an argument\n",
- MNTOPT_SUNIT);
- 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);
- return -EINVAL;
- }
- dswidth = simple_strtoul(value, &eov, 10);
- } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
- args->flags |= XFSMNT_NOUUID;
- } else if (!strcmp(this_char, MNTOPT_NOLOGFLUSH)) {
- args->flags |= XFSMNT_NOLOGFLUSH;
- } else if (!strcmp(this_char, "osyncisdsync")) {
- /* no-op, this is now the default */
-printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
- } else if (!strcmp(this_char, "irixsgid")) {
-printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
- } else {
- printk("XFS: unknown mount option [%s].\n", this_char);
- return -EINVAL;
- }
- }
-
- if (args->flags & XFSMNT_NORECOVERY) {
- if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
- printk("XFS: no-recovery mounts must be read-only.\n");
- return -EINVAL;
- }
- }
-
- if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
- printk(
- "XFS: sunit and swidth options incompatible with the noalign option\n");
- return -EINVAL;
- }
-
- if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
- printk("XFS: sunit and swidth must be specified together\n");
- return -EINVAL;
- }
-
- if (dsunit && (dswidth % dsunit != 0)) {
- printk(
- "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n",
- dswidth, dsunit);
- return -EINVAL;
- }
-
- if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
- if (dsunit) {
- args->sunit = dsunit;
- args->flags |= XFSMNT_RETERR;
- } else {
- args->sunit = vol_dsunit;
- }
- dswidth ? (args->swidth = dswidth) :
- (args->swidth = vol_dswidth);
- } else {
- args->sunit = args->swidth = 0;
- }
-
- return 0;
-}
-
-int
-xfs_showargs(
- struct bhv_desc *bhv,
- struct seq_file *m)
-{
- static struct proc_xfs_info {
- int flag;
- char *str;
- } xfs_info[] = {
- /* the few simple ones we can get from the mount struct */
- { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
- { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
- { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
- { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
- { 0, NULL }
- };
- struct proc_xfs_info *xfs_infop;
- struct xfs_mount *mp = XFS_BHVTOM(bhv);
- char b[BDEVNAME_SIZE];
-
- for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
- if (mp->m_flags & xfs_infop->flag)
- seq_puts(m, xfs_infop->str);
- }
-
- if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
- seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
-
- if (mp->m_logbufs > 0)
- seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
-
- if (mp->m_logbsize > 0)
- seq_printf(m, "," MNTOPT_LOGBSIZE "=%d", mp->m_logbsize);
-
- if (mp->m_ddev_targp->pbr_dev != mp->m_logdev_targp->pbr_dev)
- seq_printf(m, "," MNTOPT_LOGDEV "=%s",
- bdevname(mp->m_logdev_targp->pbr_bdev, b));
-
- if (mp->m_rtdev_targp &&
- mp->m_ddev_targp->pbr_dev != mp->m_rtdev_targp->pbr_dev)
- seq_printf(m, "," MNTOPT_RTDEV "=%s",
- bdevname(mp->m_rtdev_targp->pbr_bdev, b));
-
- if (mp->m_dalign > 0)
- seq_printf(m, "," MNTOPT_SUNIT "=%d",
- (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
-
- if (mp->m_swidth > 0)
- seq_printf(m, "," MNTOPT_SWIDTH "=%d",
- (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
-
- return 0;
-}
-
STATIC __inline__ void
xfs_set_inodeops(
struct inode *inode)
@@ -616,7 +385,6 @@ linvfs_remount(
char *options)
{
vfs_t *vfsp = LINVFS_GET_VFS(sb);
- xfs_mount_t *mp = XFS_VFSTOM(vfsp);
struct xfs_mount_args *args = args_allocate(sb);
int error;
@@ -624,24 +392,7 @@ linvfs_remount(
if (error)
goto out;
- if (args->flags & XFSMNT_NOATIME)
- mp->m_flags |= XFS_MOUNT_NOATIME;
- else
- mp->m_flags &= ~XFS_MOUNT_NOATIME;
-
- set_posix_acl_flag(sb);
- linvfs_write_super(sb);
-
- if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
- goto out;
-
- if (*flags & MS_RDONLY) {
- sb->s_flags |= MS_RDONLY;
- XFS_log_write_unmount_ro(&mp->m_bhv);
- vfsp->vfs_flag |= VFS_RDONLY;
- } else {
- vfsp->vfs_flag &= ~VFS_RDONLY;
- }
+ VFS_MNTUPDATE(vfsp, flags, args, error);
out:
kmem_free(args, sizeof(*args));
diff --git a/fs/xfs/linux/xfs_super.h b/fs/xfs/linux/xfs_super.h
index 001185286ece..98fa75e4e224 100644
--- a/fs/xfs/linux/xfs_super.h
+++ b/fs/xfs/linux/xfs_super.h
@@ -92,8 +92,6 @@ struct xfs_mount;
struct pb_target;
struct block_device;
-extern int xfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
-extern int xfs_showargs(bhv_desc_t *, struct seq_file *);
extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern int xfs_blkdev_get(struct xfs_mount *, const char *,
diff --git a/fs/xfs/linux/xfs_vfs.c b/fs/xfs/linux/xfs_vfs.c
index 0ce23faa46e4..3450d4bd07e3 100644
--- a/fs/xfs/linux/xfs_vfs.c
+++ b/fs/xfs/linux/xfs_vfs.c
@@ -89,6 +89,21 @@ vfs_unmount(
}
int
+vfs_mntupdate(
+ struct bhv_desc *bdp,
+ int *fl,
+ struct xfs_mount_args *args)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_mntupdate)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_mntupdate)(next, fl, args));
+}
+
+
+int
vfs_root(
struct bhv_desc *bdp,
struct vnode **vpp)
diff --git a/fs/xfs/linux/xfs_vfs.h b/fs/xfs/linux/xfs_vfs.h
index 6241f37096db..a930d9b625e5 100644
--- a/fs/xfs/linux/xfs_vfs.h
+++ b/fs/xfs/linux/xfs_vfs.h
@@ -93,6 +93,8 @@ typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *,
struct xfs_mount_args *, int);
typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
+typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
+ struct xfs_mount_args *);
typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **);
typedef int (*vfs_statvfs_t)(bhv_desc_t *, struct statfs *, struct vnode *);
typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
@@ -109,6 +111,7 @@ typedef struct vfsops {
vfs_parseargs_t vfs_parseargs; /* parse mount options */
vfs_showargs_t vfs_showargs; /* unparse mount options */
vfs_unmount_t vfs_unmount; /* unmount file system */
+ vfs_mntupdate_t vfs_mntupdate; /* update file system options */
vfs_root_t vfs_root; /* get root vnode */
vfs_statvfs_t vfs_statvfs; /* file system statistics */
vfs_sync_t vfs_sync; /* flush files */
@@ -126,7 +129,8 @@ typedef struct vfsops {
#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr))
#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f))
#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m))
-#define VFS_UNMOUNT(v, f,cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr))
+#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr))
+#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args))
#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp))
#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp))
#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr))
@@ -143,6 +147,7 @@ typedef struct vfsops {
#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f))
#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m))
#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr))
+#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args))
#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp))
#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp))
#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr))
@@ -156,6 +161,7 @@ extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
+extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
extern int vfs_root(bhv_desc_t *, struct vnode **);
extern int vfs_statvfs(bhv_desc_t *, struct statfs *, struct vnode *);
extern int vfs_sync(bhv_desc_t *, int, struct cred *);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 520ea6969afa..a3ff214d652d 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -49,7 +49,6 @@ xfs_init(void)
extern kmem_zone_t *xfs_efd_zone;
extern kmem_zone_t *xfs_efi_zone;
extern kmem_zone_t *xfs_dabuf_zone;
- extern mutex_t xfs_uuidtabmon;
#ifdef DEBUG_NOT
extern ktrace_t *xfs_alloc_trace_buf;
extern ktrace_t *xfs_bmap_trace_buf;
@@ -563,6 +562,46 @@ out:
return XFS_ERROR(error);
}
+STATIC int
+xfs_mntupdate(
+ bhv_desc_t *bdp,
+ int *flags,
+ struct xfs_mount_args *args)
+{
+ struct vfs *vfsp = bhvtovfs(bdp);
+ xfs_mount_t *mp = XFS_BHVTOM(bdp);
+ int pincount, error;
+
+ if (args->flags & XFSMNT_NOATIME)
+ mp->m_flags |= XFS_MOUNT_NOATIME;
+ else
+ mp->m_flags &= ~XFS_MOUNT_NOATIME;
+
+ if (!(vfsp->vfs_flag & VFS_RDONLY)) {
+ VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
+ }
+
+ if (*flags & MS_RDONLY) {
+ pagebuf_delwri_flush(mp->m_ddev_targp, 0, NULL);
+ xfs_finish_reclaim_all(mp);
+
+ do {
+ VFS_SYNC(vfsp, SYNC_ATTR|SYNC_WAIT, NULL, error);
+ pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT,
+ &pincount);
+ } while (pincount);
+
+ /* Ok now write out an unmount record */
+ xfs_log_unmount_write(mp);
+ xfs_unmountfs_writesb(mp);
+ vfsp->vfs_flag |= VFS_RDONLY;
+ } else {
+ vfsp->vfs_flag &= ~VFS_RDONLY;
+ }
+
+ return 0;
+}
+
/*
* xfs_unmount_flush implements a set of flush operation on special
* inodes, which are needed as a separate set of operations so that
@@ -1495,12 +1534,246 @@ xfs_vget(
}
+#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
+#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
+#define MNTOPT_LOGDEV "logdev" /* log device */
+#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
+#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
+#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
+#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
+#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
+#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
+#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
+#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
+#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
+#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
+#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
+#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
+
+
+int
+xfs_parseargs(
+ struct bhv_desc *bhv,
+ char *options,
+ struct xfs_mount_args *args,
+ int update)
+{
+ struct vfs *vfsp = bhvtovfs(bhv);
+ char *this_char, *value, *eov;
+ int dsunit, dswidth, vol_dsunit, vol_dswidth;
+ int iosize;
+
+ if (!options)
+ return 0;
+
+ iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
+
+ while ((this_char = strsep(&options, ",")) != NULL) {
+ if (!*this_char)
+ continue;
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
+ if (!value || !*value) {
+ printk("XFS: %s option requires an argument\n",
+ MNTOPT_LOGBUFS);
+ 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);
+ 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;
+ } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
+ if (!value || !*value) {
+ printk("XFS: %s option requires an argument\n",
+ MNTOPT_LOGDEV);
+ 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);
+ 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);
+ 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);
+ return -EINVAL;
+ }
+ iosize = simple_strtoul(value, &eov, 10);
+ args->flags |= XFSMNT_IOSIZE;
+ args->iosizelog = (uint8_t) iosize;
+ } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
+ args->flags |= XFSMNT_WSYNC;
+ } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
+ args->flags |= XFSMNT_OSYNCISOSYNC;
+ } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
+ args->flags |= XFSMNT_NORECOVERY;
+ } else if (!strcmp(this_char, MNTOPT_INO64)) {
+ args->flags |= XFSMNT_INO64;
+#ifndef XFS_BIG_FILESYSTEMS
+ printk("XFS: %s option not allowed on this system\n",
+ MNTOPT_INO64);
+ return -EINVAL;
+#endif
+ } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
+ args->flags |= XFSMNT_NOALIGN;
+ } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
+ if (!value || !*value) {
+ printk("XFS: %s option requires an argument\n",
+ MNTOPT_SUNIT);
+ 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);
+ return -EINVAL;
+ }
+ dswidth = simple_strtoul(value, &eov, 10);
+ } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
+ args->flags |= XFSMNT_NOUUID;
+ } else if (!strcmp(this_char, MNTOPT_NOLOGFLUSH)) {
+ args->flags |= XFSMNT_NOLOGFLUSH;
+ } else if (!strcmp(this_char, "osyncisdsync")) {
+ /* no-op, this is now the default */
+printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
+ } else if (!strcmp(this_char, "irixsgid")) {
+printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
+ } else {
+ printk("XFS: unknown mount option [%s].\n", this_char);
+ return -EINVAL;
+ }
+ }
+
+ if (args->flags & XFSMNT_NORECOVERY) {
+ if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
+ printk("XFS: no-recovery mounts must be read-only.\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
+ printk(
+ "XFS: sunit and swidth options incompatible with the noalign option\n");
+ return -EINVAL;
+ }
+
+ if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
+ printk("XFS: sunit and swidth must be specified together\n");
+ return -EINVAL;
+ }
+
+ if (dsunit && (dswidth % dsunit != 0)) {
+ printk(
+ "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n",
+ dswidth, dsunit);
+ return -EINVAL;
+ }
+
+ if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
+ if (dsunit) {
+ args->sunit = dsunit;
+ args->flags |= XFSMNT_RETERR;
+ } else {
+ args->sunit = vol_dsunit;
+ }
+ dswidth ? (args->swidth = dswidth) :
+ (args->swidth = vol_dswidth);
+ } else {
+ args->sunit = args->swidth = 0;
+ }
+
+ return 0;
+}
+
+int
+xfs_showargs(
+ struct bhv_desc *bhv,
+ struct seq_file *m)
+{
+ static struct proc_xfs_info {
+ int flag;
+ char *str;
+ } xfs_info[] = {
+ /* the few simple ones we can get from the mount struct */
+ { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
+ { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
+ { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
+ { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
+ { 0, NULL }
+ };
+ struct proc_xfs_info *xfs_infop;
+ struct xfs_mount *mp = XFS_BHVTOM(bhv);
+ char b[BDEVNAME_SIZE];
+
+ for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
+ if (mp->m_flags & xfs_infop->flag)
+ seq_puts(m, xfs_infop->str);
+ }
+
+ if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
+ seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
+
+ if (mp->m_logbufs > 0)
+ seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
+
+ if (mp->m_logbsize > 0)
+ seq_printf(m, "," MNTOPT_LOGBSIZE "=%d", mp->m_logbsize);
+
+ if (mp->m_ddev_targp->pbr_dev != mp->m_logdev_targp->pbr_dev)
+ seq_printf(m, "," MNTOPT_LOGDEV "=%s",
+ bdevname(mp->m_logdev_targp->pbr_bdev, b));
+
+ if (mp->m_rtdev_targp &&
+ mp->m_ddev_targp->pbr_dev != mp->m_rtdev_targp->pbr_dev)
+ seq_printf(m, "," MNTOPT_RTDEV "=%s",
+ bdevname(mp->m_rtdev_targp->pbr_bdev, b));
+
+ if (mp->m_dalign > 0)
+ seq_printf(m, "," MNTOPT_SUNIT "=%d",
+ (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
+
+ if (mp->m_swidth > 0)
+ seq_printf(m, "," MNTOPT_SWIDTH "=%d",
+ (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
+
+ return 0;
+}
+
+
vfsops_t xfs_vfsops = {
BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
.vfs_parseargs = xfs_parseargs,
.vfs_showargs = xfs_showargs,
.vfs_mount = xfs_mount,
.vfs_unmount = xfs_unmount,
+ .vfs_mntupdate = xfs_mntupdate,
.vfs_root = xfs_root,
.vfs_statvfs = xfs_statvfs,
.vfs_sync = xfs_sync,