]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: hoist inode free function to libxfs
authorDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jul 2024 18:22:44 +0000 (11:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jul 2024 18:36:59 +0000 (11:36 -0700)
Create a libxfs helper function that marks an inode free on disk.

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

index 5795445ef4bd21e4e2141e87e4359fa3695315fb..032333289113b7bdf657bdc68ef9592df85b9a64 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_trace.h"
 #include "xfs_ag.h"
 #include "xfs_iunlink_item.h"
+#include "xfs_inode_item.h"
 
 uint16_t
 xfs_flags2diflags(
@@ -695,3 +696,54 @@ xfs_bumplink(
 
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 }
+
+/* Free an inode in the ondisk index and zero it out. */
+int
+xfs_inode_uninit(
+       struct xfs_trans        *tp,
+       struct xfs_perag        *pag,
+       struct xfs_inode        *ip,
+       struct xfs_icluster     *xic)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       int                     error;
+
+       /*
+        * Free the inode first so that we guarantee that the AGI lock is going
+        * to be taken before we remove the inode from the unlinked list. This
+        * makes the AGI lock -> unlinked list modification order the same as
+        * used in O_TMPFILE creation.
+        */
+       error = xfs_difree(tp, pag, ip->i_ino, xic);
+       if (error)
+               return error;
+
+       error = xfs_iunlink_remove(tp, pag, ip);
+       if (error)
+               return error;
+
+       /*
+        * Free any local-format data sitting around before we reset the
+        * data fork to extents format.  Note that the attr fork data has
+        * already been freed by xfs_attr_inactive.
+        */
+       if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
+               kfree(ip->i_df.if_data);
+               ip->i_df.if_data = NULL;
+               ip->i_df.if_bytes = 0;
+       }
+
+       VFS_I(ip)->i_mode = 0;          /* mark incore inode as free */
+       ip->i_diflags = 0;
+       ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
+       ip->i_forkoff = 0;              /* mark the attr fork not in use */
+       ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
+
+       /*
+        * Bump the generation count so no one will be confused
+        * by reincarnations of this inode.
+        */
+       VFS_I(ip)->i_generation++;
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+       return 0;
+}
index 1c54c3b0cf2626ed74884a8569eb5d9caa9bd500..060242998a230d253dbb8d11dffe47c36bfd3e23 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef        __XFS_INODE_UTIL_H__
 #define        __XFS_INODE_UTIL_H__
 
+struct xfs_icluster;
+
 uint16_t       xfs_flags2diflags(struct xfs_inode *ip, unsigned int xflags);
 uint64_t       xfs_flags2diflags2(struct xfs_inode *ip, unsigned int xflags);
 uint32_t       xfs_dic2xflags(struct xfs_inode *ip);
@@ -48,6 +50,9 @@ void xfs_trans_ichgtime(struct xfs_trans *tp, struct xfs_inode *ip, int flags);
 void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args,
                struct xfs_inode *ip);
 
+int xfs_inode_uninit(struct xfs_trans *tp, struct xfs_perag *pag,
+               struct xfs_inode *ip, struct xfs_icluster *xic);
+
 int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip);
 int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag,
                struct xfs_inode *ip);
index 959fdaef840946a54e4a8abd1a270d7fb05c3934..caccb6296a487410dfc9be2e96660312a7ab351f 100644 (file)
@@ -1945,36 +1945,10 @@ xfs_ifree(
 
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
 
-       /*
-        * Free the inode first so that we guarantee that the AGI lock is going
-        * to be taken before we remove the inode from the unlinked list. This
-        * makes the AGI lock -> unlinked list modification order the same as
-        * used in O_TMPFILE creation.
-        */
-       error = xfs_difree(tp, pag, ip->i_ino, &xic);
+       error = xfs_inode_uninit(tp, pag, ip, &xic);
        if (error)
                goto out;
 
-       error = xfs_iunlink_remove(tp, pag, ip);
-       if (error)
-               goto out;
-
-       /*
-        * Free any local-format data sitting around before we reset the
-        * data fork to extents format.  Note that the attr fork data has
-        * already been freed by xfs_attr_inactive.
-        */
-       if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
-               kfree(ip->i_df.if_data);
-               ip->i_df.if_data = NULL;
-               ip->i_df.if_bytes = 0;
-       }
-
-       VFS_I(ip)->i_mode = 0;          /* mark incore inode as free */
-       ip->i_diflags = 0;
-       ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
-       ip->i_forkoff = 0;              /* mark the attr fork not in use */
-       ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
        if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS))
                xfs_iflags_clear(ip, XFS_IPRESERVE_DM_FIELDS);
 
@@ -1983,13 +1957,6 @@ xfs_ifree(
        iip->ili_fields &= ~(XFS_ILOG_AOWNER | XFS_ILOG_DOWNER);
        spin_unlock(&iip->ili_lock);
 
-       /*
-        * Bump the generation count so no one will be confused
-        * by reincarnations of this inode.
-        */
-       VFS_I(ip)->i_generation++;
-       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
        if (xic.deleted)
                error = xfs_ifree_cluster(tp, pag, ip, &xic);
 out: