From 293688ec420f1160ed93ea4c7948ed5baf8bafa7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 29 Aug 2007 11:59:36 +1000 Subject: [XFS] remove dependency of the dmapi module on behaviors Mount options are now parsed by the main XFS module and rejected if dmapi support is not available, and there is a new dm operation to send the mount event. SGI-PV: 969608 SGI-Modid: xfs-linux-melb:xfs-kern:29502a Signed-off-by: Christoph Hellwig Signed-off-by: David Chinner Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_vfs.c | 14 -------------- fs/xfs/linux-2.6/xfs_vfs.h | 7 ------- fs/xfs/xfs_dmapi.h | 3 --- fs/xfs/xfs_dmops.c | 43 ++++++++++++++++++++++++++++++++++++++----- fs/xfs/xfs_mount.h | 24 ++++++++++++++++-------- fs/xfs/xfs_vfsops.c | 31 ++++++++++++++++++++++++++++--- 6 files changed, 82 insertions(+), 40 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c index 6ed7f13..1ce1570 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.c +++ b/fs/xfs/linux-2.6/xfs_vfs.c @@ -156,19 +156,6 @@ vfs_vget( } int -vfs_dmapiops( - struct bhv_desc *bdp, - caddr_t addr) -{ - struct bhv_desc *next = bdp; - - ASSERT(next); - while (! (bhvtovfsops(next))->vfs_dmapiops) - next = BHV_NEXT(next); - return ((*bhvtovfsops(next)->vfs_dmapiops)(next, addr)); -} - -int vfs_quotactl( struct bhv_desc *bdp, int cmd, @@ -306,7 +293,6 @@ bhv_remove_all_vfsops( struct xfs_mount *mp; bhv_remove_vfsops(vfsp, VFS_POSITION_QM); - bhv_remove_vfsops(vfsp, VFS_POSITION_DM); if (!freebase) return; mp = XFS_VFSTOM(vfsp); diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index 768ffa9..e63dbdb 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h @@ -66,14 +66,12 @@ typedef struct bhv_vfs { typedef enum { VFS_BHV_UNKNOWN, /* not specified */ VFS_BHV_XFS, /* xfs */ - VFS_BHV_DM, /* data migration */ VFS_BHV_QM, /* quota manager */ VFS_BHV_IO, /* IO path */ VFS_BHV_END /* housekeeping end-of-range */ } bhv_vfs_type_t; #define VFS_POSITION_XFS (BHV_POSITION_BASE) -#define VFS_POSITION_DM (VFS_POSITION_BASE+10) #define VFS_POSITION_QM (VFS_POSITION_BASE+20) #define VFS_POSITION_IO (VFS_POSITION_BASE+30) @@ -129,7 +127,6 @@ typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *, struct inode *); typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); typedef int (*vfs_vget_t)(bhv_desc_t *, struct inode **, struct fid *); -typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); typedef void (*vfs_init_vnode_t)(bhv_desc_t *, struct inode *, struct xfs_inode *, int); @@ -147,7 +144,6 @@ typedef struct bhv_vfsops { vfs_statvfs_t vfs_statvfs; /* file system statistics */ vfs_sync_t vfs_sync; /* flush files */ vfs_vget_t vfs_vget; /* get vnode from fid */ - vfs_dmapiops_t vfs_dmapiops; /* data migration */ vfs_quotactl_t vfs_quotactl; /* disk quota */ vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ @@ -167,7 +163,6 @@ typedef struct bhv_vfsops { #define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp) #define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr) #define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp) -#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p) #define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p) #define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul) #define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l) @@ -185,7 +180,6 @@ typedef struct bhv_vfsops { #define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp) #define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr) #define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp) -#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p) #define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p) #define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul) #define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l) @@ -200,7 +194,6 @@ extern int vfs_root(bhv_desc_t *, struct inode **); extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct inode *); extern int vfs_sync(bhv_desc_t *, int, struct cred *); extern int vfs_vget(bhv_desc_t *, struct inode **, struct fid *); -extern int vfs_dmapiops(bhv_desc_t *, caddr_t); extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); extern void vfs_init_vnode(bhv_desc_t *, struct inode *, struct xfs_inode *, int); extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 98b4d63..029f96d 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h @@ -168,7 +168,4 @@ typedef enum { DM_FLAGS_NDELAY : 0) #define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) - -extern struct bhv_module_vfsops xfs_dmops; - #endif /* __XFS_DMAPI_H__ */ diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c index 1e4a35d..6cd5704 100644 --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c @@ -19,18 +19,51 @@ #include "xfs_fs.h" #include "xfs_types.h" #include "xfs_log.h" -#include "xfs_inum.h" #include "xfs_trans.h" #include "xfs_sb.h" -#include "xfs_ag.h" -#include "xfs_dir2.h" #include "xfs_dmapi.h" +#include "xfs_inum.h" +#include "xfs_ag.h" #include "xfs_mount.h" +#include "xfs_clnt.h" + -xfs_dmops_t xfs_dmcore_stub = { +static struct xfs_dmops xfs_dmcore_stub = { .xfs_send_data = (xfs_send_data_t)fs_nosys, .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr, .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys, .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys, - .xfs_send_unmount = (xfs_send_unmount_t)fs_noval, + .xfs_send_mount = (xfs_send_mount_t)fs_nosys, + .xfs_send_unmount = (xfs_send_unmount_t)fs_noerr, }; + +int +xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) +{ + if (args->flags & XFSMNT_DMAPI) { + struct xfs_dmops *ops; + + ops = symbol_get(xfs_dmcore_xfs); + if (!ops) { + request_module("xfs_dmapi"); + ops = symbol_get(xfs_dmcore_xfs); + } + + if (!ops) { + cmn_err(CE_WARN, "XFS: no dmapi support available."); + return EINVAL; + } + mp->m_dm_ops = ops; + } else { + mp->m_dm_ops = &xfs_dmcore_stub; + } + + return 0; +} + +void +xfs_dmops_put(struct xfs_mount *mp) +{ + if (mp->m_dm_ops != &xfs_dmcore_stub) + symbol_put(xfs_dmcore_xfs); +} diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 02b9a6e..a7cd596 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -85,6 +85,8 @@ typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *, bhv_vnode_t *, dm_right_t, bhv_vnode_t *, dm_right_t, char *, char *, mode_t, int, int); +typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t, + char *, char *); typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, bhv_vnode_t *, dm_right_t, mode_t, int, int); @@ -93,21 +95,24 @@ typedef struct xfs_dmops { xfs_send_mmap_t xfs_send_mmap; xfs_send_destroy_t xfs_send_destroy; xfs_send_namesp_t xfs_send_namesp; + xfs_send_mount_t xfs_send_mount; xfs_send_unmount_t xfs_send_unmount; } xfs_dmops_t; #define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \ - (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock) + (*(mp)->m_dm_ops->xfs_send_data)(ev,vp,off,len,fl,lock) #define XFS_SEND_MMAP(mp, vma,fl) \ - (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl) + (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl) #define XFS_SEND_DESTROY(mp, vp,right) \ - (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right) + (*(mp)->m_dm_ops->xfs_send_destroy)(vp,right) #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ - (*(mp)->m_dm_ops.xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) + (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) #define XFS_SEND_PREUNMOUNT(mp, vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ - (*(mp)->m_dm_ops.xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) + (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) +#define XFS_SEND_MOUNT(mp,right,path,name) \ + (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) #define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \ - (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl) + (*(mp)->m_dm_ops->xfs_send_unmount)(vfsp,vp,right,mode,rval,fl) /* @@ -407,7 +412,7 @@ typedef struct xfs_mount { uint m_chsize; /* size of next field */ struct xfs_chash *m_chash; /* fs private inode per-cluster * hash table */ - struct xfs_dmops m_dm_ops; /* vector of DMI ops */ + struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ struct xfs_qmops m_qm_ops; /* vector of XQM ops */ struct xfs_ioops m_io_ops; /* vector of I/O ops */ atomic_t m_active_trans; /* number trans frozen */ @@ -642,7 +647,10 @@ extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); -extern struct xfs_dmops xfs_dmcore_stub; +extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); +extern void xfs_dmops_put(struct xfs_mount *); + +extern struct xfs_dmops xfs_dmcore_xfs; extern struct xfs_qmops xfs_qmcore_stub; extern struct xfs_ioops xfs_iocore_xfs; diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 8c0e022..1cf8f54 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -326,6 +326,8 @@ xfs_start_flags( if (ap->flags2 & XFSMNT2_FILESTREAMS) mp->m_flags |= XFS_MOUNT_FILESTREAMS; + if (ap->flags & XFSMNT_DMAPI) + vfs->vfs_flag |= VFS_DMI; return 0; } @@ -430,11 +432,13 @@ xfs_mount( ddev = vfsp->vfs_super->s_bdev; logdev = rtdev = NULL; + error = xfs_dmops_get(mp, args); + if (error) + return error; + /* * Setup xfs_mount function vectors from available behaviors */ - p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); - mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); @@ -537,6 +541,8 @@ xfs_mount( if (error) goto error2; + XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); + return 0; error2: @@ -550,6 +556,7 @@ error1: xfs_binval(mp->m_rtdev_targp); error0: xfs_unmountfs_close(mp, credp); + xfs_dmops_put(mp); return error; } @@ -640,6 +647,7 @@ out: * and free the super block buffer & mount structures. */ xfs_unmountfs(mp, credp); + xfs_dmops_put(mp); kmem_free(mp, sizeof(xfs_mount_t)); } @@ -1688,6 +1696,9 @@ xfs_vget( #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ +#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ +#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ +#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ STATIC unsigned long suffix_strtoul(char *s, char **endp, unsigned int base) @@ -1878,6 +1889,12 @@ xfs_parseargs( args->flags &= ~XFSMNT_ATTR2; } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { args->flags2 |= XFSMNT2_FILESTREAMS; + } else if (!strcmp(this_char, MNTOPT_DMAPI)) { + args->flags |= XFSMNT_DMAPI; + } else if (!strcmp(this_char, MNTOPT_XDSM)) { + args->flags |= XFSMNT_DMAPI; + } else if (!strcmp(this_char, MNTOPT_DMI)) { + args->flags |= XFSMNT_DMAPI; } else if (!strcmp(this_char, "ihashsize")) { cmn_err(CE_WARN, "XFS: ihashsize no longer used, option is deprecated."); @@ -1909,6 +1926,12 @@ xfs_parseargs( return EINVAL; } + if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { + printk("XFS: %s option needs the mount point option as well\n", + MNTOPT_DMAPI); + return EINVAL; + } + if ((dsunit && !dswidth) || (!dsunit && dswidth)) { cmn_err(CE_WARN, "XFS: sunit and swidth must be specified together"); @@ -2002,6 +2025,9 @@ xfs_showargs( if (vfsp->vfs_flag & VFS_GRPID) seq_printf(m, "," MNTOPT_GRPID); + if (vfsp->vfs_flag & VFS_DMI) + seq_puts(m, "," MNTOPT_DMAPI); + return 0; } @@ -2032,7 +2058,6 @@ bhv_vfsops_t xfs_vfsops = { .vfs_statvfs = xfs_statvfs, .vfs_sync = xfs_sync, .vfs_vget = xfs_vget, - .vfs_dmapiops = (vfs_dmapiops_t)fs_nosys, .vfs_quotactl = (vfs_quotactl_t)fs_nosys, .vfs_init_vnode = xfs_initialize_vnode, .vfs_force_shutdown = xfs_do_force_shutdown, -- cgit v1.1