]> git.neil.brown.name Git - history.git/commitdiff
[XFS] Rework the remount path to better seperate the linux vfs portion
authorStephen Lord <lord@sgi.com>
Fri, 2 May 2003 23:51:28 +0000 (01:51 +0200)
committerStephen Lord <lord@sgi.com>
Fri, 2 May 2003 23:51:28 +0000 (01:51 +0200)
and the xfs portion of it. Move the code to more appropriate
places in the tree.

SGI Modid: 2.5.x-xfs:slinx:146667a

fs/xfs/linux/xfs_lrw.c
fs/xfs/linux/xfs_lrw.h
fs/xfs/linux/xfs_super.c
fs/xfs/linux/xfs_super.h
fs/xfs/linux/xfs_vfs.c
fs/xfs/linux/xfs_vfs.h
fs/xfs/xfs_vfsops.c

index cab83b4049b362551f096a349ca729fa6e77c42f..ccd7cbd3283bb51c859401f052ed4b58abb952e9 100644 (file)
@@ -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.
index feb917ab1771d92342657a44bab58e7836ca3763..b85c45520fd9edf50eab294b31873a6336d98aba 100644 (file)
@@ -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)) : \
index d3da2cf7821c823a315c55f202fadf06ad0a9ccb..7b3da4c76f02a33bd9b674b8e2a6fc24504331d3 100644 (file)
@@ -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));
index 001185286ececffbc097f1c17bca4fade17f01a2..98fa75e4e224738e375d63d194736401bc9a9463 100644 (file)
@@ -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 *,
index 0ce23faa46e452b74f676ca9223939a64eb9567e..3450d4bd07e320da99cbc6d445334ca9a1f8bcaf 100644 (file)
@@ -88,6 +88,21 @@ vfs_unmount(
        return ((*bhvtovfsops(next)->vfs_unmount)(next, fl, cr));
 }
 
+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,
index 6241f37096db72da48e1205770f883729f83c96d..a930d9b625e5f83ef2d8108f1cba23046f9ccaad 100644 (file)
@@ -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 *);
index 520ea6969afacccfa04975eb005b3fc865949c92..a3ff214d652dc1d8647db9cef6b485c4f0a26fe7 100644 (file)
@@ -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,