From c97163b04531f611113f2e4c791b3904da9662e7 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 3 Jul 2024 14:21:37 -0700 Subject: [PATCH] xfs_db: port the iunlink command to use the libxfs iunlink function Now that we've ported the kernel's iunlink code to userspace, adapt the debugger command to use it instead of duplicating the logic. Signed-off-by: Darrick J. Wong --- db/iunlink.c | 110 +-------------------------------------- libxfs/libxfs_api_defs.h | 1 + 2 files changed, 2 insertions(+), 109 deletions(-) diff --git a/db/iunlink.c b/db/iunlink.c index b3356d73b..a2f441903 100644 --- a/db/iunlink.c +++ b/db/iunlink.c @@ -197,114 +197,6 @@ static const cmdinfo_t dump_iunlinked_cmd = N_("[-a agno] [-b bucket] [-q] [-v]"), N_("dump chain of unlinked inode buckets"), NULL }; -/* - * Look up the inode cluster buffer and log the on-disk unlinked inode change - * we need to make. - */ -static int -iunlink_log_dinode( - struct xfs_trans *tp, - struct xfs_inode *ip, - struct xfs_perag *pag, - xfs_agino_t next_agino) -{ - struct xfs_mount *mp = tp->t_mountp; - struct xfs_dinode *dip; - struct xfs_buf *ibp; - int offset; - int error; - - error = -libxfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp); - if (error) - return error; - - dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset); - - dip->di_next_unlinked = cpu_to_be32(next_agino); - offset = ip->i_imap.im_boffset + - offsetof(struct xfs_dinode, di_next_unlinked); - - libxfs_dinode_calc_crc(mp, dip); - libxfs_trans_log_buf(tp, ibp, offset, offset + sizeof(xfs_agino_t) - 1); - return 0; -} - -static int -iunlink_insert_inode( - struct xfs_trans *tp, - struct xfs_perag *pag, - struct xfs_buf *agibp, - struct xfs_inode *ip) -{ - struct xfs_mount *mp = tp->t_mountp; - struct xfs_agi *agi = agibp->b_addr; - xfs_agino_t next_agino; - xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); - short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; - int offset; - int error; - - /* - * Get the index into the agi hash table for the list this inode will - * go on. Make sure the pointer isn't garbage and that this inode - * isn't already on the list. - */ - next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); - if (next_agino == agino || !xfs_verify_agino_or_null(pag, next_agino)) - return EFSCORRUPTED; - - if (next_agino != NULLAGINO) { - /* - * There is already another inode in the bucket, so point this - * inode to the current head of the list. - */ - error = iunlink_log_dinode(tp, ip, pag, next_agino); - if (error) - return error; - } - - /* Update the bucket. */ - agi->agi_unlinked[bucket_index] = cpu_to_be32(agino); - offset = offsetof(struct xfs_agi, agi_unlinked) + - (sizeof(xfs_agino_t) * bucket_index); - libxfs_trans_log_buf(tp, agibp, offset, - offset + sizeof(xfs_agino_t) - 1); - return 0; -} - -/* - * This is called when the inode's link count has gone to 0 or we are creating - * a tmpfile via O_TMPFILE. The inode @ip must have nlink == 0. - * - * We place the on-disk inode on a list in the AGI. It will be pulled from this - * list when the inode is freed. - */ -static int -iunlink( - struct xfs_trans *tp, - struct xfs_inode *ip) -{ - struct xfs_mount *mp = tp->t_mountp; - struct xfs_perag *pag; - struct xfs_buf *agibp; - int error; - - ASSERT(VFS_I(ip)->i_nlink == 0); - ASSERT(VFS_I(ip)->i_mode != 0); - - pag = libxfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); - - /* Get the agi buffer first. It ensures lock ordering on the list. */ - error = -libxfs_read_agi(pag, tp, 0, &agibp); - if (error) - goto out; - - error = iunlink_insert_inode(tp, pag, agibp, ip); -out: - libxfs_perag_put(pag); - return error; -} - static int create_unlinked( struct xfs_mount *mp) @@ -340,7 +232,7 @@ create_unlinked( goto out_cancel; } - error = iunlink(tp, ip); + error = -libxfs_iunlink(tp, ip); if (error) { dbprintf(_("unlink inode: %s\n"), strerror(error)); goto out_rele; diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 6a057eba1..b6a95e57c 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -202,6 +202,7 @@ #define xfs_iread_extents libxfs_iread_extents #define xfs_irele libxfs_irele +#define xfs_iunlink libxfs_iunlink #define xfs_link_space_res libxfs_link_space_res #define xfs_log_calc_minimum_size libxfs_log_calc_minimum_size #define xfs_log_get_max_trans_res libxfs_log_get_max_trans_res -- 2.50.1