Commit e5f1a514 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: use xfs_defer_finish_one to finish recovered work items



Get rid of the open-coded calls to xfs_defer_finish_one.  This also
means that the recovery transaction takes care of cleaning up the dfp,
and we have solved (I hope) all the ownership issues in recovery.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent a51489e1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ xfs_defer_relog(
 * Log an intent-done item for the first pending intent, and finish the work
 * items.
 */
static int
int
xfs_defer_finish_one(
	struct xfs_trans		*tp,
	struct xfs_defer_pending	*dfp)
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type,
		struct list_head *h);
int xfs_defer_finish_noroll(struct xfs_trans **tp);
int xfs_defer_finish(struct xfs_trans **tp);
int xfs_defer_finish_one(struct xfs_trans *tp, struct xfs_defer_pending *dfp);
void xfs_defer_cancel(struct xfs_trans *);
void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp);

+1 −1
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ xlog_recover_resv(const struct xfs_trans_res *r)

void xlog_recover_intent_item(struct xlog *log, struct xfs_log_item *lip,
		xfs_lsn_t lsn, unsigned int dfp_type);
void xlog_recover_transfer_intent(struct xfs_trans *tp,
int xlog_recover_finish_intent(struct xfs_trans *tp,
		struct xfs_defer_pending *dfp);

#endif	/* __XFS_LOG_RECOVER_H__ */
+1 −19
Original line number Diff line number Diff line
@@ -620,7 +620,6 @@ xfs_attri_item_recover(
	struct xfs_attri_log_nameval	*nv = attrip->attri_nameval;
	int				error;
	int				total;
	struct xfs_attrd_log_item	*done_item = NULL;

	/*
	 * First check the validity of the attr described by the ATTRI.  If any
@@ -645,27 +644,10 @@ xfs_attri_item_recover(
		return error;
	args->trans = tp;

	done_item = xfs_trans_get_attrd(tp, attrip);
	xlog_recover_transfer_intent(tp, dfp);

	xfs_ilock(ip, XFS_ILOCK_EXCL);
	xfs_trans_ijoin(tp, ip, 0);

	error = xfs_xattri_finish_update(attr, done_item);
	if (error == -EAGAIN) {
		/*
		 * There's more work to do, so add the intent item to this
		 * transaction so that we can continue it later.
		 */
		xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_ATTR, &attr->xattri_list);
		error = xfs_defer_ops_capture_and_commit(tp, capture_list);
		if (error)
			goto out_unlock;

		xfs_iunlock(ip, XFS_ILOCK_EXCL);
		xfs_irele(ip);
		return 0;
	}
	error = xlog_recover_finish_intent(tp, dfp);
	if (error == -EFSCORRUPTED)
		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
				&attrip->attri_format,
+7 −17
Original line number Diff line number Diff line
@@ -497,6 +497,7 @@ xfs_bui_recover_work(
	bi->bi_bmap.br_blockcount = map->me_len;
	bi->bi_bmap.br_state = (map->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
			XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
	xfs_bmap_update_get_group(mp, bi);

	xfs_defer_add_item(dfp, &bi->bi_list);
	return bi;
@@ -518,8 +519,7 @@ xfs_bui_item_recover(
	struct xfs_inode		*ip = NULL;
	struct xfs_mount		*mp = lip->li_log->l_mp;
	struct xfs_map_extent		*map;
	struct xfs_bud_log_item		*budp;
	struct xfs_bmap_intent		*fake;
	struct xfs_bmap_intent		*work;
	int				iext_delta;
	int				error = 0;

@@ -530,7 +530,7 @@ xfs_bui_item_recover(
	}

	map = &buip->bui_format.bui_extents[0];
	fake = xfs_bui_recover_work(mp, dfp, map);
	work = xfs_bui_recover_work(mp, dfp, map);

	error = xlog_recover_iget(mp, map->me_owner, &ip);
	if (error)
@@ -543,39 +543,29 @@ xfs_bui_item_recover(
	if (error)
		goto err_rele;

	budp = xfs_trans_get_bud(tp, buip);
	xlog_recover_transfer_intent(tp, dfp);

	xfs_ilock(ip, XFS_ILOCK_EXCL);
	xfs_trans_ijoin(tp, ip, 0);

	if (fake->bi_type == XFS_BMAP_MAP)
	if (work->bi_type == XFS_BMAP_MAP)
		iext_delta = XFS_IEXT_ADD_NOSPLIT_CNT;
	else
		iext_delta = XFS_IEXT_PUNCH_HOLE_CNT;

	error = xfs_iext_count_may_overflow(ip, fake->bi_whichfork, iext_delta);
	error = xfs_iext_count_may_overflow(ip, work->bi_whichfork, iext_delta);
	if (error == -EFBIG)
		error = xfs_iext_count_upgrade(tp, ip, iext_delta);
	if (error)
		goto err_cancel;

	fake->bi_owner = ip;
	work->bi_owner = ip;

	xfs_bmap_update_get_group(mp, fake);
	error = xfs_trans_log_finish_bmap_update(tp, budp, fake);
	error = xlog_recover_finish_intent(tp, dfp);
	if (error == -EFSCORRUPTED)
		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
				&buip->bui_format, sizeof(buip->bui_format));
	xfs_bmap_update_put_group(fake);
	if (error)
		goto err_cancel;

	if (fake->bi_bmap.br_blockcount > 0) {
		ASSERT(fake->bi_type == XFS_BMAP_UNMAP);
		xfs_bmap_unmap_extent(tp, ip, &fake->bi_bmap);
	}

	/*
	 * Commit transaction, which frees the transaction and saves the inode
	 * for later replay activities.
Loading