[PATCH 07/22] xfs: decouple platform-specific inode allocation functions

Darrick J. Wong
2019-01-01T02:19:53Z

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@oracle.com>
---
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()),