@@ -200,114 +200,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)
@@ -343,7 +235,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;
@@ -200,6 +200,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