aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_alloc.c82
-rw-r--r--fs/xfs/xfs_alloc_btree.c9
2 files changed, 53 insertions, 38 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 275b1f4f9430..84070f2e0ba4 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1662,11 +1662,13 @@ xfs_free_ag_extent(
1662 xfs_agf_t *agf; 1662 xfs_agf_t *agf;
1663 xfs_perag_t *pag; /* per allocation group data */ 1663 xfs_perag_t *pag; /* per allocation group data */
1664 1664
1665 pag = xfs_perag_get(mp, agno);
1666 pag->pagf_freeblks += len;
1667 xfs_perag_put(pag);
1668
1665 agf = XFS_BUF_TO_AGF(agbp); 1669 agf = XFS_BUF_TO_AGF(agbp);
1666 pag = &mp->m_perag[agno];
1667 be32_add_cpu(&agf->agf_freeblks, len); 1670 be32_add_cpu(&agf->agf_freeblks, len);
1668 xfs_trans_agblocks_delta(tp, len); 1671 xfs_trans_agblocks_delta(tp, len);
1669 pag->pagf_freeblks += len;
1670 XFS_WANT_CORRUPTED_GOTO( 1672 XFS_WANT_CORRUPTED_GOTO(
1671 be32_to_cpu(agf->agf_freeblks) <= 1673 be32_to_cpu(agf->agf_freeblks) <=
1672 be32_to_cpu(agf->agf_length), 1674 be32_to_cpu(agf->agf_length),
@@ -1969,10 +1971,12 @@ xfs_alloc_get_freelist(
1969 xfs_trans_brelse(tp, agflbp); 1971 xfs_trans_brelse(tp, agflbp);
1970 if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) 1972 if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
1971 agf->agf_flfirst = 0; 1973 agf->agf_flfirst = 0;
1972 pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; 1974
1975 pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
1973 be32_add_cpu(&agf->agf_flcount, -1); 1976 be32_add_cpu(&agf->agf_flcount, -1);
1974 xfs_trans_agflist_delta(tp, -1); 1977 xfs_trans_agflist_delta(tp, -1);
1975 pag->pagf_flcount--; 1978 pag->pagf_flcount--;
1979 xfs_perag_put(pag);
1976 1980
1977 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; 1981 logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
1978 if (btreeblk) { 1982 if (btreeblk) {
@@ -2078,7 +2082,8 @@ xfs_alloc_put_freelist(
2078 be32_add_cpu(&agf->agf_fllast, 1); 2082 be32_add_cpu(&agf->agf_fllast, 1);
2079 if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) 2083 if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
2080 agf->agf_fllast = 0; 2084 agf->agf_fllast = 0;
2081 pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; 2085
2086 pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
2082 be32_add_cpu(&agf->agf_flcount, 1); 2087 be32_add_cpu(&agf->agf_flcount, 1);
2083 xfs_trans_agflist_delta(tp, 1); 2088 xfs_trans_agflist_delta(tp, 1);
2084 pag->pagf_flcount++; 2089 pag->pagf_flcount++;
@@ -2089,6 +2094,7 @@ xfs_alloc_put_freelist(
2089 pag->pagf_btreeblks--; 2094 pag->pagf_btreeblks--;
2090 logflags |= XFS_AGF_BTREEBLKS; 2095 logflags |= XFS_AGF_BTREEBLKS;
2091 } 2096 }
2097 xfs_perag_put(pag);
2092 2098
2093 xfs_alloc_log_agf(tp, agbp, logflags); 2099 xfs_alloc_log_agf(tp, agbp, logflags);
2094 2100
@@ -2152,7 +2158,6 @@ xfs_read_agf(
2152 xfs_trans_brelse(tp, *bpp); 2158 xfs_trans_brelse(tp, *bpp);
2153 return XFS_ERROR(EFSCORRUPTED); 2159 return XFS_ERROR(EFSCORRUPTED);
2154 } 2160 }
2155
2156 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); 2161 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF);
2157 return 0; 2162 return 0;
2158} 2163}
@@ -2184,7 +2189,7 @@ xfs_alloc_read_agf(
2184 ASSERT(!XFS_BUF_GETERROR(*bpp)); 2189 ASSERT(!XFS_BUF_GETERROR(*bpp));
2185 2190
2186 agf = XFS_BUF_TO_AGF(*bpp); 2191 agf = XFS_BUF_TO_AGF(*bpp);
2187 pag = &mp->m_perag[agno]; 2192 pag = xfs_perag_get(mp, agno);
2188 if (!pag->pagf_init) { 2193 if (!pag->pagf_init) {
2189 pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); 2194 pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
2190 pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); 2195 pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
@@ -2211,6 +2216,7 @@ xfs_alloc_read_agf(
2211 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); 2216 be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
2212 } 2217 }
2213#endif 2218#endif
2219 xfs_perag_put(pag);
2214 return 0; 2220 return 0;
2215} 2221}
2216 2222
@@ -2271,7 +2277,7 @@ xfs_alloc_vextent(
2271 */ 2277 */
2272 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno); 2278 args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
2273 down_read(&mp->m_peraglock); 2279 down_read(&mp->m_peraglock);
2274 args->pag = &mp->m_perag[args->agno]; 2280 args->pag = xfs_perag_get(mp, args->agno);
2275 args->minleft = 0; 2281 args->minleft = 0;
2276 error = xfs_alloc_fix_freelist(args, 0); 2282 error = xfs_alloc_fix_freelist(args, 0);
2277 args->minleft = minleft; 2283 args->minleft = minleft;
@@ -2341,7 +2347,7 @@ xfs_alloc_vextent(
2341 */ 2347 */
2342 down_read(&mp->m_peraglock); 2348 down_read(&mp->m_peraglock);
2343 for (;;) { 2349 for (;;) {
2344 args->pag = &mp->m_perag[args->agno]; 2350 args->pag = xfs_perag_get(mp, args->agno);
2345 if (no_min) args->minleft = 0; 2351 if (no_min) args->minleft = 0;
2346 error = xfs_alloc_fix_freelist(args, flags); 2352 error = xfs_alloc_fix_freelist(args, flags);
2347 args->minleft = minleft; 2353 args->minleft = minleft;
@@ -2400,6 +2406,7 @@ xfs_alloc_vextent(
2400 } 2406 }
2401 } 2407 }
2402 } 2408 }
2409 xfs_perag_put(args->pag);
2403 } 2410 }
2404 up_read(&mp->m_peraglock); 2411 up_read(&mp->m_peraglock);
2405 if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) { 2412 if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) {
@@ -2427,8 +2434,10 @@ xfs_alloc_vextent(
2427 args->len); 2434 args->len);
2428#endif 2435#endif
2429 } 2436 }
2437 xfs_perag_put(args->pag);
2430 return 0; 2438 return 0;
2431error0: 2439error0:
2440 xfs_perag_put(args->pag);
2432 up_read(&mp->m_peraglock); 2441 up_read(&mp->m_peraglock);
2433 return error; 2442 return error;
2434} 2443}
@@ -2455,7 +2464,7 @@ xfs_free_extent(
2455 ASSERT(args.agno < args.mp->m_sb.sb_agcount); 2464 ASSERT(args.agno < args.mp->m_sb.sb_agcount);
2456 args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); 2465 args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno);
2457 down_read(&args.mp->m_peraglock); 2466 down_read(&args.mp->m_peraglock);
2458 args.pag = &args.mp->m_perag[args.agno]; 2467 args.pag = xfs_perag_get(args.mp, args.agno);
2459 if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) 2468 if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
2460 goto error0; 2469 goto error0;
2461#ifdef DEBUG 2470#ifdef DEBUG
@@ -2465,6 +2474,7 @@ xfs_free_extent(
2465#endif 2474#endif
2466 error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); 2475 error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0);
2467error0: 2476error0:
2477 xfs_perag_put(args.pag);
2468 up_read(&args.mp->m_peraglock); 2478 up_read(&args.mp->m_peraglock);
2469 return error; 2479 return error;
2470} 2480}
@@ -2486,15 +2496,15 @@ xfs_alloc_mark_busy(xfs_trans_t *tp,
2486 xfs_agblock_t bno, 2496 xfs_agblock_t bno,
2487 xfs_extlen_t len) 2497 xfs_extlen_t len)
2488{ 2498{
2489 xfs_mount_t *mp;
2490 xfs_perag_busy_t *bsy; 2499 xfs_perag_busy_t *bsy;
2500 struct xfs_perag *pag;
2491 int n; 2501 int n;
2492 2502
2493 mp = tp->t_mountp; 2503 pag = xfs_perag_get(tp->t_mountp, agno);
2494 spin_lock(&mp->m_perag[agno].pagb_lock); 2504 spin_lock(&pag->pagb_lock);
2495 2505
2496 /* search pagb_list for an open slot */ 2506 /* search pagb_list for an open slot */
2497 for (bsy = mp->m_perag[agno].pagb_list, n = 0; 2507 for (bsy = pag->pagb_list, n = 0;
2498 n < XFS_PAGB_NUM_SLOTS; 2508 n < XFS_PAGB_NUM_SLOTS;
2499 bsy++, n++) { 2509 bsy++, n++) {
2500 if (bsy->busy_tp == NULL) { 2510 if (bsy->busy_tp == NULL) {
@@ -2502,11 +2512,11 @@ xfs_alloc_mark_busy(xfs_trans_t *tp,
2502 } 2512 }
2503 } 2513 }
2504 2514
2505 trace_xfs_alloc_busy(mp, agno, bno, len, n); 2515 trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len, n);
2506 2516
2507 if (n < XFS_PAGB_NUM_SLOTS) { 2517 if (n < XFS_PAGB_NUM_SLOTS) {
2508 bsy = &mp->m_perag[agno].pagb_list[n]; 2518 bsy = &pag->pagb_list[n];
2509 mp->m_perag[agno].pagb_count++; 2519 pag->pagb_count++;
2510 bsy->busy_start = bno; 2520 bsy->busy_start = bno;
2511 bsy->busy_length = len; 2521 bsy->busy_length = len;
2512 bsy->busy_tp = tp; 2522 bsy->busy_tp = tp;
@@ -2521,7 +2531,8 @@ xfs_alloc_mark_busy(xfs_trans_t *tp,
2521 xfs_trans_set_sync(tp); 2531 xfs_trans_set_sync(tp);
2522 } 2532 }
2523 2533
2524 spin_unlock(&mp->m_perag[agno].pagb_lock); 2534 spin_unlock(&pag->pagb_lock);
2535 xfs_perag_put(pag);
2525} 2536}
2526 2537
2527void 2538void
@@ -2529,24 +2540,23 @@ xfs_alloc_clear_busy(xfs_trans_t *tp,
2529 xfs_agnumber_t agno, 2540 xfs_agnumber_t agno,
2530 int idx) 2541 int idx)
2531{ 2542{
2532 xfs_mount_t *mp; 2543 struct xfs_perag *pag;
2533 xfs_perag_busy_t *list; 2544 xfs_perag_busy_t *list;
2534 2545
2535 mp = tp->t_mountp;
2536
2537 spin_lock(&mp->m_perag[agno].pagb_lock);
2538 list = mp->m_perag[agno].pagb_list;
2539
2540 ASSERT(idx < XFS_PAGB_NUM_SLOTS); 2546 ASSERT(idx < XFS_PAGB_NUM_SLOTS);
2547 pag = xfs_perag_get(tp->t_mountp, agno);
2548 spin_lock(&pag->pagb_lock);
2549 list = pag->pagb_list;
2541 2550
2542 trace_xfs_alloc_unbusy(mp, agno, idx, list[idx].busy_tp == tp); 2551 trace_xfs_alloc_unbusy(tp->t_mountp, agno, idx, list[idx].busy_tp == tp);
2543 2552
2544 if (list[idx].busy_tp == tp) { 2553 if (list[idx].busy_tp == tp) {
2545 list[idx].busy_tp = NULL; 2554 list[idx].busy_tp = NULL;
2546 mp->m_perag[agno].pagb_count--; 2555 pag->pagb_count--;
2547 } 2556 }
2548 2557
2549 spin_unlock(&mp->m_perag[agno].pagb_lock); 2558 spin_unlock(&pag->pagb_lock);
2559 xfs_perag_put(pag);
2550} 2560}
2551 2561
2552 2562
@@ -2560,17 +2570,15 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
2560 xfs_agblock_t bno, 2570 xfs_agblock_t bno,
2561 xfs_extlen_t len) 2571 xfs_extlen_t len)
2562{ 2572{
2563 xfs_mount_t *mp; 2573 struct xfs_perag *pag;
2564 xfs_perag_busy_t *bsy; 2574 xfs_perag_busy_t *bsy;
2565 xfs_agblock_t uend, bend; 2575 xfs_agblock_t uend, bend;
2566 xfs_lsn_t lsn = 0; 2576 xfs_lsn_t lsn = 0;
2567 int cnt; 2577 int cnt;
2568 2578
2569 mp = tp->t_mountp; 2579 pag = xfs_perag_get(tp->t_mountp, agno);
2570 2580 spin_lock(&pag->pagb_lock);
2571 spin_lock(&mp->m_perag[agno].pagb_lock); 2581 cnt = pag->pagb_count;
2572
2573 uend = bno + len - 1;
2574 2582
2575 /* 2583 /*
2576 * search pagb_list for this slot, skipping open slots. We have to 2584 * search pagb_list for this slot, skipping open slots. We have to
@@ -2578,8 +2586,9 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
2578 * we have to get the most recent LSN for the log force to push out 2586 * we have to get the most recent LSN for the log force to push out
2579 * all the transactions that span the range. 2587 * all the transactions that span the range.
2580 */ 2588 */
2581 for (cnt = 0; cnt < mp->m_perag[agno].pagb_count; cnt++) { 2589 uend = bno + len - 1;
2582 bsy = &mp->m_perag[agno].pagb_list[cnt]; 2590 for (cnt = 0; cnt < pag->pagb_count; cnt++) {
2591 bsy = &pag->pagb_list[cnt];
2583 if (!bsy->busy_tp) 2592 if (!bsy->busy_tp)
2584 continue; 2593 continue;
2585 2594
@@ -2591,7 +2600,8 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
2591 if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0) 2600 if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0)
2592 lsn = bsy->busy_tp->t_commit_lsn; 2601 lsn = bsy->busy_tp->t_commit_lsn;
2593 } 2602 }
2594 spin_unlock(&mp->m_perag[agno].pagb_lock); 2603 spin_unlock(&pag->pagb_lock);
2604 xfs_perag_put(pag);
2595 trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn); 2605 trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn);
2596 2606
2597 /* 2607 /*
@@ -2599,5 +2609,5 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
2599 * transaction that freed the block 2609 * transaction that freed the block
2600 */ 2610 */
2601 if (lsn) 2611 if (lsn)
2602 xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC); 2612 xfs_log_force(tp->t_mountp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC);
2603} 2613}
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index adbd9141aea1..b726e10d2c1c 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -61,12 +61,14 @@ xfs_allocbt_set_root(
61 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 61 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
62 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); 62 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
63 int btnum = cur->bc_btnum; 63 int btnum = cur->bc_btnum;
64 struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno);
64 65
65 ASSERT(ptr->s != 0); 66 ASSERT(ptr->s != 0);
66 67
67 agf->agf_roots[btnum] = ptr->s; 68 agf->agf_roots[btnum] = ptr->s;
68 be32_add_cpu(&agf->agf_levels[btnum], inc); 69 be32_add_cpu(&agf->agf_levels[btnum], inc);
69 cur->bc_mp->m_perag[seqno].pagf_levels[btnum] += inc; 70 pag->pagf_levels[btnum] += inc;
71 xfs_perag_put(pag);
70 72
71 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); 73 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
72} 74}
@@ -150,6 +152,7 @@ xfs_allocbt_update_lastrec(
150{ 152{
151 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 153 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
152 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); 154 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
155 struct xfs_perag *pag;
153 __be32 len; 156 __be32 len;
154 int numrecs; 157 int numrecs;
155 158
@@ -193,7 +196,9 @@ xfs_allocbt_update_lastrec(
193 } 196 }
194 197
195 agf->agf_longest = len; 198 agf->agf_longest = len;
196 cur->bc_mp->m_perag[seqno].pagf_longest = be32_to_cpu(len); 199 pag = xfs_perag_get(cur->bc_mp, seqno);
200 pag->pagf_longest = be32_to_cpu(len);
201 xfs_perag_put(pag);
197 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST); 202 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST);
198} 203}
199 204