diff options
| -rw-r--r-- | fs/xfs/linux/xfs_lrw.c | 27 | ||||
| -rw-r--r-- | fs/xfs/linux/xfs_lrw.h | 2 | ||||
| -rw-r--r-- | fs/xfs/linux/xfs_super.c | 251 | ||||
| -rw-r--r-- | fs/xfs/linux/xfs_super.h | 2 | ||||
| -rw-r--r-- | fs/xfs/linux/xfs_vfs.c | 15 | ||||
| -rw-r--r-- | fs/xfs/linux/xfs_vfs.h | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_vfsops.c | 275 |
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, |
