From: Darrick J. Wong <djwong@xxxxxxxxxx> Create a libxfs helper function that marks an inode free on disk. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- libxfs/xfs_inode_util.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_inode_util.h | 5 +++++ 2 files changed, 55 insertions(+) diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c index e12c43954cf..65c025f3573 100644 --- a/libxfs/xfs_inode_util.c +++ b/libxfs/xfs_inode_util.c @@ -643,3 +643,53 @@ 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; + + /* + * 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) { + 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; +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index f92b14a6fbe..fcddaa6f738 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -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); @@ -56,6 +58,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_dir_ifree(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);