aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-07-30 01:37:08 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2018-07-30 01:37:08 -0400
commitebcbef3a61a6081ffe20b0b684f18ebbf23f1dfb (patch)
treed9b30678acfa6dc5e99944a4e7dc5fca6f09f2a9
parent1c02d502c20809a2a5f71ec16a930a61ed779b81 (diff)
xfs: pass transaction lock while setting up agresv on cyclic metadata
Pass a tranaction pointer through to all helpers that calculate the per-AG block reservation. Online repair will use this to reinitialize per-ag reservations while it still holds all the AG headers locked to the repair transaction. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
-rw-r--r--fs/xfs/libxfs/xfs_ag_resv.c13
-rw-r--r--fs/xfs/libxfs/xfs_ag_resv.h2
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c10
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.h4
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.c5
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.h3
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.c5
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.h2
-rw-r--r--fs/xfs/xfs_fsops.c2
9 files changed, 26 insertions, 20 deletions
diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c
index fecd187fcf2c..e701ebc36c06 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.c
+++ b/fs/xfs/libxfs/xfs_ag_resv.c
@@ -248,7 +248,8 @@ __xfs_ag_resv_init(
248/* Create a per-AG block reservation. */ 248/* Create a per-AG block reservation. */
249int 249int
250xfs_ag_resv_init( 250xfs_ag_resv_init(
251 struct xfs_perag *pag) 251 struct xfs_perag *pag,
252 struct xfs_trans *tp)
252{ 253{
253 struct xfs_mount *mp = pag->pag_mount; 254 struct xfs_mount *mp = pag->pag_mount;
254 xfs_agnumber_t agno = pag->pag_agno; 255 xfs_agnumber_t agno = pag->pag_agno;
@@ -260,11 +261,11 @@ xfs_ag_resv_init(
260 if (pag->pag_meta_resv.ar_asked == 0) { 261 if (pag->pag_meta_resv.ar_asked == 0) {
261 ask = used = 0; 262 ask = used = 0;
262 263
263 error = xfs_refcountbt_calc_reserves(mp, agno, &ask, &used); 264 error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, &used);
264 if (error) 265 if (error)
265 goto out; 266 goto out;
266 267
267 error = xfs_finobt_calc_reserves(mp, agno, &ask, &used); 268 error = xfs_finobt_calc_reserves(mp, tp, agno, &ask, &used);
268 if (error) 269 if (error)
269 goto out; 270 goto out;
270 271
@@ -282,7 +283,7 @@ xfs_ag_resv_init(
282 283
283 mp->m_inotbt_nores = true; 284 mp->m_inotbt_nores = true;
284 285
285 error = xfs_refcountbt_calc_reserves(mp, agno, &ask, 286 error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask,
286 &used); 287 &used);
287 if (error) 288 if (error)
288 goto out; 289 goto out;
@@ -298,7 +299,7 @@ xfs_ag_resv_init(
298 if (pag->pag_rmapbt_resv.ar_asked == 0) { 299 if (pag->pag_rmapbt_resv.ar_asked == 0) {
299 ask = used = 0; 300 ask = used = 0;
300 301
301 error = xfs_rmapbt_calc_reserves(mp, agno, &ask, &used); 302 error = xfs_rmapbt_calc_reserves(mp, tp, agno, &ask, &used);
302 if (error) 303 if (error)
303 goto out; 304 goto out;
304 305
@@ -309,7 +310,7 @@ xfs_ag_resv_init(
309 310
310#ifdef DEBUG 311#ifdef DEBUG
311 /* need to read in the AGF for the ASSERT below to work */ 312 /* need to read in the AGF for the ASSERT below to work */
312 error = xfs_alloc_pagf_init(pag->pag_mount, NULL, pag->pag_agno, 0); 313 error = xfs_alloc_pagf_init(pag->pag_mount, tp, pag->pag_agno, 0);
313 if (error) 314 if (error)
314 return error; 315 return error;
315 316
diff --git a/fs/xfs/libxfs/xfs_ag_resv.h b/fs/xfs/libxfs/xfs_ag_resv.h
index dc953fc84b2f..c0352edc8e41 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.h
+++ b/fs/xfs/libxfs/xfs_ag_resv.h
@@ -7,7 +7,7 @@
7#define __XFS_AG_RESV_H__ 7#define __XFS_AG_RESV_H__
8 8
9int xfs_ag_resv_free(struct xfs_perag *pag); 9int xfs_ag_resv_free(struct xfs_perag *pag);
10int xfs_ag_resv_init(struct xfs_perag *pag); 10int xfs_ag_resv_init(struct xfs_perag *pag, struct xfs_trans *tp);
11 11
12bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type); 12bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type);
13xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag, 13xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag,
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index 735a33252eb2..86c50208a143 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -552,6 +552,7 @@ xfs_inobt_max_size(
552static int 552static int
553xfs_inobt_count_blocks( 553xfs_inobt_count_blocks(
554 struct xfs_mount *mp, 554 struct xfs_mount *mp,
555 struct xfs_trans *tp,
555 xfs_agnumber_t agno, 556 xfs_agnumber_t agno,
556 xfs_btnum_t btnum, 557 xfs_btnum_t btnum,
557 xfs_extlen_t *tree_blocks) 558 xfs_extlen_t *tree_blocks)
@@ -560,14 +561,14 @@ xfs_inobt_count_blocks(
560 struct xfs_btree_cur *cur; 561 struct xfs_btree_cur *cur;
561 int error; 562 int error;
562 563
563 error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); 564 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
564 if (error) 565 if (error)
565 return error; 566 return error;
566 567
567 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); 568 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum);
568 error = xfs_btree_count_blocks(cur, tree_blocks); 569 error = xfs_btree_count_blocks(cur, tree_blocks);
569 xfs_btree_del_cursor(cur, error); 570 xfs_btree_del_cursor(cur, error);
570 xfs_buf_relse(agbp); 571 xfs_trans_brelse(tp, agbp);
571 572
572 return error; 573 return error;
573} 574}
@@ -578,6 +579,7 @@ xfs_inobt_count_blocks(
578int 579int
579xfs_finobt_calc_reserves( 580xfs_finobt_calc_reserves(
580 struct xfs_mount *mp, 581 struct xfs_mount *mp,
582 struct xfs_trans *tp,
581 xfs_agnumber_t agno, 583 xfs_agnumber_t agno,
582 xfs_extlen_t *ask, 584 xfs_extlen_t *ask,
583 xfs_extlen_t *used) 585 xfs_extlen_t *used)
@@ -588,7 +590,7 @@ xfs_finobt_calc_reserves(
588 if (!xfs_sb_version_hasfinobt(&mp->m_sb)) 590 if (!xfs_sb_version_hasfinobt(&mp->m_sb))
589 return 0; 591 return 0;
590 592
591 error = xfs_inobt_count_blocks(mp, agno, XFS_BTNUM_FINO, &tree_len); 593 error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len);
592 if (error) 594 if (error)
593 return error; 595 return error;
594 596
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h
index bf8f0c405e7d..ebdd0c6b8766 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.h
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.h
@@ -60,8 +60,8 @@ int xfs_inobt_rec_check_count(struct xfs_mount *,
60#define xfs_inobt_rec_check_count(mp, rec) 0 60#define xfs_inobt_rec_check_count(mp, rec) 0
61#endif /* DEBUG */ 61#endif /* DEBUG */
62 62
63int xfs_finobt_calc_reserves(struct xfs_mount *mp, xfs_agnumber_t agno, 63int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp,
64 xfs_extlen_t *ask, xfs_extlen_t *used); 64 xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used);
65extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, 65extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp,
66 unsigned long long len); 66 unsigned long long len);
67 67
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 26d2300ed865..1aaa01c97517 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -404,6 +404,7 @@ xfs_refcountbt_max_size(
404int 404int
405xfs_refcountbt_calc_reserves( 405xfs_refcountbt_calc_reserves(
406 struct xfs_mount *mp, 406 struct xfs_mount *mp,
407 struct xfs_trans *tp,
407 xfs_agnumber_t agno, 408 xfs_agnumber_t agno,
408 xfs_extlen_t *ask, 409 xfs_extlen_t *ask,
409 xfs_extlen_t *used) 410 xfs_extlen_t *used)
@@ -418,14 +419,14 @@ xfs_refcountbt_calc_reserves(
418 return 0; 419 return 0;
419 420
420 421
421 error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); 422 error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
422 if (error) 423 if (error)
423 return error; 424 return error;
424 425
425 agf = XFS_BUF_TO_AGF(agbp); 426 agf = XFS_BUF_TO_AGF(agbp);
426 agblocks = be32_to_cpu(agf->agf_length); 427 agblocks = be32_to_cpu(agf->agf_length);
427 tree_len = be32_to_cpu(agf->agf_refcount_blocks); 428 tree_len = be32_to_cpu(agf->agf_refcount_blocks);
428 xfs_buf_relse(agbp); 429 xfs_trans_brelse(tp, agbp);
429 430
430 *ask += xfs_refcountbt_max_size(mp, agblocks); 431 *ask += xfs_refcountbt_max_size(mp, agblocks);
431 *used += tree_len; 432 *used += tree_len;
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h
index 801c2c7732fd..ba416f71c824 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.h
+++ b/fs/xfs/libxfs/xfs_refcount_btree.h
@@ -55,6 +55,7 @@ extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp,
55 xfs_agblock_t agblocks); 55 xfs_agblock_t agblocks);
56 56
57extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp, 57extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp,
58 xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); 58 struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask,
59 xfs_extlen_t *used);
59 60
60#endif /* __XFS_REFCOUNT_BTREE_H__ */ 61#endif /* __XFS_REFCOUNT_BTREE_H__ */
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index 221a88ea60bb..f79cf040d745 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -554,6 +554,7 @@ xfs_rmapbt_max_size(
554int 554int
555xfs_rmapbt_calc_reserves( 555xfs_rmapbt_calc_reserves(
556 struct xfs_mount *mp, 556 struct xfs_mount *mp,
557 struct xfs_trans *tp,
557 xfs_agnumber_t agno, 558 xfs_agnumber_t agno,
558 xfs_extlen_t *ask, 559 xfs_extlen_t *ask,
559 xfs_extlen_t *used) 560 xfs_extlen_t *used)
@@ -567,14 +568,14 @@ xfs_rmapbt_calc_reserves(
567 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) 568 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
568 return 0; 569 return 0;
569 570
570 error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); 571 error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
571 if (error) 572 if (error)
572 return error; 573 return error;
573 574
574 agf = XFS_BUF_TO_AGF(agbp); 575 agf = XFS_BUF_TO_AGF(agbp);
575 agblocks = be32_to_cpu(agf->agf_length); 576 agblocks = be32_to_cpu(agf->agf_length);
576 tree_len = be32_to_cpu(agf->agf_rmap_blocks); 577 tree_len = be32_to_cpu(agf->agf_rmap_blocks);
577 xfs_buf_relse(agbp); 578 xfs_trans_brelse(tp, agbp);
578 579
579 /* Reserve 1% of the AG or enough for 1 block per record. */ 580 /* Reserve 1% of the AG or enough for 1 block per record. */
580 *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks)); 581 *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks));
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h
index 50198b6c3bb2..820d668b063d 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rmap_btree.h
@@ -51,7 +51,7 @@ extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp,
51extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, 51extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp,
52 xfs_agblock_t agblocks); 52 xfs_agblock_t agblocks);
53 53
54extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, 54extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp,
55 xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); 55 xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used);
56 56
57#endif /* __XFS_RMAP_BTREE_H__ */ 57#endif /* __XFS_RMAP_BTREE_H__ */
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 3f2bd6032cf8..7c00b8bedfe3 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -536,7 +536,7 @@ xfs_fs_reserve_ag_blocks(
536 536
537 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 537 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
538 pag = xfs_perag_get(mp, agno); 538 pag = xfs_perag_get(mp, agno);
539 err2 = xfs_ag_resv_init(pag); 539 err2 = xfs_ag_resv_init(pag, NULL);
540 xfs_perag_put(pag); 540 xfs_perag_put(pag);
541 if (err2 && !error) 541 if (err2 && !error)
542 error = err2; 542 error = err2;