diff options
-rw-r--r-- | fs/xfs/xfs_alloc.c | 82 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc_btree.c | 9 |
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; |
2431 | error0: | 2439 | error0: |
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); |
2467 | error0: | 2476 | error0: |
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 | ||
2527 | void | 2538 | void |
@@ -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 | ||