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: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
parent
03786f0afb
commit
774a99b47b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue