summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_inode_util.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 11:07:34 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-09-17 18:55:04 -0700
commitbf1075b6db1803ba29af4acd9a11efe18790aa54 (patch)
treeba0f5c190fc76162e2621bace501fd5e0dd194fd /fs/xfs/libxfs/xfs_inode_util.c
parentc70c42a6455d2374fac4a5024716ef94f0770bfd (diff)
xfs: hoist inode free function to libxfs
Create a libxfs helper function that marks an inode free on disk. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs/xfs_inode_util.c')
-rw-r--r--fs/xfs/libxfs/xfs_inode_util.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_util.c b/fs/xfs/libxfs/xfs_inode_util.c
index b6c6d321f6fc..fb68eeb58d0a 100644
--- a/fs/xfs/libxfs/xfs_inode_util.c
+++ b/fs/xfs/libxfs/xfs_inode_util.c
@@ -21,6 +21,7 @@
#include "xfs_error.h"
#include "xfs_trace.h"
#include "xfs_ag.h"
+#include "xfs_inode_item.h"
uint16_t
xfs_flags2diflags(
@@ -791,3 +792,50 @@ xfs_bumplink(
inc_nlink(VFS_I(ip));
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
}
+
+/* Mark an inode free on disk. */
+int
+xfs_dir_ifree(
+ struct xfs_trans *tp,
+ struct xfs_perag *pag,
+ struct xfs_inode *ip,
+ struct xfs_icluster *xic)
+{
+ int error;
+
+ /*
+ * Pull the on-disk inode from the AGI unlinked list.
+ */
+ error = xfs_iunlink_remove(tp, pag, ip);
+ if (error)
+ return error;
+
+ error = xfs_difree(tp, pag, ip->i_ino, xic);
+ 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) {
+ kmem_free(ip->i_df.if_u1.if_data);
+ ip->i_df.if_u1.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 = ip->i_mount->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;
+}