diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 113 |
1 files changed, 93 insertions, 20 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index ecb1067494f0..f6bac20af7aa 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -178,6 +178,83 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state) | |||
178 | #define xlog_trace_iclog(iclog,state) | 178 | #define xlog_trace_iclog(iclog,state) |
179 | #endif /* XFS_LOG_TRACE */ | 179 | #endif /* XFS_LOG_TRACE */ |
180 | 180 | ||
181 | |||
182 | static void | ||
183 | xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) | ||
184 | { | ||
185 | if (*qp) { | ||
186 | tic->t_next = (*qp); | ||
187 | tic->t_prev = (*qp)->t_prev; | ||
188 | (*qp)->t_prev->t_next = tic; | ||
189 | (*qp)->t_prev = tic; | ||
190 | } else { | ||
191 | tic->t_prev = tic->t_next = tic; | ||
192 | *qp = tic; | ||
193 | } | ||
194 | |||
195 | tic->t_flags |= XLOG_TIC_IN_Q; | ||
196 | } | ||
197 | |||
198 | static void | ||
199 | xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) | ||
200 | { | ||
201 | if (tic == tic->t_next) { | ||
202 | *qp = NULL; | ||
203 | } else { | ||
204 | *qp = tic->t_next; | ||
205 | tic->t_next->t_prev = tic->t_prev; | ||
206 | tic->t_prev->t_next = tic->t_next; | ||
207 | } | ||
208 | |||
209 | tic->t_next = tic->t_prev = NULL; | ||
210 | tic->t_flags &= ~XLOG_TIC_IN_Q; | ||
211 | } | ||
212 | |||
213 | static void | ||
214 | xlog_grant_sub_space(struct log *log, int bytes) | ||
215 | { | ||
216 | log->l_grant_write_bytes -= bytes; | ||
217 | if (log->l_grant_write_bytes < 0) { | ||
218 | log->l_grant_write_bytes += log->l_logsize; | ||
219 | log->l_grant_write_cycle--; | ||
220 | } | ||
221 | |||
222 | log->l_grant_reserve_bytes -= bytes; | ||
223 | if ((log)->l_grant_reserve_bytes < 0) { | ||
224 | log->l_grant_reserve_bytes += log->l_logsize; | ||
225 | log->l_grant_reserve_cycle--; | ||
226 | } | ||
227 | |||
228 | } | ||
229 | |||
230 | static void | ||
231 | xlog_grant_add_space_write(struct log *log, int bytes) | ||
232 | { | ||
233 | log->l_grant_write_bytes += bytes; | ||
234 | if (log->l_grant_write_bytes > log->l_logsize) { | ||
235 | log->l_grant_write_bytes -= log->l_logsize; | ||
236 | log->l_grant_write_cycle++; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static void | ||
241 | xlog_grant_add_space_reserve(struct log *log, int bytes) | ||
242 | { | ||
243 | log->l_grant_reserve_bytes += bytes; | ||
244 | if (log->l_grant_reserve_bytes > log->l_logsize) { | ||
245 | log->l_grant_reserve_bytes -= log->l_logsize; | ||
246 | log->l_grant_reserve_cycle++; | ||
247 | } | ||
248 | } | ||
249 | |||
250 | static inline void | ||
251 | xlog_grant_add_space(struct log *log, int bytes) | ||
252 | { | ||
253 | xlog_grant_add_space_write(log, bytes); | ||
254 | xlog_grant_add_space_reserve(log, bytes); | ||
255 | } | ||
256 | |||
257 | |||
181 | /* | 258 | /* |
182 | * NOTES: | 259 | * NOTES: |
183 | * | 260 | * |
@@ -1320,8 +1397,7 @@ xlog_sync(xlog_t *log, | |||
1320 | 1397 | ||
1321 | /* move grant heads by roundoff in sync */ | 1398 | /* move grant heads by roundoff in sync */ |
1322 | s = GRANT_LOCK(log); | 1399 | s = GRANT_LOCK(log); |
1323 | XLOG_GRANT_ADD_SPACE(log, roundoff, 'w'); | 1400 | xlog_grant_add_space(log, roundoff); |
1324 | XLOG_GRANT_ADD_SPACE(log, roundoff, 'r'); | ||
1325 | GRANT_UNLOCK(log, s); | 1401 | GRANT_UNLOCK(log, s); |
1326 | 1402 | ||
1327 | /* put cycle number in every block */ | 1403 | /* put cycle number in every block */ |
@@ -2389,7 +2465,7 @@ xlog_grant_log_space(xlog_t *log, | |||
2389 | 2465 | ||
2390 | /* something is already sleeping; insert new transaction at end */ | 2466 | /* something is already sleeping; insert new transaction at end */ |
2391 | if (log->l_reserve_headq) { | 2467 | if (log->l_reserve_headq) { |
2392 | XLOG_INS_TICKETQ(log->l_reserve_headq, tic); | 2468 | xlog_ins_ticketq(&log->l_reserve_headq, tic); |
2393 | xlog_trace_loggrant(log, tic, | 2469 | xlog_trace_loggrant(log, tic, |
2394 | "xlog_grant_log_space: sleep 1"); | 2470 | "xlog_grant_log_space: sleep 1"); |
2395 | /* | 2471 | /* |
@@ -2422,7 +2498,7 @@ redo: | |||
2422 | log->l_grant_reserve_bytes); | 2498 | log->l_grant_reserve_bytes); |
2423 | if (free_bytes < need_bytes) { | 2499 | if (free_bytes < need_bytes) { |
2424 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2500 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) |
2425 | XLOG_INS_TICKETQ(log->l_reserve_headq, tic); | 2501 | xlog_ins_ticketq(&log->l_reserve_headq, tic); |
2426 | xlog_trace_loggrant(log, tic, | 2502 | xlog_trace_loggrant(log, tic, |
2427 | "xlog_grant_log_space: sleep 2"); | 2503 | "xlog_grant_log_space: sleep 2"); |
2428 | XFS_STATS_INC(xs_sleep_logspace); | 2504 | XFS_STATS_INC(xs_sleep_logspace); |
@@ -2439,11 +2515,10 @@ redo: | |||
2439 | s = GRANT_LOCK(log); | 2515 | s = GRANT_LOCK(log); |
2440 | goto redo; | 2516 | goto redo; |
2441 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2517 | } else if (tic->t_flags & XLOG_TIC_IN_Q) |
2442 | XLOG_DEL_TICKETQ(log->l_reserve_headq, tic); | 2518 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
2443 | 2519 | ||
2444 | /* we've got enough space */ | 2520 | /* we've got enough space */ |
2445 | XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); | 2521 | xlog_grant_add_space(log, need_bytes); |
2446 | XLOG_GRANT_ADD_SPACE(log, need_bytes, 'r'); | ||
2447 | #ifdef DEBUG | 2522 | #ifdef DEBUG |
2448 | tail_lsn = log->l_tail_lsn; | 2523 | tail_lsn = log->l_tail_lsn; |
2449 | /* | 2524 | /* |
@@ -2464,7 +2539,7 @@ redo: | |||
2464 | 2539 | ||
2465 | error_return: | 2540 | error_return: |
2466 | if (tic->t_flags & XLOG_TIC_IN_Q) | 2541 | if (tic->t_flags & XLOG_TIC_IN_Q) |
2467 | XLOG_DEL_TICKETQ(log->l_reserve_headq, tic); | 2542 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
2468 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret"); | 2543 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret"); |
2469 | /* | 2544 | /* |
2470 | * If we are failing, make sure the ticket doesn't have any | 2545 | * If we are failing, make sure the ticket doesn't have any |
@@ -2533,7 +2608,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2533 | 2608 | ||
2534 | if (ntic != log->l_write_headq) { | 2609 | if (ntic != log->l_write_headq) { |
2535 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2610 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) |
2536 | XLOG_INS_TICKETQ(log->l_write_headq, tic); | 2611 | xlog_ins_ticketq(&log->l_write_headq, tic); |
2537 | 2612 | ||
2538 | xlog_trace_loggrant(log, tic, | 2613 | xlog_trace_loggrant(log, tic, |
2539 | "xlog_regrant_write_log_space: sleep 1"); | 2614 | "xlog_regrant_write_log_space: sleep 1"); |
@@ -2565,7 +2640,7 @@ redo: | |||
2565 | log->l_grant_write_bytes); | 2640 | log->l_grant_write_bytes); |
2566 | if (free_bytes < need_bytes) { | 2641 | if (free_bytes < need_bytes) { |
2567 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2642 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) |
2568 | XLOG_INS_TICKETQ(log->l_write_headq, tic); | 2643 | xlog_ins_ticketq(&log->l_write_headq, tic); |
2569 | XFS_STATS_INC(xs_sleep_logspace); | 2644 | XFS_STATS_INC(xs_sleep_logspace); |
2570 | sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); | 2645 | sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); |
2571 | 2646 | ||
@@ -2581,9 +2656,10 @@ redo: | |||
2581 | s = GRANT_LOCK(log); | 2656 | s = GRANT_LOCK(log); |
2582 | goto redo; | 2657 | goto redo; |
2583 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2658 | } else if (tic->t_flags & XLOG_TIC_IN_Q) |
2584 | XLOG_DEL_TICKETQ(log->l_write_headq, tic); | 2659 | xlog_del_ticketq(&log->l_write_headq, tic); |
2585 | 2660 | ||
2586 | XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); /* we've got enough space */ | 2661 | /* we've got enough space */ |
2662 | xlog_grant_add_space_write(log, need_bytes); | ||
2587 | #ifdef DEBUG | 2663 | #ifdef DEBUG |
2588 | tail_lsn = log->l_tail_lsn; | 2664 | tail_lsn = log->l_tail_lsn; |
2589 | if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { | 2665 | if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { |
@@ -2600,7 +2676,7 @@ redo: | |||
2600 | 2676 | ||
2601 | error_return: | 2677 | error_return: |
2602 | if (tic->t_flags & XLOG_TIC_IN_Q) | 2678 | if (tic->t_flags & XLOG_TIC_IN_Q) |
2603 | XLOG_DEL_TICKETQ(log->l_reserve_headq, tic); | 2679 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
2604 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret"); | 2680 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret"); |
2605 | /* | 2681 | /* |
2606 | * If we are failing, make sure the ticket doesn't have any | 2682 | * If we are failing, make sure the ticket doesn't have any |
@@ -2633,8 +2709,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2633 | ticket->t_cnt--; | 2709 | ticket->t_cnt--; |
2634 | 2710 | ||
2635 | s = GRANT_LOCK(log); | 2711 | s = GRANT_LOCK(log); |
2636 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); | 2712 | xlog_grant_sub_space(log, ticket->t_curr_res); |
2637 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); | ||
2638 | ticket->t_curr_res = ticket->t_unit_res; | 2713 | ticket->t_curr_res = ticket->t_unit_res; |
2639 | XLOG_TIC_RESET_RES(ticket); | 2714 | XLOG_TIC_RESET_RES(ticket); |
2640 | xlog_trace_loggrant(log, ticket, | 2715 | xlog_trace_loggrant(log, ticket, |
@@ -2647,7 +2722,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2647 | return; | 2722 | return; |
2648 | } | 2723 | } |
2649 | 2724 | ||
2650 | XLOG_GRANT_ADD_SPACE(log, ticket->t_unit_res, 'r'); | 2725 | xlog_grant_add_space_reserve(log, ticket->t_unit_res); |
2651 | xlog_trace_loggrant(log, ticket, | 2726 | xlog_trace_loggrant(log, ticket, |
2652 | "xlog_regrant_reserve_log_space: exit"); | 2727 | "xlog_regrant_reserve_log_space: exit"); |
2653 | xlog_verify_grant_head(log, 0); | 2728 | xlog_verify_grant_head(log, 0); |
@@ -2683,8 +2758,7 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2683 | s = GRANT_LOCK(log); | 2758 | s = GRANT_LOCK(log); |
2684 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); | 2759 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); |
2685 | 2760 | ||
2686 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); | 2761 | xlog_grant_sub_space(log, ticket->t_curr_res); |
2687 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); | ||
2688 | 2762 | ||
2689 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current"); | 2763 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current"); |
2690 | 2764 | ||
@@ -2693,8 +2767,7 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2693 | */ | 2767 | */ |
2694 | if (ticket->t_cnt > 0) { | 2768 | if (ticket->t_cnt > 0) { |
2695 | ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV); | 2769 | ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV); |
2696 | XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'w'); | 2770 | xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt); |
2697 | XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'r'); | ||
2698 | } | 2771 | } |
2699 | 2772 | ||
2700 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); | 2773 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); |