diff options
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
| -rw-r--r-- | fs/xfs/xfs_alloc.c | 357 |
1 files changed, 252 insertions, 105 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 94cddbfb2560..a7fbe8a99b12 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
| @@ -46,11 +46,9 @@ | |||
| 46 | #define XFSA_FIXUP_BNO_OK 1 | 46 | #define XFSA_FIXUP_BNO_OK 1 |
| 47 | #define XFSA_FIXUP_CNT_OK 2 | 47 | #define XFSA_FIXUP_CNT_OK 2 |
| 48 | 48 | ||
| 49 | STATIC void | 49 | static int |
| 50 | xfs_alloc_search_busy(xfs_trans_t *tp, | 50 | xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, |
| 51 | xfs_agnumber_t agno, | 51 | xfs_agblock_t bno, xfs_extlen_t len); |
| 52 | xfs_agblock_t bno, | ||
| 53 | xfs_extlen_t len); | ||
| 54 | 52 | ||
| 55 | /* | 53 | /* |
| 56 | * Prototypes for per-ag allocation routines | 54 | * Prototypes for per-ag allocation routines |
| @@ -540,9 +538,16 @@ xfs_alloc_ag_vextent( | |||
| 540 | be32_to_cpu(agf->agf_length)); | 538 | be32_to_cpu(agf->agf_length)); |
| 541 | xfs_alloc_log_agf(args->tp, args->agbp, | 539 | xfs_alloc_log_agf(args->tp, args->agbp, |
| 542 | XFS_AGF_FREEBLKS); | 540 | XFS_AGF_FREEBLKS); |
| 543 | /* search the busylist for these blocks */ | 541 | /* |
| 544 | xfs_alloc_search_busy(args->tp, args->agno, | 542 | * Search the busylist for these blocks and mark the |
| 545 | args->agbno, args->len); | 543 | * transaction as synchronous if blocks are found. This |
| 544 | * avoids the need to block due to a synchronous log | ||
| 545 | * force to ensure correct ordering as the synchronous | ||
| 546 | * transaction will guarantee that for us. | ||
| 547 | */ | ||
| 548 | if (xfs_alloc_busy_search(args->mp, args->agno, | ||
| 549 | args->agbno, args->len)) | ||
| 550 | xfs_trans_set_sync(args->tp); | ||
| 546 | } | 551 | } |
| 547 | if (!args->isfl) | 552 | if (!args->isfl) |
| 548 | xfs_trans_mod_sb(args->tp, | 553 | xfs_trans_mod_sb(args->tp, |
| @@ -1693,7 +1698,7 @@ xfs_free_ag_extent( | |||
| 1693 | * when the iclog commits to disk. If a busy block is allocated, | 1698 | * when the iclog commits to disk. If a busy block is allocated, |
| 1694 | * the iclog is pushed up to the LSN that freed the block. | 1699 | * the iclog is pushed up to the LSN that freed the block. |
| 1695 | */ | 1700 | */ |
| 1696 | xfs_alloc_mark_busy(tp, agno, bno, len); | 1701 | xfs_alloc_busy_insert(tp, agno, bno, len); |
| 1697 | return 0; | 1702 | return 0; |
| 1698 | 1703 | ||
| 1699 | error0: | 1704 | error0: |
| @@ -1989,14 +1994,20 @@ xfs_alloc_get_freelist( | |||
| 1989 | *bnop = bno; | 1994 | *bnop = bno; |
| 1990 | 1995 | ||
| 1991 | /* | 1996 | /* |
| 1992 | * As blocks are freed, they are added to the per-ag busy list | 1997 | * As blocks are freed, they are added to the per-ag busy list and |
| 1993 | * and remain there until the freeing transaction is committed to | 1998 | * remain there until the freeing transaction is committed to disk. |
| 1994 | * disk. Now that we have allocated blocks, this list must be | 1999 | * Now that we have allocated blocks, this list must be searched to see |
| 1995 | * searched to see if a block is being reused. If one is, then | 2000 | * if a block is being reused. If one is, then the freeing transaction |
| 1996 | * the freeing transaction must be pushed to disk NOW by forcing | 2001 | * must be pushed to disk before this transaction. |
| 1997 | * to disk all iclogs up that transaction's LSN. | 2002 | * |
| 2003 | * We do this by setting the current transaction to a sync transaction | ||
| 2004 | * which guarantees that the freeing transaction is on disk before this | ||
| 2005 | * transaction. This is done instead of a synchronous log force here so | ||
| 2006 | * that we don't sit and wait with the AGF locked in the transaction | ||
| 2007 | * during the log force. | ||
| 1998 | */ | 2008 | */ |
| 1999 | xfs_alloc_search_busy(tp, be32_to_cpu(agf->agf_seqno), bno, 1); | 2009 | if (xfs_alloc_busy_search(mp, be32_to_cpu(agf->agf_seqno), bno, 1)) |
| 2010 | xfs_trans_set_sync(tp); | ||
| 2000 | return 0; | 2011 | return 0; |
| 2001 | } | 2012 | } |
| 2002 | 2013 | ||
| @@ -2201,7 +2212,7 @@ xfs_alloc_read_agf( | |||
| 2201 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); | 2212 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); |
| 2202 | spin_lock_init(&pag->pagb_lock); | 2213 | spin_lock_init(&pag->pagb_lock); |
| 2203 | pag->pagb_count = 0; | 2214 | pag->pagb_count = 0; |
| 2204 | memset(pag->pagb_list, 0, sizeof(pag->pagb_list)); | 2215 | pag->pagb_tree = RB_ROOT; |
| 2205 | pag->pagf_init = 1; | 2216 | pag->pagf_init = 1; |
| 2206 | } | 2217 | } |
| 2207 | #ifdef DEBUG | 2218 | #ifdef DEBUG |
| @@ -2479,127 +2490,263 @@ error0: | |||
| 2479 | * list is reused, the transaction that freed it must be forced to disk | 2490 | * list is reused, the transaction that freed it must be forced to disk |
| 2480 | * before continuing to use the block. | 2491 | * before continuing to use the block. |
| 2481 | * | 2492 | * |
| 2482 | * xfs_alloc_mark_busy - add to the per-ag busy list | 2493 | * xfs_alloc_busy_insert - add to the per-ag busy list |
| 2483 | * xfs_alloc_clear_busy - remove an item from the per-ag busy list | 2494 | * xfs_alloc_busy_clear - remove an item from the per-ag busy list |
| 2495 | * xfs_alloc_busy_search - search for a busy extent | ||
| 2496 | */ | ||
| 2497 | |||
| 2498 | /* | ||
| 2499 | * Insert a new extent into the busy tree. | ||
| 2500 | * | ||
| 2501 | * The busy extent tree is indexed by the start block of the busy extent. | ||
| 2502 | * there can be multiple overlapping ranges in the busy extent tree but only | ||
| 2503 | * ever one entry at a given start block. The reason for this is that | ||
| 2504 | * multi-block extents can be freed, then smaller chunks of that extent | ||
| 2505 | * allocated and freed again before the first transaction commit is on disk. | ||
| 2506 | * If the exact same start block is freed a second time, we have to wait for | ||
| 2507 | * that busy extent to pass out of the tree before the new extent is inserted. | ||
| 2508 | * There are two main cases we have to handle here. | ||
| 2509 | * | ||
| 2510 | * The first case is a transaction that triggers a "free - allocate - free" | ||
| 2511 | * cycle. This can occur during btree manipulations as a btree block is freed | ||
| 2512 | * to the freelist, then allocated from the free list, then freed again. In | ||
| 2513 | * this case, the second extxpnet free is what triggers the duplicate and as | ||
| 2514 | * such the transaction IDs should match. Because the extent was allocated in | ||
| 2515 | * this transaction, the transaction must be marked as synchronous. This is | ||
| 2516 | * true for all cases where the free/alloc/free occurs in the one transaction, | ||
| 2517 | * hence the addition of the ASSERT(tp->t_flags & XFS_TRANS_SYNC) to this case. | ||
| 2518 | * This serves to catch violations of the second case quite effectively. | ||
| 2519 | * | ||
| 2520 | * The second case is where the free/alloc/free occur in different | ||
| 2521 | * transactions. In this case, the thread freeing the extent the second time | ||
| 2522 | * can't mark the extent busy immediately because it is already tracked in a | ||
| 2523 | * transaction that may be committing. When the log commit for the existing | ||
| 2524 | * busy extent completes, the busy extent will be removed from the tree. If we | ||
| 2525 | * allow the second busy insert to continue using that busy extent structure, | ||
| 2526 | * it can be freed before this transaction is safely in the log. Hence our | ||
| 2527 | * only option in this case is to force the log to remove the existing busy | ||
| 2528 | * extent from the list before we insert the new one with the current | ||
| 2529 | * transaction ID. | ||
| 2530 | * | ||
| 2531 | * The problem we are trying to avoid in the free-alloc-free in separate | ||
| 2532 | * transactions is most easily described with a timeline: | ||
| 2533 | * | ||
| 2534 | * Thread 1 Thread 2 Thread 3 xfslogd | ||
| 2535 | * xact alloc | ||
| 2536 | * free X | ||
| 2537 | * mark busy | ||
| 2538 | * commit xact | ||
| 2539 | * free xact | ||
| 2540 | * xact alloc | ||
| 2541 | * alloc X | ||
| 2542 | * busy search | ||
| 2543 | * mark xact sync | ||
| 2544 | * commit xact | ||
| 2545 | * free xact | ||
| 2546 | * force log | ||
| 2547 | * checkpoint starts | ||
| 2548 | * .... | ||
| 2549 | * xact alloc | ||
| 2550 | * free X | ||
| 2551 | * mark busy | ||
| 2552 | * finds match | ||
| 2553 | * *** KABOOM! *** | ||
| 2554 | * .... | ||
| 2555 | * log IO completes | ||
| 2556 | * unbusy X | ||
| 2557 | * checkpoint completes | ||
| 2558 | * | ||
| 2559 | * By issuing a log force in thread 3 @ "KABOOM", the thread will block until | ||
| 2560 | * the checkpoint completes, and the busy extent it matched will have been | ||
| 2561 | * removed from the tree when it is woken. Hence it can then continue safely. | ||
| 2562 | * | ||
| 2563 | * However, to ensure this matching process is robust, we need to use the | ||
| 2564 | * transaction ID for identifying transaction, as delayed logging results in | ||
| 2565 | * the busy extent and transaction lifecycles being different. i.e. the busy | ||
| 2566 | * extent is active for a lot longer than the transaction. Hence the | ||
| 2567 | * transaction structure can be freed and reallocated, then mark the same | ||
| 2568 | * extent busy again in the new transaction. In this case the new transaction | ||
| 2569 | * will have a different tid but can have the same address, and hence we need | ||
| 2570 | * to check against the tid. | ||
| 2571 | * | ||
| 2572 | * Future: for delayed logging, we could avoid the log force if the extent was | ||
| 2573 | * first freed in the current checkpoint sequence. This, however, requires the | ||
| 2574 | * ability to pin the current checkpoint in memory until this transaction | ||
| 2575 | * commits to ensure that both the original free and the current one combine | ||
| 2576 | * logically into the one checkpoint. If the checkpoint sequences are | ||
| 2577 | * different, however, we still need to wait on a log force. | ||
| 2484 | */ | 2578 | */ |
| 2485 | void | 2579 | void |
| 2486 | xfs_alloc_mark_busy(xfs_trans_t *tp, | 2580 | xfs_alloc_busy_insert( |
| 2487 | xfs_agnumber_t agno, | 2581 | struct xfs_trans *tp, |
| 2488 | xfs_agblock_t bno, | 2582 | xfs_agnumber_t agno, |
| 2489 | xfs_extlen_t len) | 2583 | xfs_agblock_t bno, |
| 2584 | xfs_extlen_t len) | ||
| 2490 | { | 2585 | { |
| 2491 | xfs_perag_busy_t *bsy; | 2586 | struct xfs_busy_extent *new; |
| 2587 | struct xfs_busy_extent *busyp; | ||
| 2492 | struct xfs_perag *pag; | 2588 | struct xfs_perag *pag; |
| 2493 | int n; | 2589 | struct rb_node **rbp; |
| 2590 | struct rb_node *parent; | ||
| 2591 | int match; | ||
| 2494 | 2592 | ||
| 2495 | pag = xfs_perag_get(tp->t_mountp, agno); | ||
| 2496 | spin_lock(&pag->pagb_lock); | ||
| 2497 | 2593 | ||
| 2498 | /* search pagb_list for an open slot */ | 2594 | new = kmem_zalloc(sizeof(struct xfs_busy_extent), KM_MAYFAIL); |
| 2499 | for (bsy = pag->pagb_list, n = 0; | 2595 | if (!new) { |
| 2500 | n < XFS_PAGB_NUM_SLOTS; | 2596 | /* |
| 2501 | bsy++, n++) { | 2597 | * No Memory! Since it is now not possible to track the free |
| 2502 | if (bsy->busy_tp == NULL) { | 2598 | * block, make this a synchronous transaction to insure that |
| 2503 | break; | 2599 | * the block is not reused before this transaction commits. |
| 2504 | } | 2600 | */ |
| 2601 | trace_xfs_alloc_busy(tp, agno, bno, len, 1); | ||
| 2602 | xfs_trans_set_sync(tp); | ||
| 2603 | return; | ||
| 2505 | } | 2604 | } |
| 2506 | 2605 | ||
| 2507 | trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len, n); | 2606 | new->agno = agno; |
| 2607 | new->bno = bno; | ||
| 2608 | new->length = len; | ||
| 2609 | new->tid = xfs_log_get_trans_ident(tp); | ||
| 2508 | 2610 | ||
| 2509 | if (n < XFS_PAGB_NUM_SLOTS) { | 2611 | INIT_LIST_HEAD(&new->list); |
| 2510 | bsy = &pag->pagb_list[n]; | 2612 | |
| 2511 | pag->pagb_count++; | 2613 | /* trace before insert to be able to see failed inserts */ |
| 2512 | bsy->busy_start = bno; | 2614 | trace_xfs_alloc_busy(tp, agno, bno, len, 0); |
| 2513 | bsy->busy_length = len; | 2615 | |
| 2514 | bsy->busy_tp = tp; | 2616 | pag = xfs_perag_get(tp->t_mountp, new->agno); |
| 2515 | xfs_trans_add_busy(tp, agno, n); | 2617 | restart: |
| 2516 | } else { | 2618 | spin_lock(&pag->pagb_lock); |
| 2619 | rbp = &pag->pagb_tree.rb_node; | ||
| 2620 | parent = NULL; | ||
| 2621 | busyp = NULL; | ||
| 2622 | match = 0; | ||
| 2623 | while (*rbp && match >= 0) { | ||
| 2624 | parent = *rbp; | ||
| 2625 | busyp = rb_entry(parent, struct xfs_busy_extent, rb_node); | ||
| 2626 | |||
| 2627 | if (new->bno < busyp->bno) { | ||
| 2628 | /* may overlap, but exact start block is lower */ | ||
| 2629 | rbp = &(*rbp)->rb_left; | ||
| 2630 | if (new->bno + new->length > busyp->bno) | ||
| 2631 | match = busyp->tid == new->tid ? 1 : -1; | ||
| 2632 | } else if (new->bno > busyp->bno) { | ||
| 2633 | /* may overlap, but exact start block is higher */ | ||
| 2634 | rbp = &(*rbp)->rb_right; | ||
| 2635 | if (bno < busyp->bno + busyp->length) | ||
| 2636 | match = busyp->tid == new->tid ? 1 : -1; | ||
| 2637 | } else { | ||
| 2638 | match = busyp->tid == new->tid ? 1 : -1; | ||
| 2639 | break; | ||
| 2640 | } | ||
| 2641 | } | ||
| 2642 | if (match < 0) { | ||
| 2643 | /* overlap marked busy in different transaction */ | ||
| 2644 | spin_unlock(&pag->pagb_lock); | ||
| 2645 | xfs_log_force(tp->t_mountp, XFS_LOG_SYNC); | ||
| 2646 | goto restart; | ||
| 2647 | } | ||
| 2648 | if (match > 0) { | ||
| 2517 | /* | 2649 | /* |
| 2518 | * The busy list is full! Since it is now not possible to | 2650 | * overlap marked busy in same transaction. Update if exact |
| 2519 | * track the free block, make this a synchronous transaction | 2651 | * start block match, otherwise combine the busy extents into |
| 2520 | * to insure that the block is not reused before this | 2652 | * a single range. |
| 2521 | * transaction commits. | ||
| 2522 | */ | 2653 | */ |
| 2523 | xfs_trans_set_sync(tp); | 2654 | if (busyp->bno == new->bno) { |
| 2524 | } | 2655 | busyp->length = max(busyp->length, new->length); |
| 2656 | spin_unlock(&pag->pagb_lock); | ||
| 2657 | ASSERT(tp->t_flags & XFS_TRANS_SYNC); | ||
| 2658 | xfs_perag_put(pag); | ||
| 2659 | kmem_free(new); | ||
| 2660 | return; | ||
| 2661 | } | ||
| 2662 | rb_erase(&busyp->rb_node, &pag->pagb_tree); | ||
| 2663 | new->length = max(busyp->bno + busyp->length, | ||
| 2664 | new->bno + new->length) - | ||
| 2665 | min(busyp->bno, new->bno); | ||
| 2666 | new->bno = min(busyp->bno, new->bno); | ||
| 2667 | } else | ||
| 2668 | busyp = NULL; | ||
| 2525 | 2669 | ||
| 2670 | rb_link_node(&new->rb_node, parent, rbp); | ||
| 2671 | rb_insert_color(&new->rb_node, &pag->pagb_tree); | ||
| 2672 | |||
| 2673 | list_add(&new->list, &tp->t_busy); | ||
| 2526 | spin_unlock(&pag->pagb_lock); | 2674 | spin_unlock(&pag->pagb_lock); |
| 2527 | xfs_perag_put(pag); | 2675 | xfs_perag_put(pag); |
| 2676 | kmem_free(busyp); | ||
| 2528 | } | 2677 | } |
| 2529 | 2678 | ||
| 2530 | void | 2679 | /* |
| 2531 | xfs_alloc_clear_busy(xfs_trans_t *tp, | 2680 | * Search for a busy extent within the range of the extent we are about to |
| 2532 | xfs_agnumber_t agno, | 2681 | * allocate. You need to be holding the busy extent tree lock when calling |
| 2533 | int idx) | 2682 | * xfs_alloc_busy_search(). This function returns 0 for no overlapping busy |
| 2683 | * extent, -1 for an overlapping but not exact busy extent, and 1 for an exact | ||
| 2684 | * match. This is done so that a non-zero return indicates an overlap that | ||
| 2685 | * will require a synchronous transaction, but it can still be | ||
| 2686 | * used to distinguish between a partial or exact match. | ||
| 2687 | */ | ||
| 2688 | static int | ||
| 2689 | xfs_alloc_busy_search( | ||
| 2690 | struct xfs_mount *mp, | ||
| 2691 | xfs_agnumber_t agno, | ||
| 2692 | xfs_agblock_t bno, | ||
| 2693 | xfs_extlen_t len) | ||
| 2534 | { | 2694 | { |
| 2535 | struct xfs_perag *pag; | 2695 | struct xfs_perag *pag; |
| 2536 | xfs_perag_busy_t *list; | 2696 | struct rb_node *rbp; |
| 2697 | struct xfs_busy_extent *busyp; | ||
| 2698 | int match = 0; | ||
| 2537 | 2699 | ||
| 2538 | ASSERT(idx < XFS_PAGB_NUM_SLOTS); | 2700 | pag = xfs_perag_get(mp, agno); |
| 2539 | pag = xfs_perag_get(tp->t_mountp, agno); | ||
| 2540 | spin_lock(&pag->pagb_lock); | 2701 | spin_lock(&pag->pagb_lock); |
| 2541 | list = pag->pagb_list; | ||
| 2542 | 2702 | ||
| 2543 | trace_xfs_alloc_unbusy(tp->t_mountp, agno, idx, list[idx].busy_tp == tp); | 2703 | rbp = pag->pagb_tree.rb_node; |
| 2544 | 2704 | ||
| 2545 | if (list[idx].busy_tp == tp) { | 2705 | /* find closest start bno overlap */ |
| 2546 | list[idx].busy_tp = NULL; | 2706 | while (rbp) { |
| 2547 | pag->pagb_count--; | 2707 | busyp = rb_entry(rbp, struct xfs_busy_extent, rb_node); |
| 2708 | if (bno < busyp->bno) { | ||
| 2709 | /* may overlap, but exact start block is lower */ | ||
| 2710 | if (bno + len > busyp->bno) | ||
| 2711 | match = -1; | ||
| 2712 | rbp = rbp->rb_left; | ||
| 2713 | } else if (bno > busyp->bno) { | ||
| 2714 | /* may overlap, but exact start block is higher */ | ||
| 2715 | if (bno < busyp->bno + busyp->length) | ||
| 2716 | match = -1; | ||
| 2717 | rbp = rbp->rb_right; | ||
| 2718 | } else { | ||
| 2719 | /* bno matches busyp, length determines exact match */ | ||
| 2720 | match = (busyp->length == len) ? 1 : -1; | ||
| 2721 | break; | ||
| 2722 | } | ||
| 2548 | } | 2723 | } |
| 2549 | |||
| 2550 | spin_unlock(&pag->pagb_lock); | 2724 | spin_unlock(&pag->pagb_lock); |
| 2725 | trace_xfs_alloc_busysearch(mp, agno, bno, len, !!match); | ||
| 2551 | xfs_perag_put(pag); | 2726 | xfs_perag_put(pag); |
| 2727 | return match; | ||
| 2552 | } | 2728 | } |
| 2553 | 2729 | ||
| 2554 | 2730 | void | |
| 2555 | /* | 2731 | xfs_alloc_busy_clear( |
| 2556 | * If we find the extent in the busy list, force the log out to get the | 2732 | struct xfs_mount *mp, |
| 2557 | * extent out of the busy list so the caller can use it straight away. | 2733 | struct xfs_busy_extent *busyp) |
| 2558 | */ | ||
| 2559 | STATIC void | ||
| 2560 | xfs_alloc_search_busy(xfs_trans_t *tp, | ||
| 2561 | xfs_agnumber_t agno, | ||
| 2562 | xfs_agblock_t bno, | ||
| 2563 | xfs_extlen_t len) | ||
| 2564 | { | 2734 | { |
| 2565 | struct xfs_perag *pag; | 2735 | struct xfs_perag *pag; |
| 2566 | xfs_perag_busy_t *bsy; | ||
| 2567 | xfs_agblock_t uend, bend; | ||
| 2568 | xfs_lsn_t lsn = 0; | ||
| 2569 | int cnt; | ||
| 2570 | 2736 | ||
| 2571 | pag = xfs_perag_get(tp->t_mountp, agno); | 2737 | trace_xfs_alloc_unbusy(mp, busyp->agno, busyp->bno, |
| 2572 | spin_lock(&pag->pagb_lock); | 2738 | busyp->length); |
| 2573 | cnt = pag->pagb_count; | ||
| 2574 | 2739 | ||
| 2575 | /* | 2740 | ASSERT(xfs_alloc_busy_search(mp, busyp->agno, busyp->bno, |
| 2576 | * search pagb_list for this slot, skipping open slots. We have to | 2741 | busyp->length) == 1); |
| 2577 | * search the entire array as there may be multiple overlaps and | ||
| 2578 | * we have to get the most recent LSN for the log force to push out | ||
| 2579 | * all the transactions that span the range. | ||
| 2580 | */ | ||
| 2581 | uend = bno + len - 1; | ||
| 2582 | for (cnt = 0; cnt < pag->pagb_count; cnt++) { | ||
| 2583 | bsy = &pag->pagb_list[cnt]; | ||
| 2584 | if (!bsy->busy_tp) | ||
| 2585 | continue; | ||
| 2586 | 2742 | ||
| 2587 | bend = bsy->busy_start + bsy->busy_length - 1; | 2743 | list_del_init(&busyp->list); |
| 2588 | if (bno > bend || uend < bsy->busy_start) | ||
| 2589 | continue; | ||
| 2590 | 2744 | ||
| 2591 | /* (start1,length1) within (start2, length2) */ | 2745 | pag = xfs_perag_get(mp, busyp->agno); |
| 2592 | if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0) | 2746 | spin_lock(&pag->pagb_lock); |
| 2593 | lsn = bsy->busy_tp->t_commit_lsn; | 2747 | rb_erase(&busyp->rb_node, &pag->pagb_tree); |
| 2594 | } | ||
| 2595 | spin_unlock(&pag->pagb_lock); | 2748 | spin_unlock(&pag->pagb_lock); |
| 2596 | xfs_perag_put(pag); | 2749 | xfs_perag_put(pag); |
| 2597 | trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn); | ||
| 2598 | 2750 | ||
| 2599 | /* | 2751 | kmem_free(busyp); |
| 2600 | * If a block was found, force the log through the LSN of the | ||
| 2601 | * transaction that freed the block | ||
| 2602 | */ | ||
| 2603 | if (lsn) | ||
| 2604 | xfs_log_force_lsn(tp->t_mountp, lsn, XFS_LOG_SYNC); | ||
| 2605 | } | 2752 | } |
