From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Decouple the xfs_ialloc function from the platform-specific pieces by passing in an operations structure. This prepares the function for hoisting to libxfs. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_inode_util.h | 30 ++++++++++++++++++++++++++++++ fs/xfs/xfs_inode.c | 13 ++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_util.h b/fs/xfs/libxfs/xfs_inode_util.h index 942524b59cf6..6318234003e1 100644 --- a/fs/xfs/libxfs/xfs_inode_util.h +++ b/fs/xfs/libxfs/xfs_inode_util.h @@ -43,8 +43,11 @@ xfs_get_initial_prid(struct xfs_icdinode *id) return XFS_PROJID_DEFAULT; } +struct xfs_ialloc_ops; + /* Initial ids, link count, device number, and mode of a new inode. */ struct xfs_ialloc_args { + const struct xfs_ialloc_ops *ops; struct xfs_inode *pip; /* parent inode or null */ uint32_t uid; @@ -57,4 +60,31 @@ struct xfs_ialloc_args { umode_t mode; }; +/* Platform-specific inode allocation functions. */ +struct xfs_ialloc_ops { + /* + * Load in-core inode given our new inode number, returning the inode + * with ILOCK_EXCL held to prevent anyone else from seeing the inode + * until we're done. + */ + int (*iget)(struct xfs_mount *mp, struct xfs_trans *tp, xfs_ino_t ino, + struct xfs_inode **ipp); + + /* + * Do whatever platform-specific initialization is necessary to bring + * up this new inode. This is called after we've set up default values + * on the inode but before propagating required fields from the parent + * inode. + */ + void (*platform_init)(struct xfs_trans *tp, + const struct xfs_ialloc_args *args, + struct xfs_inode *ip); + + /* Do any final setup needed before we return the inode. */ + void (*setup)(struct xfs_inode *ip); +}; + +/* The libxfs client must provide this symbol. */ +extern const struct xfs_ialloc_ops xfs_default_ialloc_ops; + #endif /* __XFS_INODE_UTIL_H__ */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b635d43caeed..41fab97d1270 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -647,6 +647,12 @@ xfs_ialloc_platform_init( VFS_I(ip)->i_ctime = tv; } +const struct xfs_ialloc_ops xfs_default_ialloc_ops = { + .iget = xfs_ialloc_iget, + .platform_init = xfs_ialloc_platform_init, + .setup = xfs_setup_inode, +}; + /* * Allocate an inode on disk and return a copy of its in-core version. * The in-core inode is locked exclusively. Set mode, nlink, and rdev @@ -724,7 +730,7 @@ xfs_ialloc( * This is because we're setting fields here we need * to prevent others from looking at until we're done. */ - error = xfs_ialloc_iget(mp, tp, ino, &ip); + error = args->ops->iget(mp, tp, ino, &ip); if (error) return error; ASSERT(ip != NULL); @@ -785,7 +791,7 @@ xfs_ialloc( ip->i_d.di_crtime.t_nsec = 0; } - xfs_ialloc_platform_init(tp, args, ip); + args->ops->platform_init(tp, args, ip); flags = XFS_ILOG_CORE; switch (args->mode & S_IFMT) { @@ -877,7 +883,7 @@ xfs_ialloc( xfs_trans_log_inode(tp, ip, flags); /* now that we have an i_mode we can setup the inode structure */ - xfs_setup_inode(ip); + args->ops->setup(ip); *ipp = ip; return 0; @@ -907,6 +913,7 @@ xfs_dir_ialloc( locked. */ { struct xfs_ialloc_args args = { + .ops = &xfs_default_ialloc_ops, .pip = dp, .uid = xfs_kuid_to_uid(current_fsuid()), .gid = xfs_kgid_to_gid(current_fsgid()),