aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-05-26 15:16:03 +0200
committerCarlos Maiolino <cem@kernel.org>2023-06-09 10:27:28 +0200
commit32debad7cda40bfa9ecf094cee240f4ec12fb3f2 (patch)
treedeb76b5ac0f02a0ad63e5ecbf1947f456c3258a1
parent36100197818eee4e90db5389c3fd12ce63043382 (diff)
downloadxfsprogs-dev-32debad7cda40bfa9ecf094cee240f4ec12fb3f2.tar.gz
xfs: give xfs_bmap_intent its own perag reference
Source kernel commit: 774a99b47b588bf0bd9f65d3b241d5bba0b2fcb0 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> Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r--libxfs/defer_item.c24
-rw-r--r--libxfs/xfs_bmap.c1
-rw-r--r--libxfs/xfs_bmap.h4
3 files changed, 29 insertions, 0 deletions
diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c
index 285dc9a35d..3dbcf11634 100644
--- a/libxfs/defer_item.c
+++ b/libxfs/defer_item.c
@@ -390,6 +390,26 @@ xfs_bmap_update_create_done(
return NULL;
}
+/* 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(
@@ -407,6 +427,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;
}
@@ -426,6 +448,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);
}
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 76591d0776..4a7f3d280e 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -6068,6 +6068,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;
}
diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h
index dd08361ca5..e5a492027a 100644
--- a/libxfs/xfs_bmap.h
+++ b/libxfs/xfs_bmap.h
@@ -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);