]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: split new inode creation into two pieces
authorDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jul 2024 18:22:36 +0000 (11:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jul 2024 18:36:57 +0000 (11:36 -0700)
There are two parts to initializing a newly allocated inode: setting up
the incore structures, and initializing the new inode core based on the
parent inode and the current user's environment.  The initialization
code is not specific to the kernel, so we would like to share that with
userspace by hoisting it to libxfs.  Therefore, split xfs_icreate into
separate functions to prepare for the next few patches.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/xfs_inode.c

index 14c81f227c5bb92c98c742bae20d68364dc1de63..f8d5ed7aedde89b434ee59801e6825a716a232a0 100644 (file)
@@ -1946,6 +1946,21 @@ retry:
                }
                return -ENOSPC;
        }
+
+       /*
+        * Protect against obviously corrupt allocation btree records. Later
+        * xfs_iget checks will catch re-allocation of other active in-memory
+        * and on-disk inodes. If we don't catch reallocating the parent inode
+        * here we will deadlock in xfs_iget() so we have to do these checks
+        * first.
+        */
+       if (ino == parent || !xfs_verify_dir_ino(mp, ino)) {
+               xfs_alert(mp, "Allocated a known in-use inode 0x%llx!", ino);
+               xfs_agno_mark_sick(mp, XFS_INO_TO_AGNO(mp, ino),
+                               XFS_SICK_AG_INOBT);
+               return -EFSCORRUPTED;
+       }
+
        *new_ino = ino;
        return 0;
 }
index 59e76759e41ff7386a05f152b0405a87ff7205cc..88c641400f51e15f3f7a3d9ad2ec0d7f4136a584 100644 (file)
@@ -655,53 +655,20 @@ xfs_inode_inherit_flags2(
        }
 }
 
-/*
- * Initialise a newly allocated inode and return the in-core inode to the
- * caller locked exclusively.
- *
- * Caller is responsible for unlocking the inode manually upon return
- */
-int
-xfs_icreate(
+/* Initialise an inode's attributes. */
+static void
+xfs_inode_init(
        struct xfs_trans        *tp,
-       xfs_ino_t               ino,
        const struct xfs_icreate_args *args,
-       struct xfs_inode        **ipp)
+       struct xfs_inode        *ip)
 {
        struct xfs_inode        *pip = args->pip;
        struct inode            *dir = pip ? VFS_I(pip) : NULL;
        struct xfs_mount        *mp = tp->t_mountp;
-       struct xfs_inode        *ip;
-       struct inode            *inode;
+       struct inode            *inode = VFS_I(ip);
        unsigned int            flags;
        int                     times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG |
                                        XFS_ICHGTIME_ACCESS;
-       int                     error;
-
-       /*
-        * Protect against obviously corrupt allocation btree records. Later
-        * xfs_iget checks will catch re-allocation of other active in-memory
-        * and on-disk inodes. If we don't catch reallocating the parent inode
-        * here we will deadlock in xfs_iget() so we have to do these checks
-        * first.
-        */
-       if ((pip && ino == pip->i_ino) || !xfs_verify_dir_ino(mp, ino)) {
-               xfs_alert(mp, "Allocated a known in-use inode 0x%llx!", ino);
-               xfs_agno_mark_sick(mp, XFS_INO_TO_AGNO(mp, ino),
-                               XFS_SICK_AG_INOBT);
-               return -EFSCORRUPTED;
-       }
-
-       /*
-        * Get the in-core inode with the lock held exclusively to prevent
-        * others from looking at until we're done.
-        */
-       error = xfs_iget(mp, tp, ino, XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip);
-       if (error)
-               return error;
-
-       ASSERT(ip != NULL);
-       inode = VFS_I(ip);
 
        if (args->flags & XFS_ICREATE_TMPFILE)
                set_nlink(inode, 0);
@@ -801,11 +768,37 @@ xfs_icreate(
                }
        }
 
+       xfs_trans_log_inode(tp, ip, flags);
+}
+
+/*
+ * Initialise a newly allocated inode and return the in-core inode to the
+ * caller locked exclusively.
+ *
+ * Caller is responsible for unlocking the inode manually upon return
+ */
+int
+xfs_icreate(
+       struct xfs_trans        *tp,
+       xfs_ino_t               ino,
+       const struct xfs_icreate_args *args,
+       struct xfs_inode        **ipp)
+{
+       struct xfs_mount        *mp = tp->t_mountp;
+       struct xfs_inode        *ip = NULL;
+       int                     error;
+
        /*
-        * Log the new values stuffed into the inode.
+        * Get the in-core inode with the lock held exclusively to prevent
+        * others from looking at until we're done.
         */
+       error = xfs_iget(mp, tp, ino, XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip);
+       if (error)
+               return error;
+
+       ASSERT(ip != NULL);
        xfs_trans_ijoin(tp, ip, 0);
-       xfs_trans_log_inode(tp, ip, flags);
+       xfs_inode_init(tp, args, ip);
 
        /* now that we have an i_mode we can setup the inode structure */
        xfs_setup_inode(ip);