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

xfs: give xfs_bmap_intent its own perag reference



Give the xfs_bmap_intent an active reference to the perag structure
data.  This reference will be used to enable scrub intent draining
functionality in subsequent patches.  Later, shrink will use these
passive references to know if an AG is quiesced or not.

The reason why we take a passive ref for a file mapping operation is
simple: we're committing to some sort of action involving space in an
AG, so we want to indicate our interest in that AG.  The space is
already allocated, so we need to be able to operate on AGs that are
offline or being shrunk.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 03786f0a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6075,6 +6075,7 @@ __xfs_bmap_add(
	bi->bi_whichfork = whichfork;
	bi->bi_bmap = *bmap;

	xfs_bmap_update_get_group(tp->t_mountp, bi);
	xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list);
	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -238,9 +238,13 @@ struct xfs_bmap_intent {
	enum xfs_bmap_intent_type		bi_type;
	int					bi_whichfork;
	struct xfs_inode			*bi_owner;
	struct xfs_perag			*bi_pag;
	struct xfs_bmbt_irec			bi_bmap;
};

void xfs_bmap_update_get_group(struct xfs_mount *mp,
		struct xfs_bmap_intent *bi);

int	xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
void	xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
		struct xfs_bmbt_irec *imap);
+28 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "xfs_error.h"
#include "xfs_log_priv.h"
#include "xfs_log_recover.h"
#include "xfs_ag.h"

struct kmem_cache	*xfs_bui_cache;
struct kmem_cache	*xfs_bud_cache;
@@ -363,6 +364,26 @@ xfs_bmap_update_create_done(
	return &xfs_trans_get_bud(tp, BUI_ITEM(intent))->bud_item;
}

/* Take a passive ref to the AG containing the space we're mapping. */
void
xfs_bmap_update_get_group(
	struct xfs_mount	*mp,
	struct xfs_bmap_intent	*bi)
{
	xfs_agnumber_t		agno;

	agno = XFS_FSB_TO_AGNO(mp, bi->bi_bmap.br_startblock);
	bi->bi_pag = xfs_perag_get(mp, agno);
}

/* Release a passive AG ref after finishing mapping work. */
static inline void
xfs_bmap_update_put_group(
	struct xfs_bmap_intent	*bi)
{
	xfs_perag_put(bi->bi_pag);
}

/* Process a deferred rmap update. */
STATIC int
xfs_bmap_update_finish_item(
@@ -381,6 +402,8 @@ xfs_bmap_update_finish_item(
		ASSERT(bi->bi_type == XFS_BMAP_UNMAP);
		return -EAGAIN;
	}

	xfs_bmap_update_put_group(bi);
	kmem_cache_free(xfs_bmap_intent_cache, bi);
	return error;
}
@@ -393,7 +416,7 @@ xfs_bmap_update_abort_intent(
	xfs_bui_release(BUI_ITEM(intent));
}

/* Cancel a deferred rmap update. */
/* Cancel a deferred bmap update. */
STATIC void
xfs_bmap_update_cancel_item(
	struct list_head		*item)
@@ -401,6 +424,8 @@ xfs_bmap_update_cancel_item(
	struct xfs_bmap_intent		*bi;

	bi = container_of(item, struct xfs_bmap_intent, bi_list);

	xfs_bmap_update_put_group(bi);
	kmem_cache_free(xfs_bmap_intent_cache, bi);
}

@@ -509,10 +534,12 @@ xfs_bui_item_recover(
	fake.bi_bmap.br_state = (map->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
			XFS_EXT_UNWRITTEN : XFS_EXT_NORM;

	xfs_bmap_update_get_group(mp, &fake);
	error = xfs_trans_log_finish_bmap_update(tp, budp, &fake);
	if (error == -EFSCORRUPTED)
		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, map,
				sizeof(*map));
	xfs_bmap_update_put_group(&fake);
	if (error)
		goto err_cancel;