]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_db: port the iunlink command to use the libxfs iunlink function
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:21:37 +0000 (14:21 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 31 Jul 2024 01:46:43 +0000 (18:46 -0700)
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 <djwong@kernel.org>
db/iunlink.c
libxfs/libxfs_api_defs.h

index b3356d73b346d611dc63dce8fd9547dd2d1d98e9..a2f44190346a4e111831cf81dbabbc3d347d69c6 100644 (file)
@@ -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;
index 6a057eba1e38b84e3d09b45bd1836f29c0ecb636..b6a95e57cca0283eec9a962ae62d7972cf830692 100644 (file)
 
 #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