diff options
author | Dave Chinner <dchinner@redhat.com> | 2010-12-20 20:02:25 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2010-12-20 20:02:25 -0500 |
commit | 1054794198e39103cb986618c4c10ec2252b7089 (patch) | |
tree | bc1d6a3eece9385bef892c2df7d6dba6f39d3088 /fs/xfs/xfs_log.c | |
parent | 9552e7f2f3dd13a7580e488a7a3582332daad4f5 (diff) |
xfs: convert log grant ticket queues to list heads
The grant write and reserve queues use a roll-your-own double linked
list, so convert it to a standard list_head structure and convert
all the list traversals to use list_for_each_entry(). We can also
get rid of the XLOG_TIC_IN_Q flag as we can use the list_empty()
check to tell if the ticket is in a list or not.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 123 |
1 files changed, 41 insertions, 82 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index cee4ab9f8a9e..1b82735471ab 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -95,38 +95,6 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, | |||
95 | 95 | ||
96 | STATIC int xlog_iclogs_empty(xlog_t *log); | 96 | STATIC int xlog_iclogs_empty(xlog_t *log); |
97 | 97 | ||
98 | |||
99 | static void | ||
100 | xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) | ||
101 | { | ||
102 | if (*qp) { | ||
103 | tic->t_next = (*qp); | ||
104 | tic->t_prev = (*qp)->t_prev; | ||
105 | (*qp)->t_prev->t_next = tic; | ||
106 | (*qp)->t_prev = tic; | ||
107 | } else { | ||
108 | tic->t_prev = tic->t_next = tic; | ||
109 | *qp = tic; | ||
110 | } | ||
111 | |||
112 | tic->t_flags |= XLOG_TIC_IN_Q; | ||
113 | } | ||
114 | |||
115 | static void | ||
116 | xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) | ||
117 | { | ||
118 | if (tic == tic->t_next) { | ||
119 | *qp = NULL; | ||
120 | } else { | ||
121 | *qp = tic->t_next; | ||
122 | tic->t_next->t_prev = tic->t_prev; | ||
123 | tic->t_prev->t_next = tic->t_next; | ||
124 | } | ||
125 | |||
126 | tic->t_next = tic->t_prev = NULL; | ||
127 | tic->t_flags &= ~XLOG_TIC_IN_Q; | ||
128 | } | ||
129 | |||
130 | static void | 98 | static void |
131 | xlog_grant_sub_space(struct log *log, int bytes) | 99 | xlog_grant_sub_space(struct log *log, int bytes) |
132 | { | 100 | { |
@@ -724,7 +692,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
724 | log->l_tail_lsn = tail_lsn; | 692 | log->l_tail_lsn = tail_lsn; |
725 | } | 693 | } |
726 | 694 | ||
727 | if ((tic = log->l_write_headq)) { | 695 | if (!list_empty(&log->l_writeq)) { |
728 | #ifdef DEBUG | 696 | #ifdef DEBUG |
729 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | 697 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) |
730 | panic("Recovery problem"); | 698 | panic("Recovery problem"); |
@@ -732,7 +700,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
732 | cycle = log->l_grant_write_cycle; | 700 | cycle = log->l_grant_write_cycle; |
733 | bytes = log->l_grant_write_bytes; | 701 | bytes = log->l_grant_write_bytes; |
734 | free_bytes = xlog_space_left(log, cycle, bytes); | 702 | free_bytes = xlog_space_left(log, cycle, bytes); |
735 | do { | 703 | list_for_each_entry(tic, &log->l_writeq, t_queue) { |
736 | ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); | 704 | ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); |
737 | 705 | ||
738 | if (free_bytes < tic->t_unit_res && tail_lsn != 1) | 706 | if (free_bytes < tic->t_unit_res && tail_lsn != 1) |
@@ -740,10 +708,10 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
740 | tail_lsn = 0; | 708 | tail_lsn = 0; |
741 | free_bytes -= tic->t_unit_res; | 709 | free_bytes -= tic->t_unit_res; |
742 | sv_signal(&tic->t_wait); | 710 | sv_signal(&tic->t_wait); |
743 | tic = tic->t_next; | 711 | } |
744 | } while (tic != log->l_write_headq); | ||
745 | } | 712 | } |
746 | if ((tic = log->l_reserve_headq)) { | 713 | |
714 | if (!list_empty(&log->l_reserveq)) { | ||
747 | #ifdef DEBUG | 715 | #ifdef DEBUG |
748 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | 716 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) |
749 | panic("Recovery problem"); | 717 | panic("Recovery problem"); |
@@ -751,7 +719,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
751 | cycle = log->l_grant_reserve_cycle; | 719 | cycle = log->l_grant_reserve_cycle; |
752 | bytes = log->l_grant_reserve_bytes; | 720 | bytes = log->l_grant_reserve_bytes; |
753 | free_bytes = xlog_space_left(log, cycle, bytes); | 721 | free_bytes = xlog_space_left(log, cycle, bytes); |
754 | do { | 722 | list_for_each_entry(tic, &log->l_reserveq, t_queue) { |
755 | if (tic->t_flags & XLOG_TIC_PERM_RESERV) | 723 | if (tic->t_flags & XLOG_TIC_PERM_RESERV) |
756 | need_bytes = tic->t_unit_res*tic->t_cnt; | 724 | need_bytes = tic->t_unit_res*tic->t_cnt; |
757 | else | 725 | else |
@@ -761,8 +729,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
761 | tail_lsn = 0; | 729 | tail_lsn = 0; |
762 | free_bytes -= need_bytes; | 730 | free_bytes -= need_bytes; |
763 | sv_signal(&tic->t_wait); | 731 | sv_signal(&tic->t_wait); |
764 | tic = tic->t_next; | 732 | } |
765 | } while (tic != log->l_reserve_headq); | ||
766 | } | 733 | } |
767 | spin_unlock(&log->l_grant_lock); | 734 | spin_unlock(&log->l_grant_lock); |
768 | } /* xfs_log_move_tail */ | 735 | } /* xfs_log_move_tail */ |
@@ -1053,6 +1020,8 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1053 | log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ | 1020 | log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ |
1054 | log->l_grant_reserve_cycle = 1; | 1021 | log->l_grant_reserve_cycle = 1; |
1055 | log->l_grant_write_cycle = 1; | 1022 | log->l_grant_write_cycle = 1; |
1023 | INIT_LIST_HEAD(&log->l_reserveq); | ||
1024 | INIT_LIST_HEAD(&log->l_writeq); | ||
1056 | 1025 | ||
1057 | error = EFSCORRUPTED; | 1026 | error = EFSCORRUPTED; |
1058 | if (xfs_sb_version_hassector(&mp->m_sb)) { | 1027 | if (xfs_sb_version_hassector(&mp->m_sb)) { |
@@ -2550,8 +2519,8 @@ xlog_grant_log_space(xlog_t *log, | |||
2550 | trace_xfs_log_grant_enter(log, tic); | 2519 | trace_xfs_log_grant_enter(log, tic); |
2551 | 2520 | ||
2552 | /* something is already sleeping; insert new transaction at end */ | 2521 | /* something is already sleeping; insert new transaction at end */ |
2553 | if (log->l_reserve_headq) { | 2522 | if (!list_empty(&log->l_reserveq)) { |
2554 | xlog_ins_ticketq(&log->l_reserve_headq, tic); | 2523 | list_add_tail(&tic->t_queue, &log->l_reserveq); |
2555 | 2524 | ||
2556 | trace_xfs_log_grant_sleep1(log, tic); | 2525 | trace_xfs_log_grant_sleep1(log, tic); |
2557 | 2526 | ||
@@ -2583,8 +2552,8 @@ redo: | |||
2583 | free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle, | 2552 | free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle, |
2584 | log->l_grant_reserve_bytes); | 2553 | log->l_grant_reserve_bytes); |
2585 | if (free_bytes < need_bytes) { | 2554 | if (free_bytes < need_bytes) { |
2586 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2555 | if (list_empty(&tic->t_queue)) |
2587 | xlog_ins_ticketq(&log->l_reserve_headq, tic); | 2556 | list_add_tail(&tic->t_queue, &log->l_reserveq); |
2588 | 2557 | ||
2589 | trace_xfs_log_grant_sleep2(log, tic); | 2558 | trace_xfs_log_grant_sleep2(log, tic); |
2590 | 2559 | ||
@@ -2602,8 +2571,9 @@ redo: | |||
2602 | trace_xfs_log_grant_wake2(log, tic); | 2571 | trace_xfs_log_grant_wake2(log, tic); |
2603 | 2572 | ||
2604 | goto redo; | 2573 | goto redo; |
2605 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2574 | } |
2606 | xlog_del_ticketq(&log->l_reserve_headq, tic); | 2575 | |
2576 | list_del_init(&tic->t_queue); | ||
2607 | 2577 | ||
2608 | /* we've got enough space */ | 2578 | /* we've got enough space */ |
2609 | xlog_grant_add_space(log, need_bytes); | 2579 | xlog_grant_add_space(log, need_bytes); |
@@ -2626,9 +2596,7 @@ redo: | |||
2626 | return 0; | 2596 | return 0; |
2627 | 2597 | ||
2628 | error_return: | 2598 | error_return: |
2629 | if (tic->t_flags & XLOG_TIC_IN_Q) | 2599 | list_del_init(&tic->t_queue); |
2630 | xlog_del_ticketq(&log->l_reserve_headq, tic); | ||
2631 | |||
2632 | trace_xfs_log_grant_error(log, tic); | 2600 | trace_xfs_log_grant_error(log, tic); |
2633 | 2601 | ||
2634 | /* | 2602 | /* |
@@ -2653,7 +2621,6 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2653 | xlog_ticket_t *tic) | 2621 | xlog_ticket_t *tic) |
2654 | { | 2622 | { |
2655 | int free_bytes, need_bytes; | 2623 | int free_bytes, need_bytes; |
2656 | xlog_ticket_t *ntic; | ||
2657 | #ifdef DEBUG | 2624 | #ifdef DEBUG |
2658 | xfs_lsn_t tail_lsn; | 2625 | xfs_lsn_t tail_lsn; |
2659 | #endif | 2626 | #endif |
@@ -2683,22 +2650,23 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2683 | * this transaction. | 2650 | * this transaction. |
2684 | */ | 2651 | */ |
2685 | need_bytes = tic->t_unit_res; | 2652 | need_bytes = tic->t_unit_res; |
2686 | if ((ntic = log->l_write_headq)) { | 2653 | if (!list_empty(&log->l_writeq)) { |
2654 | struct xlog_ticket *ntic; | ||
2687 | free_bytes = xlog_space_left(log, log->l_grant_write_cycle, | 2655 | free_bytes = xlog_space_left(log, log->l_grant_write_cycle, |
2688 | log->l_grant_write_bytes); | 2656 | log->l_grant_write_bytes); |
2689 | do { | 2657 | list_for_each_entry(ntic, &log->l_writeq, t_queue) { |
2690 | ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); | 2658 | ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); |
2691 | 2659 | ||
2692 | if (free_bytes < ntic->t_unit_res) | 2660 | if (free_bytes < ntic->t_unit_res) |
2693 | break; | 2661 | break; |
2694 | free_bytes -= ntic->t_unit_res; | 2662 | free_bytes -= ntic->t_unit_res; |
2695 | sv_signal(&ntic->t_wait); | 2663 | sv_signal(&ntic->t_wait); |
2696 | ntic = ntic->t_next; | 2664 | } |
2697 | } while (ntic != log->l_write_headq); | ||
2698 | 2665 | ||
2699 | if (ntic != log->l_write_headq) { | 2666 | if (ntic != list_first_entry(&log->l_writeq, |
2700 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2667 | struct xlog_ticket, t_queue)) { |
2701 | xlog_ins_ticketq(&log->l_write_headq, tic); | 2668 | if (list_empty(&tic->t_queue)) |
2669 | list_add_tail(&tic->t_queue, &log->l_writeq); | ||
2702 | 2670 | ||
2703 | trace_xfs_log_regrant_write_sleep1(log, tic); | 2671 | trace_xfs_log_regrant_write_sleep1(log, tic); |
2704 | 2672 | ||
@@ -2727,8 +2695,8 @@ redo: | |||
2727 | free_bytes = xlog_space_left(log, log->l_grant_write_cycle, | 2695 | free_bytes = xlog_space_left(log, log->l_grant_write_cycle, |
2728 | log->l_grant_write_bytes); | 2696 | log->l_grant_write_bytes); |
2729 | if (free_bytes < need_bytes) { | 2697 | if (free_bytes < need_bytes) { |
2730 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2698 | if (list_empty(&tic->t_queue)) |
2731 | xlog_ins_ticketq(&log->l_write_headq, tic); | 2699 | list_add_tail(&tic->t_queue, &log->l_writeq); |
2732 | spin_unlock(&log->l_grant_lock); | 2700 | spin_unlock(&log->l_grant_lock); |
2733 | xlog_grant_push_ail(log->l_mp, need_bytes); | 2701 | xlog_grant_push_ail(log->l_mp, need_bytes); |
2734 | spin_lock(&log->l_grant_lock); | 2702 | spin_lock(&log->l_grant_lock); |
@@ -2745,8 +2713,9 @@ redo: | |||
2745 | 2713 | ||
2746 | trace_xfs_log_regrant_write_wake2(log, tic); | 2714 | trace_xfs_log_regrant_write_wake2(log, tic); |
2747 | goto redo; | 2715 | goto redo; |
2748 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2716 | } |
2749 | xlog_del_ticketq(&log->l_write_headq, tic); | 2717 | |
2718 | list_del_init(&tic->t_queue); | ||
2750 | 2719 | ||
2751 | /* we've got enough space */ | 2720 | /* we've got enough space */ |
2752 | xlog_grant_add_space_write(log, need_bytes); | 2721 | xlog_grant_add_space_write(log, need_bytes); |
@@ -2766,9 +2735,7 @@ redo: | |||
2766 | 2735 | ||
2767 | 2736 | ||
2768 | error_return: | 2737 | error_return: |
2769 | if (tic->t_flags & XLOG_TIC_IN_Q) | 2738 | list_del_init(&tic->t_queue); |
2770 | xlog_del_ticketq(&log->l_reserve_headq, tic); | ||
2771 | |||
2772 | trace_xfs_log_regrant_write_error(log, tic); | 2739 | trace_xfs_log_regrant_write_error(log, tic); |
2773 | 2740 | ||
2774 | /* | 2741 | /* |
@@ -3435,6 +3402,7 @@ xlog_ticket_alloc( | |||
3435 | } | 3402 | } |
3436 | 3403 | ||
3437 | atomic_set(&tic->t_ref, 1); | 3404 | atomic_set(&tic->t_ref, 1); |
3405 | INIT_LIST_HEAD(&tic->t_queue); | ||
3438 | tic->t_unit_res = unit_bytes; | 3406 | tic->t_unit_res = unit_bytes; |
3439 | tic->t_curr_res = unit_bytes; | 3407 | tic->t_curr_res = unit_bytes; |
3440 | tic->t_cnt = cnt; | 3408 | tic->t_cnt = cnt; |
@@ -3742,26 +3710,17 @@ xfs_log_force_umount( | |||
3742 | spin_unlock(&log->l_icloglock); | 3710 | spin_unlock(&log->l_icloglock); |
3743 | 3711 | ||
3744 | /* | 3712 | /* |
3745 | * We don't want anybody waiting for log reservations | 3713 | * We don't want anybody waiting for log reservations after this. That |
3746 | * after this. That means we have to wake up everybody | 3714 | * means we have to wake up everybody queued up on reserveq as well as |
3747 | * queued up on reserve_headq as well as write_headq. | 3715 | * writeq. In addition, we make sure in xlog_{re}grant_log_space that |
3748 | * In addition, we make sure in xlog_{re}grant_log_space | 3716 | * we don't enqueue anything once the SHUTDOWN flag is set, and this |
3749 | * that we don't enqueue anything once the SHUTDOWN flag | 3717 | * action is protected by the GRANTLOCK. |
3750 | * is set, and this action is protected by the GRANTLOCK. | ||
3751 | */ | 3718 | */ |
3752 | if ((tic = log->l_reserve_headq)) { | 3719 | list_for_each_entry(tic, &log->l_reserveq, t_queue) |
3753 | do { | 3720 | sv_signal(&tic->t_wait); |
3754 | sv_signal(&tic->t_wait); | ||
3755 | tic = tic->t_next; | ||
3756 | } while (tic != log->l_reserve_headq); | ||
3757 | } | ||
3758 | 3721 | ||
3759 | if ((tic = log->l_write_headq)) { | 3722 | list_for_each_entry(tic, &log->l_writeq, t_queue) |
3760 | do { | 3723 | sv_signal(&tic->t_wait); |
3761 | sv_signal(&tic->t_wait); | ||
3762 | tic = tic->t_next; | ||
3763 | } while (tic != log->l_write_headq); | ||
3764 | } | ||
3765 | spin_unlock(&log->l_grant_lock); | 3724 | spin_unlock(&log->l_grant_lock); |
3766 | 3725 | ||
3767 | if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { | 3726 | if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { |