aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r--fs/xfs/xfs_log.c113
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
182static void
183xlog_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
198static void
199xlog_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
213static void
214xlog_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
230static void
231xlog_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
240static void
241xlog_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
250static inline void
251xlog_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");