]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: hoist inode free function to libxfs
authorDarrick J. Wong <djwong@kernel.org>
Wed, 2 Oct 2024 01:14:52 +0000 (18:14 -0700)
committerAndrey Albershteyn <aalbersh@redhat.com>
Fri, 4 Oct 2024 10:42:07 +0000 (12:42 +0200)
Source kernel commit: 1964435d19d947b8626379d09db3e33b9669f333

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>
libxfs/xfs_inode_util.c
libxfs/xfs_inode_util.h

index 13c32d114cb9a81144792a1f514c0ac620f6d82e..74d2b5960bf0f22dcf4c85ef3142a46ce93b5969 100644 (file)
@@ -693,3 +693,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);