diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 123 |
1 files changed, 96 insertions, 27 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 29af51275ca9..3d9a36e77363 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 | * |
@@ -428,7 +505,7 @@ xfs_log_mount(xfs_mount_t *mp, | |||
428 | if (readonly) | 505 | if (readonly) |
429 | vfsp->vfs_flag &= ~VFS_RDONLY; | 506 | vfsp->vfs_flag &= ~VFS_RDONLY; |
430 | 507 | ||
431 | error = xlog_recover(mp->m_log, readonly); | 508 | error = xlog_recover(mp->m_log); |
432 | 509 | ||
433 | if (readonly) | 510 | if (readonly) |
434 | vfsp->vfs_flag |= VFS_RDONLY; | 511 | vfsp->vfs_flag |= VFS_RDONLY; |
@@ -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 */ |
@@ -1515,7 +1591,6 @@ xlog_state_finish_copy(xlog_t *log, | |||
1515 | * print out info relating to regions written which consume | 1591 | * print out info relating to regions written which consume |
1516 | * the reservation | 1592 | * the reservation |
1517 | */ | 1593 | */ |
1518 | #if defined(XFS_LOG_RES_DEBUG) | ||
1519 | STATIC void | 1594 | STATIC void |
1520 | xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) | 1595 | xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) |
1521 | { | 1596 | { |
@@ -1605,11 +1680,11 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) | |||
1605 | ticket->t_res_arr_sum, ticket->t_res_o_flow, | 1680 | ticket->t_res_arr_sum, ticket->t_res_o_flow, |
1606 | ticket->t_res_num_ophdrs, ophdr_spc, | 1681 | ticket->t_res_num_ophdrs, ophdr_spc, |
1607 | ticket->t_res_arr_sum + | 1682 | ticket->t_res_arr_sum + |
1608 | ticket->t_res_o_flow + ophdr_spc, | 1683 | ticket->t_res_o_flow + ophdr_spc, |
1609 | ticket->t_res_num); | 1684 | ticket->t_res_num); |
1610 | 1685 | ||
1611 | for (i = 0; i < ticket->t_res_num; i++) { | 1686 | for (i = 0; i < ticket->t_res_num; i++) { |
1612 | uint r_type = ticket->t_res_arr[i].r_type; | 1687 | uint r_type = ticket->t_res_arr[i].r_type; |
1613 | cmn_err(CE_WARN, | 1688 | cmn_err(CE_WARN, |
1614 | "region[%u]: %s - %u bytes\n", | 1689 | "region[%u]: %s - %u bytes\n", |
1615 | i, | 1690 | i, |
@@ -1618,9 +1693,6 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) | |||
1618 | ticket->t_res_arr[i].r_len); | 1693 | ticket->t_res_arr[i].r_len); |
1619 | } | 1694 | } |
1620 | } | 1695 | } |
1621 | #else | ||
1622 | #define xlog_print_tic_res(mp, ticket) | ||
1623 | #endif | ||
1624 | 1696 | ||
1625 | /* | 1697 | /* |
1626 | * Write some region out to in-core log | 1698 | * Write some region out to in-core log |
@@ -2389,7 +2461,7 @@ xlog_grant_log_space(xlog_t *log, | |||
2389 | 2461 | ||
2390 | /* something is already sleeping; insert new transaction at end */ | 2462 | /* something is already sleeping; insert new transaction at end */ |
2391 | if (log->l_reserve_headq) { | 2463 | if (log->l_reserve_headq) { |
2392 | XLOG_INS_TICKETQ(log->l_reserve_headq, tic); | 2464 | xlog_ins_ticketq(&log->l_reserve_headq, tic); |
2393 | xlog_trace_loggrant(log, tic, | 2465 | xlog_trace_loggrant(log, tic, |
2394 | "xlog_grant_log_space: sleep 1"); | 2466 | "xlog_grant_log_space: sleep 1"); |
2395 | /* | 2467 | /* |
@@ -2422,7 +2494,7 @@ redo: | |||
2422 | log->l_grant_reserve_bytes); | 2494 | log->l_grant_reserve_bytes); |
2423 | if (free_bytes < need_bytes) { | 2495 | if (free_bytes < need_bytes) { |
2424 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2496 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) |
2425 | XLOG_INS_TICKETQ(log->l_reserve_headq, tic); | 2497 | xlog_ins_ticketq(&log->l_reserve_headq, tic); |
2426 | xlog_trace_loggrant(log, tic, | 2498 | xlog_trace_loggrant(log, tic, |
2427 | "xlog_grant_log_space: sleep 2"); | 2499 | "xlog_grant_log_space: sleep 2"); |
2428 | XFS_STATS_INC(xs_sleep_logspace); | 2500 | XFS_STATS_INC(xs_sleep_logspace); |
@@ -2439,11 +2511,10 @@ redo: | |||
2439 | s = GRANT_LOCK(log); | 2511 | s = GRANT_LOCK(log); |
2440 | goto redo; | 2512 | goto redo; |
2441 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2513 | } else if (tic->t_flags & XLOG_TIC_IN_Q) |
2442 | XLOG_DEL_TICKETQ(log->l_reserve_headq, tic); | 2514 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
2443 | 2515 | ||
2444 | /* we've got enough space */ | 2516 | /* we've got enough space */ |
2445 | XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); | 2517 | xlog_grant_add_space(log, need_bytes); |
2446 | XLOG_GRANT_ADD_SPACE(log, need_bytes, 'r'); | ||
2447 | #ifdef DEBUG | 2518 | #ifdef DEBUG |
2448 | tail_lsn = log->l_tail_lsn; | 2519 | tail_lsn = log->l_tail_lsn; |
2449 | /* | 2520 | /* |
@@ -2464,7 +2535,7 @@ redo: | |||
2464 | 2535 | ||
2465 | error_return: | 2536 | error_return: |
2466 | if (tic->t_flags & XLOG_TIC_IN_Q) | 2537 | if (tic->t_flags & XLOG_TIC_IN_Q) |
2467 | XLOG_DEL_TICKETQ(log->l_reserve_headq, tic); | 2538 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
2468 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret"); | 2539 | xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret"); |
2469 | /* | 2540 | /* |
2470 | * If we are failing, make sure the ticket doesn't have any | 2541 | * If we are failing, make sure the ticket doesn't have any |
@@ -2533,7 +2604,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2533 | 2604 | ||
2534 | if (ntic != log->l_write_headq) { | 2605 | if (ntic != log->l_write_headq) { |
2535 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2606 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) |
2536 | XLOG_INS_TICKETQ(log->l_write_headq, tic); | 2607 | xlog_ins_ticketq(&log->l_write_headq, tic); |
2537 | 2608 | ||
2538 | xlog_trace_loggrant(log, tic, | 2609 | xlog_trace_loggrant(log, tic, |
2539 | "xlog_regrant_write_log_space: sleep 1"); | 2610 | "xlog_regrant_write_log_space: sleep 1"); |
@@ -2565,7 +2636,7 @@ redo: | |||
2565 | log->l_grant_write_bytes); | 2636 | log->l_grant_write_bytes); |
2566 | if (free_bytes < need_bytes) { | 2637 | if (free_bytes < need_bytes) { |
2567 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) | 2638 | if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) |
2568 | XLOG_INS_TICKETQ(log->l_write_headq, tic); | 2639 | xlog_ins_ticketq(&log->l_write_headq, tic); |
2569 | XFS_STATS_INC(xs_sleep_logspace); | 2640 | XFS_STATS_INC(xs_sleep_logspace); |
2570 | sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); | 2641 | sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s); |
2571 | 2642 | ||
@@ -2581,9 +2652,10 @@ redo: | |||
2581 | s = GRANT_LOCK(log); | 2652 | s = GRANT_LOCK(log); |
2582 | goto redo; | 2653 | goto redo; |
2583 | } else if (tic->t_flags & XLOG_TIC_IN_Q) | 2654 | } else if (tic->t_flags & XLOG_TIC_IN_Q) |
2584 | XLOG_DEL_TICKETQ(log->l_write_headq, tic); | 2655 | xlog_del_ticketq(&log->l_write_headq, tic); |
2585 | 2656 | ||
2586 | XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); /* we've got enough space */ | 2657 | /* we've got enough space */ |
2658 | xlog_grant_add_space_write(log, need_bytes); | ||
2587 | #ifdef DEBUG | 2659 | #ifdef DEBUG |
2588 | tail_lsn = log->l_tail_lsn; | 2660 | tail_lsn = log->l_tail_lsn; |
2589 | if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { | 2661 | if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { |
@@ -2600,7 +2672,7 @@ redo: | |||
2600 | 2672 | ||
2601 | error_return: | 2673 | error_return: |
2602 | if (tic->t_flags & XLOG_TIC_IN_Q) | 2674 | if (tic->t_flags & XLOG_TIC_IN_Q) |
2603 | XLOG_DEL_TICKETQ(log->l_reserve_headq, tic); | 2675 | xlog_del_ticketq(&log->l_reserve_headq, tic); |
2604 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret"); | 2676 | xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret"); |
2605 | /* | 2677 | /* |
2606 | * If we are failing, make sure the ticket doesn't have any | 2678 | * If we are failing, make sure the ticket doesn't have any |
@@ -2633,8 +2705,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2633 | ticket->t_cnt--; | 2705 | ticket->t_cnt--; |
2634 | 2706 | ||
2635 | s = GRANT_LOCK(log); | 2707 | s = GRANT_LOCK(log); |
2636 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); | 2708 | 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; | 2709 | ticket->t_curr_res = ticket->t_unit_res; |
2639 | XLOG_TIC_RESET_RES(ticket); | 2710 | XLOG_TIC_RESET_RES(ticket); |
2640 | xlog_trace_loggrant(log, ticket, | 2711 | xlog_trace_loggrant(log, ticket, |
@@ -2647,7 +2718,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2647 | return; | 2718 | return; |
2648 | } | 2719 | } |
2649 | 2720 | ||
2650 | XLOG_GRANT_ADD_SPACE(log, ticket->t_unit_res, 'r'); | 2721 | xlog_grant_add_space_reserve(log, ticket->t_unit_res); |
2651 | xlog_trace_loggrant(log, ticket, | 2722 | xlog_trace_loggrant(log, ticket, |
2652 | "xlog_regrant_reserve_log_space: exit"); | 2723 | "xlog_regrant_reserve_log_space: exit"); |
2653 | xlog_verify_grant_head(log, 0); | 2724 | xlog_verify_grant_head(log, 0); |
@@ -2683,8 +2754,7 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2683 | s = GRANT_LOCK(log); | 2754 | s = GRANT_LOCK(log); |
2684 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); | 2755 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); |
2685 | 2756 | ||
2686 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); | 2757 | xlog_grant_sub_space(log, ticket->t_curr_res); |
2687 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); | ||
2688 | 2758 | ||
2689 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current"); | 2759 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current"); |
2690 | 2760 | ||
@@ -2693,8 +2763,7 @@ xlog_ungrant_log_space(xlog_t *log, | |||
2693 | */ | 2763 | */ |
2694 | if (ticket->t_cnt > 0) { | 2764 | if (ticket->t_cnt > 0) { |
2695 | ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV); | 2765 | ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV); |
2696 | XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'w'); | 2766 | 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 | } | 2767 | } |
2699 | 2768 | ||
2700 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); | 2769 | xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); |