Nobody ever dereferences an XFS mount point's m_dm_ops vector pointer any more unless the XFS_MOUNT_DMAPI mount flag is set. So leverage that to just use a null pointer there in that case, and drop the whole xfs_dmcore_stub variable. Change it so that once the m_dm_ops vector has had a chance to be assigned at mount time, a non-null m_vm_ops pointer is always used to indicate DMAPI is active on a file system rather than looking at the mount flag. Also rearrange the logic in xfs_dmops_get() a bit to avoid including much of the code in the case DMAPI isn't supported at build time. Signed-off-by: Alex Elder <aelder@xxxxxxx> --- fs/xfs/linux-2.6/xfs_file.c | 6 ++---- fs/xfs/xfs_dmapi.h | 10 +++++----- fs/xfs/xfs_dmops.c | 37 +++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 25 deletions(-) Index: b/fs/xfs/linux-2.6/xfs_file.c =================================================================== --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -674,8 +674,7 @@ start: goto out_unlock_mutex; } - if (mp->m_flags & XFS_MOUNT_DMAPI && !(ioflags & IO_INVIS) && - !eventsent) { + if (mp->m_dm_ops && !(ioflags & IO_INVIS) && !eventsent) { int dmflags = FILP_DELAY_FLAG(file); if (need_i_mutex) @@ -830,8 +829,7 @@ write_retry: xfs_iunlock(ip, XFS_ILOCK_EXCL); } - if (ret == -ENOSPC && mp->m_flags & XFS_MOUNT_DMAPI && - !(ioflags & IO_INVIS)) { + if (ret == -ENOSPC && mp->m_dm_ops && !(ioflags & IO_INVIS)) { xfs_iunlock(ip, iolock); if (need_i_mutex) mutex_unlock(&inode->i_mutex); Index: b/fs/xfs/xfs_dmapi.h =================================================================== --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h @@ -201,7 +201,7 @@ xfs_dmapi_event_enabled(struct xfs_inode #ifdef XFS_DMAPI unsigned int event_mask = 1 << event; - return ip->i_mount->m_flags & XFS_MOUNT_DMAPI && + return ip->i_mount->m_dm_ops && (ip->i_mount->m_dmevmask & event_mask || ip->i_d.di_dmevmask & event_mask); #else /* ! XFS_DMAPI */ @@ -235,7 +235,7 @@ xfs_dmapi_send_mmap( struct inode *inode = vma->vm_file->f_path.dentry->d_inode; struct xfs_mount *mp = XFS_M(inode->i_sb); - if (mp->m_flags & XFS_MOUNT_DMAPI) { + if (mp->m_dm_ops) { xfs_send_mmap_t send_mmap = mp->m_dm_ops->xfs_send_mmap; return send_mmap(vma, vm_flags); @@ -319,7 +319,7 @@ xfs_dmapi_send_mount( struct xfs_mount *mp, char *path) { - if (mp->m_flags & XFS_MOUNT_DMAPI) { + if (mp->m_dm_ops) { xfs_send_mount_t send_mount = mp->m_dm_ops->xfs_send_mount; return send_mount(mp, DM_RIGHT_NULL, path, mp->m_fsname); @@ -333,7 +333,7 @@ static inline void xfs_dmapi_send_preunmount( struct xfs_mount *mp) { - if (mp->m_flags & XFS_MOUNT_DMAPI) + if (mp->m_dm_ops) (void) xfs_dmapi_send_namesp(mp->m_rootip, DM_RIGHT_NULL, NULL, DM_EVENT_PREUNMOUNT, mp->m_rootip, DM_RIGHT_NULL, NULL, @@ -344,7 +344,7 @@ static inline void xfs_dmapi_send_unmount( struct xfs_mount *mp) { - if (mp->m_flags & XFS_MOUNT_DMAPI) { + if (mp->m_dm_ops) { xfs_send_unmount_t send_unmount = mp->m_dm_ops->xfs_send_unmount; Index: b/fs/xfs/xfs_dmops.c =================================================================== --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c @@ -28,30 +28,35 @@ #include "xfs_inode.h" #include "xfs_dmapi.h" - -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_mount = (xfs_send_mount_t)fs_nosys, - .xfs_send_unmount = (xfs_send_unmount_t)fs_noerr, -}; - int xfs_dmops_get(struct xfs_mount *mp) { - if (mp->m_flags & XFS_MOUNT_DMAPI) { - cmn_err(CE_WARN, - "XFS: dmapi support not available in this kernel."); - return EINVAL; + ASSERT(!mp->m_dm_ops); + if (!(mp->m_flags & XFS_MOUNT_DMAPI)) + return 0; + +#ifdef XFS_DMAPI + mp->m_dm_ops = symbol_get(xfs_dmcore_xfs); + if (!mp->m_dm_ops) { + request_module("xfs_dmapi"); + mp->m_dm_ops = symbol_get(xfs_dmcore_xfs); } + if (mp->m_dm_ops) + return 0; +#endif /* XFS_DMAPI */ - mp->m_dm_ops = &xfs_dmcore_stub; - return 0; + /* Turn off the flag, since it won't be operative */ + mp->m_flags &= ~XFS_MOUNT_DMAPI; + cmn_err(CE_WARN, "XFS: dmapi support not available in this kernel."); + + return EINVAL; } void xfs_dmops_put(struct xfs_mount *mp) { + if (mp->m_dm_ops) { + symbol_put(xfs_dmcore_xfs); + mp->m_dm_ops = NULL; + } } _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs