diff options
author | Dave Chinner <dchinner@redhat.com> | 2010-12-20 20:08:20 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2010-12-20 20:08:20 -0500 |
commit | a69ed03c24d4a336c23b7116127713d5a8c5ac4d (patch) | |
tree | 95c73e560b2780abc9125022032e8cc85ec518c7 /fs | |
parent | 663e496a720a3a9fc08ea70b29724e8906b34e43 (diff) |
xfs: combine grant heads into a single 64 bit integer
Prepare for switching the grant heads to atomic variables by
combining the two 32 bit values that make up the grant head into a
single 64 bit variable. Provide wrapper functions to combine and
split the grant heads appropriately for calculations and use them as
necessary.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_trace.h | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 166 | ||||
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 26 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 8 |
4 files changed, 119 insertions, 91 deletions
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index 69b9e1f1baaf..3ff6b35f9207 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h | |||
@@ -786,10 +786,12 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, | |||
786 | __entry->flags = tic->t_flags; | 786 | __entry->flags = tic->t_flags; |
787 | __entry->reserveq = list_empty(&log->l_reserveq); | 787 | __entry->reserveq = list_empty(&log->l_reserveq); |
788 | __entry->writeq = list_empty(&log->l_writeq); | 788 | __entry->writeq = list_empty(&log->l_writeq); |
789 | __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; | 789 | xlog_crack_grant_head(&log->l_grant_reserve_head, |
790 | __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; | 790 | &__entry->grant_reserve_cycle, |
791 | __entry->grant_write_cycle = log->l_grant_write_cycle; | 791 | &__entry->grant_reserve_bytes); |
792 | __entry->grant_write_bytes = log->l_grant_write_bytes; | 792 | xlog_crack_grant_head(&log->l_grant_write_head, |
793 | &__entry->grant_write_cycle, | ||
794 | &__entry->grant_write_bytes); | ||
793 | __entry->curr_cycle = log->l_curr_cycle; | 795 | __entry->curr_cycle = log->l_curr_cycle; |
794 | __entry->curr_block = log->l_curr_block; | 796 | __entry->curr_block = log->l_curr_block; |
795 | __entry->tail_lsn = log->l_tail_lsn; | 797 | __entry->tail_lsn = log->l_tail_lsn; |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 9a4b9edad847..6bba8b4b8596 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -47,7 +47,7 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, | |||
47 | xfs_buftarg_t *log_target, | 47 | xfs_buftarg_t *log_target, |
48 | xfs_daddr_t blk_offset, | 48 | xfs_daddr_t blk_offset, |
49 | int num_bblks); | 49 | int num_bblks); |
50 | STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); | 50 | STATIC int xlog_space_left(struct log *log, int64_t *head); |
51 | STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); | 51 | STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); |
52 | STATIC void xlog_dealloc_log(xlog_t *log); | 52 | STATIC void xlog_dealloc_log(xlog_t *log); |
53 | 53 | ||
@@ -100,32 +100,44 @@ STATIC int xlog_iclogs_empty(xlog_t *log); | |||
100 | static void | 100 | static void |
101 | xlog_grant_sub_space( | 101 | xlog_grant_sub_space( |
102 | struct log *log, | 102 | struct log *log, |
103 | int *cycle, | 103 | int64_t *head, |
104 | int *space, | ||
105 | int bytes) | 104 | int bytes) |
106 | { | 105 | { |
107 | *space -= bytes; | 106 | int cycle, space; |
108 | if (*space < 0) { | 107 | |
109 | *space += log->l_logsize; | 108 | xlog_crack_grant_head(head, &cycle, &space); |
110 | (*cycle)--; | 109 | |
110 | space -= bytes; | ||
111 | if (space < 0) { | ||
112 | space += log->l_logsize; | ||
113 | cycle--; | ||
111 | } | 114 | } |
115 | |||
116 | xlog_assign_grant_head(head, cycle, space); | ||
112 | } | 117 | } |
113 | 118 | ||
114 | static void | 119 | static void |
115 | xlog_grant_add_space( | 120 | xlog_grant_add_space( |
116 | struct log *log, | 121 | struct log *log, |
117 | int *cycle, | 122 | int64_t *head, |
118 | int *space, | ||
119 | int bytes) | 123 | int bytes) |
120 | { | 124 | { |
121 | int tmp = log->l_logsize - *space; | 125 | int tmp; |
126 | int cycle, space; | ||
127 | |||
128 | xlog_crack_grant_head(head, &cycle, &space); | ||
129 | |||
130 | tmp = log->l_logsize - space; | ||
122 | if (tmp > bytes) | 131 | if (tmp > bytes) |
123 | *space += bytes; | 132 | space += bytes; |
124 | else { | 133 | else { |
125 | *space = bytes - tmp; | 134 | space = bytes - tmp; |
126 | (*cycle)++; | 135 | cycle++; |
127 | } | 136 | } |
137 | |||
138 | xlog_assign_grant_head(head, cycle, space); | ||
128 | } | 139 | } |
140 | |||
129 | static void | 141 | static void |
130 | xlog_tic_reset_res(xlog_ticket_t *tic) | 142 | xlog_tic_reset_res(xlog_ticket_t *tic) |
131 | { | 143 | { |
@@ -654,7 +666,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
654 | { | 666 | { |
655 | xlog_ticket_t *tic; | 667 | xlog_ticket_t *tic; |
656 | xlog_t *log = mp->m_log; | 668 | xlog_t *log = mp->m_log; |
657 | int need_bytes, free_bytes, cycle, bytes; | 669 | int need_bytes, free_bytes; |
658 | 670 | ||
659 | if (XLOG_FORCED_SHUTDOWN(log)) | 671 | if (XLOG_FORCED_SHUTDOWN(log)) |
660 | return; | 672 | return; |
@@ -680,9 +692,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
680 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | 692 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) |
681 | panic("Recovery problem"); | 693 | panic("Recovery problem"); |
682 | #endif | 694 | #endif |
683 | cycle = log->l_grant_write_cycle; | 695 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); |
684 | bytes = log->l_grant_write_bytes; | ||
685 | free_bytes = xlog_space_left(log, cycle, bytes); | ||
686 | list_for_each_entry(tic, &log->l_writeq, t_queue) { | 696 | list_for_each_entry(tic, &log->l_writeq, t_queue) { |
687 | ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); | 697 | ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); |
688 | 698 | ||
@@ -699,9 +709,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
699 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | 709 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) |
700 | panic("Recovery problem"); | 710 | panic("Recovery problem"); |
701 | #endif | 711 | #endif |
702 | cycle = log->l_grant_reserve_cycle; | 712 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); |
703 | bytes = log->l_grant_reserve_bytes; | ||
704 | free_bytes = xlog_space_left(log, cycle, bytes); | ||
705 | list_for_each_entry(tic, &log->l_reserveq, t_queue) { | 713 | list_for_each_entry(tic, &log->l_reserveq, t_queue) { |
706 | if (tic->t_flags & XLOG_TIC_PERM_RESERV) | 714 | if (tic->t_flags & XLOG_TIC_PERM_RESERV) |
707 | need_bytes = tic->t_unit_res*tic->t_cnt; | 715 | need_bytes = tic->t_unit_res*tic->t_cnt; |
@@ -814,21 +822,26 @@ xlog_assign_tail_lsn(xfs_mount_t *mp) | |||
814 | * result is that we return the size of the log as the amount of space left. | 822 | * result is that we return the size of the log as the amount of space left. |
815 | */ | 823 | */ |
816 | STATIC int | 824 | STATIC int |
817 | xlog_space_left(xlog_t *log, int cycle, int bytes) | 825 | xlog_space_left( |
826 | struct log *log, | ||
827 | int64_t *head) | ||
818 | { | 828 | { |
819 | int free_bytes; | 829 | int free_bytes; |
820 | int tail_bytes; | 830 | int tail_bytes; |
821 | int tail_cycle; | 831 | int tail_cycle; |
832 | int head_cycle; | ||
833 | int head_bytes; | ||
822 | 834 | ||
835 | xlog_crack_grant_head(head, &head_cycle, &head_bytes); | ||
823 | tail_bytes = BBTOB(BLOCK_LSN(log->l_tail_lsn)); | 836 | tail_bytes = BBTOB(BLOCK_LSN(log->l_tail_lsn)); |
824 | tail_cycle = CYCLE_LSN(log->l_tail_lsn); | 837 | tail_cycle = CYCLE_LSN(log->l_tail_lsn); |
825 | if ((tail_cycle == cycle) && (bytes >= tail_bytes)) { | 838 | if (tail_cycle == head_cycle && head_bytes >= tail_bytes) |
826 | free_bytes = log->l_logsize - (bytes - tail_bytes); | 839 | free_bytes = log->l_logsize - (head_bytes - tail_bytes); |
827 | } else if ((tail_cycle + 1) < cycle) { | 840 | else if (tail_cycle + 1 < head_cycle) |
828 | return 0; | 841 | return 0; |
829 | } else if (tail_cycle < cycle) { | 842 | else if (tail_cycle < head_cycle) { |
830 | ASSERT(tail_cycle == (cycle - 1)); | 843 | ASSERT(tail_cycle == (head_cycle - 1)); |
831 | free_bytes = tail_bytes - bytes; | 844 | free_bytes = tail_bytes - head_bytes; |
832 | } else { | 845 | } else { |
833 | /* | 846 | /* |
834 | * The reservation head is behind the tail. | 847 | * The reservation head is behind the tail. |
@@ -839,12 +852,12 @@ xlog_space_left(xlog_t *log, int cycle, int bytes) | |||
839 | "xlog_space_left: head behind tail\n" | 852 | "xlog_space_left: head behind tail\n" |
840 | " tail_cycle = %d, tail_bytes = %d\n" | 853 | " tail_cycle = %d, tail_bytes = %d\n" |
841 | " GH cycle = %d, GH bytes = %d", | 854 | " GH cycle = %d, GH bytes = %d", |
842 | tail_cycle, tail_bytes, cycle, bytes); | 855 | tail_cycle, tail_bytes, head_cycle, head_bytes); |
843 | ASSERT(0); | 856 | ASSERT(0); |
844 | free_bytes = log->l_logsize; | 857 | free_bytes = log->l_logsize; |
845 | } | 858 | } |
846 | return free_bytes; | 859 | return free_bytes; |
847 | } /* xlog_space_left */ | 860 | } |
848 | 861 | ||
849 | 862 | ||
850 | /* | 863 | /* |
@@ -1001,8 +1014,8 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1001 | /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ | 1014 | /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ |
1002 | log->l_last_sync_lsn = log->l_tail_lsn; | 1015 | log->l_last_sync_lsn = log->l_tail_lsn; |
1003 | log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ | 1016 | log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ |
1004 | log->l_grant_reserve_cycle = 1; | 1017 | xlog_assign_grant_head(&log->l_grant_reserve_head, 1, 0); |
1005 | log->l_grant_write_cycle = 1; | 1018 | xlog_assign_grant_head(&log->l_grant_write_head, 1, 0); |
1006 | INIT_LIST_HEAD(&log->l_reserveq); | 1019 | INIT_LIST_HEAD(&log->l_reserveq); |
1007 | INIT_LIST_HEAD(&log->l_writeq); | 1020 | INIT_LIST_HEAD(&log->l_writeq); |
1008 | 1021 | ||
@@ -1190,9 +1203,7 @@ xlog_grant_push_ail(xfs_mount_t *mp, | |||
1190 | ASSERT(BTOBB(need_bytes) < log->l_logBBsize); | 1203 | ASSERT(BTOBB(need_bytes) < log->l_logBBsize); |
1191 | 1204 | ||
1192 | spin_lock(&log->l_grant_lock); | 1205 | spin_lock(&log->l_grant_lock); |
1193 | free_bytes = xlog_space_left(log, | 1206 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); |
1194 | log->l_grant_reserve_cycle, | ||
1195 | log->l_grant_reserve_bytes); | ||
1196 | tail_lsn = log->l_tail_lsn; | 1207 | tail_lsn = log->l_tail_lsn; |
1197 | free_blocks = BTOBBT(free_bytes); | 1208 | free_blocks = BTOBBT(free_bytes); |
1198 | 1209 | ||
@@ -1325,10 +1336,8 @@ xlog_sync(xlog_t *log, | |||
1325 | 1336 | ||
1326 | /* move grant heads by roundoff in sync */ | 1337 | /* move grant heads by roundoff in sync */ |
1327 | spin_lock(&log->l_grant_lock); | 1338 | spin_lock(&log->l_grant_lock); |
1328 | xlog_grant_add_space(log, &log->l_grant_reserve_cycle, | 1339 | xlog_grant_add_space(log, &log->l_grant_reserve_head, roundoff); |
1329 | &log->l_grant_reserve_bytes, roundoff); | 1340 | xlog_grant_add_space(log, &log->l_grant_write_head, roundoff); |
1330 | xlog_grant_add_space(log, &log->l_grant_write_cycle, | ||
1331 | &log->l_grant_write_bytes, roundoff); | ||
1332 | spin_unlock(&log->l_grant_lock); | 1341 | spin_unlock(&log->l_grant_lock); |
1333 | 1342 | ||
1334 | /* put cycle number in every block */ | 1343 | /* put cycle number in every block */ |
@@ -2531,8 +2540,7 @@ redo: | |||
2531 | if (XLOG_FORCED_SHUTDOWN(log)) | 2540 | if (XLOG_FORCED_SHUTDOWN(log)) |
2532 | goto error_return; | 2541 | goto error_return; |
2533 | 2542 | ||
2534 | free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle, | 2543 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); |
2535 | log->l_grant_reserve_bytes); | ||
2536 | if (free_bytes < need_bytes) { | 2544 | if (free_bytes < need_bytes) { |
2537 | if (list_empty(&tic->t_queue)) | 2545 | if (list_empty(&tic->t_queue)) |
2538 | list_add_tail(&tic->t_queue, &log->l_reserveq); | 2546 | list_add_tail(&tic->t_queue, &log->l_reserveq); |
@@ -2558,10 +2566,8 @@ redo: | |||
2558 | list_del_init(&tic->t_queue); | 2566 | list_del_init(&tic->t_queue); |
2559 | 2567 | ||
2560 | /* we've got enough space */ | 2568 | /* we've got enough space */ |
2561 | xlog_grant_add_space(log, &log->l_grant_reserve_cycle, | 2569 | xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); |
2562 | &log->l_grant_reserve_bytes, need_bytes); | 2570 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); |
2563 | xlog_grant_add_space(log, &log->l_grant_write_cycle, | ||
2564 | &log->l_grant_write_bytes, need_bytes); | ||
2565 | trace_xfs_log_grant_exit(log, tic); | 2571 | trace_xfs_log_grant_exit(log, tic); |
2566 | xlog_verify_grant_head(log, 1); | 2572 | xlog_verify_grant_head(log, 1); |
2567 | xlog_verify_grant_tail(log); | 2573 | xlog_verify_grant_tail(log); |
@@ -2622,8 +2628,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2622 | need_bytes = tic->t_unit_res; | 2628 | need_bytes = tic->t_unit_res; |
2623 | if (!list_empty(&log->l_writeq)) { | 2629 | if (!list_empty(&log->l_writeq)) { |
2624 | struct xlog_ticket *ntic; | 2630 | struct xlog_ticket *ntic; |
2625 | free_bytes = xlog_space_left(log, log->l_grant_write_cycle, | 2631 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); |
2626 | log->l_grant_write_bytes); | ||
2627 | list_for_each_entry(ntic, &log->l_writeq, t_queue) { | 2632 | list_for_each_entry(ntic, &log->l_writeq, t_queue) { |
2628 | ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); | 2633 | ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); |
2629 | 2634 | ||
@@ -2662,8 +2667,7 @@ redo: | |||
2662 | if (XLOG_FORCED_SHUTDOWN(log)) | 2667 | if (XLOG_FORCED_SHUTDOWN(log)) |
2663 | goto error_return; | 2668 | goto error_return; |
2664 | 2669 | ||
2665 | free_bytes = xlog_space_left(log, log->l_grant_write_cycle, | 2670 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); |
2666 | log->l_grant_write_bytes); | ||
2667 | if (free_bytes < need_bytes) { | 2671 | if (free_bytes < need_bytes) { |
2668 | if (list_empty(&tic->t_queue)) | 2672 | if (list_empty(&tic->t_queue)) |
2669 | list_add_tail(&tic->t_queue, &log->l_writeq); | 2673 | list_add_tail(&tic->t_queue, &log->l_writeq); |
@@ -2688,8 +2692,7 @@ redo: | |||
2688 | list_del_init(&tic->t_queue); | 2692 | list_del_init(&tic->t_queue); |
2689 | 2693 | ||
2690 | /* we've got enough space */ | 2694 | /* we've got enough space */ |
2691 | xlog_grant_add_space(log, &log->l_grant_write_cycle, | 2695 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); |
2692 | &log->l_grant_write_bytes, need_bytes); | ||
2693 | trace_xfs_log_regrant_write_exit(log, tic); | 2696 | trace_xfs_log_regrant_write_exit(log, tic); |
2694 | xlog_verify_grant_head(log, 1); | 2697 | xlog_verify_grant_head(log, 1); |
2695 | xlog_verify_grant_tail(log); | 2698 | xlog_verify_grant_tail(log); |
@@ -2730,12 +2733,10 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2730 | ticket->t_cnt--; | 2733 | ticket->t_cnt--; |
2731 | 2734 | ||
2732 | spin_lock(&log->l_grant_lock); | 2735 | spin_lock(&log->l_grant_lock); |
2733 | xlog_grant_sub_space(log, &log->l_grant_reserve_cycle, | 2736 | xlog_grant_sub_space(log, &log->l_grant_reserve_head, |
2734 | &log->l_grant_reserve_bytes, | 2737 | ticket->t_curr_res); |
2735 | ticket->t_curr_res); | 2738 | xlog_grant_sub_space(log, &log->l_grant_write_head, |
2736 | xlog_grant_sub_space(log, &log->l_grant_write_cycle, | 2739 | ticket->t_curr_res); |
2737 | &log->l_grant_write_bytes, | ||
2738 | ticket->t_curr_res); | ||
2739 | ticket->t_curr_res = ticket->t_unit_res; | 2740 | ticket->t_curr_res = ticket->t_unit_res; |
2740 | xlog_tic_reset_res(ticket); | 2741 | xlog_tic_reset_res(ticket); |
2741 | 2742 | ||
@@ -2749,9 +2750,8 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2749 | return; | 2750 | return; |
2750 | } | 2751 | } |
2751 | 2752 | ||
2752 | xlog_grant_add_space(log, &log->l_grant_reserve_cycle, | 2753 | xlog_grant_add_space(log, &log->l_grant_reserve_head, |
2753 | &log->l_grant_reserve_bytes, | 2754 | ticket->t_unit_res); |
2754 | ticket->t_unit_res); | ||
2755 | 2755 | ||
2756 | trace_xfs_log_regrant_reserve_exit(log, ticket); | 2756 | trace_xfs_log_regrant_reserve_exit(log, ticket); |
2757 | 2757 | ||
@@ -2799,10 +2799,8 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2799 | bytes += ticket->t_unit_res*ticket->t_cnt; | 2799 | bytes += ticket->t_unit_res*ticket->t_cnt; |
2800 | } | 2800 | } |
2801 | 2801 | ||
2802 | xlog_grant_sub_space(log, &log->l_grant_reserve_cycle, | 2802 | xlog_grant_sub_space(log, &log->l_grant_reserve_head, bytes); |
2803 | &log->l_grant_reserve_bytes, bytes); | 2803 | xlog_grant_sub_space(log, &log->l_grant_write_head, bytes); |
2804 | xlog_grant_sub_space(log, &log->l_grant_write_cycle, | ||
2805 | &log->l_grant_write_bytes, bytes); | ||
2806 | 2804 | ||
2807 | trace_xfs_log_ungrant_exit(log, ticket); | 2805 | trace_xfs_log_ungrant_exit(log, ticket); |
2808 | 2806 | ||
@@ -3430,22 +3428,31 @@ xlog_verify_dest_ptr( | |||
3430 | STATIC void | 3428 | STATIC void |
3431 | xlog_verify_grant_head(xlog_t *log, int equals) | 3429 | xlog_verify_grant_head(xlog_t *log, int equals) |
3432 | { | 3430 | { |
3433 | if (log->l_grant_reserve_cycle == log->l_grant_write_cycle) { | 3431 | int reserve_cycle, reserve_space; |
3434 | if (equals) | 3432 | int write_cycle, write_space; |
3435 | ASSERT(log->l_grant_reserve_bytes >= log->l_grant_write_bytes); | 3433 | |
3436 | else | 3434 | xlog_crack_grant_head(&log->l_grant_reserve_head, |
3437 | ASSERT(log->l_grant_reserve_bytes > log->l_grant_write_bytes); | 3435 | &reserve_cycle, &reserve_space); |
3438 | } else { | 3436 | xlog_crack_grant_head(&log->l_grant_write_head, |
3439 | ASSERT(log->l_grant_reserve_cycle-1 == log->l_grant_write_cycle); | 3437 | &write_cycle, &write_space); |
3440 | ASSERT(log->l_grant_write_bytes >= log->l_grant_reserve_bytes); | 3438 | |
3441 | } | 3439 | if (reserve_cycle == write_cycle) { |
3442 | } /* xlog_verify_grant_head */ | 3440 | if (equals) |
3441 | ASSERT(reserve_space >= write_space); | ||
3442 | else | ||
3443 | ASSERT(reserve_space > write_space); | ||
3444 | } else { | ||
3445 | ASSERT(reserve_cycle - 1 == write_cycle); | ||
3446 | ASSERT(write_space >= reserve_space); | ||
3447 | } | ||
3448 | } | ||
3443 | 3449 | ||
3444 | STATIC void | 3450 | STATIC void |
3445 | xlog_verify_grant_tail( | 3451 | xlog_verify_grant_tail( |
3446 | struct log *log) | 3452 | struct log *log) |
3447 | { | 3453 | { |
3448 | xfs_lsn_t tail_lsn = log->l_tail_lsn; | 3454 | xfs_lsn_t tail_lsn = log->l_tail_lsn; |
3455 | int cycle, space; | ||
3449 | 3456 | ||
3450 | /* | 3457 | /* |
3451 | * Check to make sure the grant write head didn't just over lap the | 3458 | * Check to make sure the grant write head didn't just over lap the |
@@ -3453,9 +3460,10 @@ xlog_verify_grant_tail( | |||
3453 | * Otherwise, make sure that the cycles differ by exactly one and | 3460 | * Otherwise, make sure that the cycles differ by exactly one and |
3454 | * check the byte count. | 3461 | * check the byte count. |
3455 | */ | 3462 | */ |
3456 | if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { | 3463 | xlog_crack_grant_head(&log->l_grant_write_head, &cycle, &space); |
3457 | ASSERT(log->l_grant_write_cycle - 1 == CYCLE_LSN(tail_lsn)); | 3464 | if (CYCLE_LSN(tail_lsn) != cycle) { |
3458 | ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn))); | 3465 | ASSERT(cycle - 1 == CYCLE_LSN(tail_lsn)); |
3466 | ASSERT(space <= BBTOB(BLOCK_LSN(tail_lsn))); | ||
3459 | } | 3467 | } |
3460 | } | 3468 | } |
3461 | 3469 | ||
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index a5b3c021a406..2f74c80a7a40 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -518,10 +518,8 @@ typedef struct log { | |||
518 | spinlock_t l_grant_lock ____cacheline_aligned_in_smp; | 518 | spinlock_t l_grant_lock ____cacheline_aligned_in_smp; |
519 | struct list_head l_reserveq; | 519 | struct list_head l_reserveq; |
520 | struct list_head l_writeq; | 520 | struct list_head l_writeq; |
521 | int l_grant_reserve_cycle; | 521 | int64_t l_grant_reserve_head; |
522 | int l_grant_reserve_bytes; | 522 | int64_t l_grant_write_head; |
523 | int l_grant_write_cycle; | ||
524 | int l_grant_write_bytes; | ||
525 | 523 | ||
526 | /* The following field are used for debugging; need to hold icloglock */ | 524 | /* The following field are used for debugging; need to hold icloglock */ |
527 | #ifdef DEBUG | 525 | #ifdef DEBUG |
@@ -561,6 +559,26 @@ int xlog_write(struct log *log, struct xfs_log_vec *log_vector, | |||
561 | xlog_in_core_t **commit_iclog, uint flags); | 559 | xlog_in_core_t **commit_iclog, uint flags); |
562 | 560 | ||
563 | /* | 561 | /* |
562 | * When we crack the grrant head, we sample it first so that the value will not | ||
563 | * change while we are cracking it into the component values. This means we | ||
564 | * will always get consistent component values to work from. | ||
565 | */ | ||
566 | static inline void | ||
567 | xlog_crack_grant_head(int64_t *head, int *cycle, int *space) | ||
568 | { | ||
569 | int64_t val = *head; | ||
570 | |||
571 | *cycle = val >> 32; | ||
572 | *space = val & 0xffffffff; | ||
573 | } | ||
574 | |||
575 | static inline void | ||
576 | xlog_assign_grant_head(int64_t *head, int cycle, int space) | ||
577 | { | ||
578 | *head = ((int64_t)cycle << 32) | space; | ||
579 | } | ||
580 | |||
581 | /* | ||
564 | * Committed Item List interfaces | 582 | * Committed Item List interfaces |
565 | */ | 583 | */ |
566 | int xlog_cil_init(struct log *log); | 584 | int xlog_cil_init(struct log *log); |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4abe7a9b380e..1550404a8aeb 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -938,10 +938,10 @@ xlog_find_tail( | |||
938 | log->l_curr_cycle++; | 938 | log->l_curr_cycle++; |
939 | log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); | 939 | log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); |
940 | log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn); | 940 | log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn); |
941 | log->l_grant_reserve_cycle = log->l_curr_cycle; | 941 | xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, |
942 | log->l_grant_reserve_bytes = BBTOB(log->l_curr_block); | 942 | BBTOB(log->l_curr_block)); |
943 | log->l_grant_write_cycle = log->l_curr_cycle; | 943 | xlog_assign_grant_head(&log->l_grant_write_head, log->l_curr_cycle, |
944 | log->l_grant_write_bytes = BBTOB(log->l_curr_block); | 944 | BBTOB(log->l_curr_block)); |
945 | 945 | ||
946 | /* | 946 | /* |
947 | * Look for unmount record. If we find it, then we know there | 947 | * Look for unmount record. If we find it, then we know there |