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"); |
