aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_ag_resv.c4
-rw-r--r--fs/xfs/libxfs/xfs_ag_resv.h31
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c18
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.c4
-rw-r--r--fs/xfs/xfs_mount.h1
5 files changed, 46 insertions, 12 deletions
diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c
index 0ca2e680034a..03885a968de8 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.c
+++ b/fs/xfs/libxfs/xfs_ag_resv.c
@@ -326,6 +326,8 @@ xfs_ag_resv_alloc_extent(
326 trace_xfs_ag_resv_alloc_extent(pag, type, args->len); 326 trace_xfs_ag_resv_alloc_extent(pag, type, args->len);
327 327
328 switch (type) { 328 switch (type) {
329 case XFS_AG_RESV_AGFL:
330 return;
329 case XFS_AG_RESV_METADATA: 331 case XFS_AG_RESV_METADATA:
330 case XFS_AG_RESV_RMAPBT: 332 case XFS_AG_RESV_RMAPBT:
331 resv = xfs_perag_resv(pag, type); 333 resv = xfs_perag_resv(pag, type);
@@ -366,6 +368,8 @@ xfs_ag_resv_free_extent(
366 trace_xfs_ag_resv_free_extent(pag, type, len); 368 trace_xfs_ag_resv_free_extent(pag, type, len);
367 369
368 switch (type) { 370 switch (type) {
371 case XFS_AG_RESV_AGFL:
372 return;
369 case XFS_AG_RESV_METADATA: 373 case XFS_AG_RESV_METADATA:
370 case XFS_AG_RESV_RMAPBT: 374 case XFS_AG_RESV_RMAPBT:
371 resv = xfs_perag_resv(pag, type); 375 resv = xfs_perag_resv(pag, type);
diff --git a/fs/xfs/libxfs/xfs_ag_resv.h b/fs/xfs/libxfs/xfs_ag_resv.h
index 8d6c687deef3..938f2f96c5e8 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.h
+++ b/fs/xfs/libxfs/xfs_ag_resv.h
@@ -32,4 +32,35 @@ void xfs_ag_resv_alloc_extent(struct xfs_perag *pag, enum xfs_ag_resv_type type,
32void xfs_ag_resv_free_extent(struct xfs_perag *pag, enum xfs_ag_resv_type type, 32void xfs_ag_resv_free_extent(struct xfs_perag *pag, enum xfs_ag_resv_type type,
33 struct xfs_trans *tp, xfs_extlen_t len); 33 struct xfs_trans *tp, xfs_extlen_t len);
34 34
35/*
36 * RMAPBT reservation accounting wrappers. Since rmapbt blocks are sourced from
37 * the AGFL, they are allocated one at a time and the reservation updates don't
38 * require a transaction.
39 */
40static inline void
41xfs_ag_resv_rmapbt_alloc(
42 struct xfs_mount *mp,
43 xfs_agnumber_t agno)
44{
45 struct xfs_alloc_arg args = {0};
46 struct xfs_perag *pag;
47
48 args.len = 1;
49 pag = xfs_perag_get(mp, agno);
50 xfs_ag_resv_alloc_extent(pag, XFS_AG_RESV_RMAPBT, &args);
51 xfs_perag_put(pag);
52}
53
54static inline void
55xfs_ag_resv_rmapbt_free(
56 struct xfs_mount *mp,
57 xfs_agnumber_t agno)
58{
59 struct xfs_perag *pag;
60
61 pag = xfs_perag_get(mp, agno);
62 xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);
63 xfs_perag_put(pag);
64}
65
35#endif /* __XFS_AG_RESV_H__ */ 66#endif /* __XFS_AG_RESV_H__ */
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 1dc244d15a75..3db90b707fb2 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -728,7 +728,7 @@ xfs_alloc_ag_vextent(
728 728
729 ASSERT(args->len >= args->minlen); 729 ASSERT(args->len >= args->minlen);
730 ASSERT(args->len <= args->maxlen); 730 ASSERT(args->len <= args->maxlen);
731 ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_RMAPBT); 731 ASSERT(!args->wasfromfl || args->resv != XFS_AG_RESV_AGFL);
732 ASSERT(args->agbno % args->alignment == 0); 732 ASSERT(args->agbno % args->alignment == 0);
733 733
734 /* if not file data, insert new block into the reverse map btree */ 734 /* if not file data, insert new block into the reverse map btree */
@@ -1581,7 +1581,6 @@ xfs_alloc_ag_vextent_small(
1581 int *stat) /* status: 0-freelist, 1-normal/none */ 1581 int *stat) /* status: 0-freelist, 1-normal/none */
1582{ 1582{
1583 struct xfs_owner_info oinfo; 1583 struct xfs_owner_info oinfo;
1584 struct xfs_perag *pag;
1585 int error; 1584 int error;
1586 xfs_agblock_t fbno; 1585 xfs_agblock_t fbno;
1587 xfs_extlen_t flen; 1586 xfs_extlen_t flen;
@@ -1600,7 +1599,7 @@ xfs_alloc_ag_vextent_small(
1600 * freelist. 1599 * freelist.
1601 */ 1600 */
1602 else if (args->minlen == 1 && args->alignment == 1 && 1601 else if (args->minlen == 1 && args->alignment == 1 &&
1603 args->resv != XFS_AG_RESV_RMAPBT && 1602 args->resv != XFS_AG_RESV_AGFL &&
1604 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) 1603 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
1605 > args->minleft)) { 1604 > args->minleft)) {
1606 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0); 1605 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
@@ -1633,18 +1632,13 @@ xfs_alloc_ag_vextent_small(
1633 /* 1632 /*
1634 * If we're feeding an AGFL block to something that 1633 * If we're feeding an AGFL block to something that
1635 * doesn't live in the free space, we need to clear 1634 * doesn't live in the free space, we need to clear
1636 * out the OWN_AG rmap and add the block back to 1635 * out the OWN_AG rmap.
1637 * the RMAPBT per-AG reservation.
1638 */ 1636 */
1639 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); 1637 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
1640 error = xfs_rmap_free(args->tp, args->agbp, args->agno, 1638 error = xfs_rmap_free(args->tp, args->agbp, args->agno,
1641 fbno, 1, &oinfo); 1639 fbno, 1, &oinfo);
1642 if (error) 1640 if (error)
1643 goto error0; 1641 goto error0;
1644 pag = xfs_perag_get(args->mp, args->agno);
1645 xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT,
1646 args->tp, 1);
1647 xfs_perag_put(pag);
1648 1642
1649 *stat = 0; 1643 *stat = 0;
1650 return 0; 1644 return 0;
@@ -2170,7 +2164,7 @@ xfs_alloc_fix_freelist(
2170 if (error) 2164 if (error)
2171 goto out_agbp_relse; 2165 goto out_agbp_relse;
2172 error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 2166 error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1,
2173 &targs.oinfo, XFS_AG_RESV_RMAPBT); 2167 &targs.oinfo, XFS_AG_RESV_AGFL);
2174 if (error) 2168 if (error)
2175 goto out_agbp_relse; 2169 goto out_agbp_relse;
2176 bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); 2170 bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
@@ -2196,7 +2190,7 @@ xfs_alloc_fix_freelist(
2196 while (pag->pagf_flcount < need) { 2190 while (pag->pagf_flcount < need) {
2197 targs.agbno = 0; 2191 targs.agbno = 0;
2198 targs.maxlen = need - pag->pagf_flcount; 2192 targs.maxlen = need - pag->pagf_flcount;
2199 targs.resv = XFS_AG_RESV_RMAPBT; 2193 targs.resv = XFS_AG_RESV_AGFL;
2200 2194
2201 /* Allocate as many blocks as possible at once. */ 2195 /* Allocate as many blocks as possible at once. */
2202 error = xfs_alloc_ag_vextent(&targs); 2196 error = xfs_alloc_ag_vextent(&targs);
@@ -2877,7 +2871,7 @@ xfs_free_extent(
2877 int error; 2871 int error;
2878 2872
2879 ASSERT(len != 0); 2873 ASSERT(len != 0);
2880 ASSERT(type != XFS_AG_RESV_RMAPBT); 2874 ASSERT(type != XFS_AG_RESV_AGFL);
2881 2875
2882 if (XFS_TEST_ERROR(false, mp, 2876 if (XFS_TEST_ERROR(false, mp,
2883 XFS_ERRTAG_FREE_EXTENT)) 2877 XFS_ERRTAG_FREE_EXTENT))
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index 738df3f9b5f2..8b0d0de1cd11 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -125,6 +125,8 @@ xfs_rmapbt_alloc_block(
125 be32_add_cpu(&agf->agf_rmap_blocks, 1); 125 be32_add_cpu(&agf->agf_rmap_blocks, 1);
126 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS); 126 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_RMAP_BLOCKS);
127 127
128 xfs_ag_resv_rmapbt_alloc(cur->bc_mp, cur->bc_private.a.agno);
129
128 *stat = 1; 130 *stat = 1;
129 return 0; 131 return 0;
130} 132}
@@ -152,6 +154,8 @@ xfs_rmapbt_free_block(
152 XFS_EXTENT_BUSY_SKIP_DISCARD); 154 XFS_EXTENT_BUSY_SKIP_DISCARD);
153 xfs_trans_agbtree_delta(cur->bc_tp, -1); 155 xfs_trans_agbtree_delta(cur->bc_tp, -1);
154 156
157 xfs_ag_resv_rmapbt_free(cur->bc_mp, cur->bc_private.a.agno);
158
155 return 0; 159 return 0;
156} 160}
157 161
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a2cf3718bea9..1808f56decaa 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -325,6 +325,7 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
325/* per-AG block reservation data structures*/ 325/* per-AG block reservation data structures*/
326enum xfs_ag_resv_type { 326enum xfs_ag_resv_type {
327 XFS_AG_RESV_NONE = 0, 327 XFS_AG_RESV_NONE = 0,
328 XFS_AG_RESV_AGFL,
328 XFS_AG_RESV_METADATA, 329 XFS_AG_RESV_METADATA,
329 XFS_AG_RESV_RMAPBT, 330 XFS_AG_RESV_RMAPBT,
330}; 331};