diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 161 |
1 files changed, 151 insertions, 10 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 42975cb9e538..54a6f1142403 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -159,11 +159,15 @@ xfs_buftarg_t *xlog_target; | |||
159 | void | 159 | void |
160 | xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) | 160 | xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) |
161 | { | 161 | { |
162 | if (! log->l_grant_trace) { | 162 | unsigned long cnts; |
163 | log->l_grant_trace = ktrace_alloc(1024, KM_NOSLEEP); | 163 | |
164 | if (! log->l_grant_trace) | 164 | if (!log->l_grant_trace) { |
165 | log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP); | ||
166 | if (!log->l_grant_trace) | ||
165 | return; | 167 | return; |
166 | } | 168 | } |
169 | /* ticket counts are 1 byte each */ | ||
170 | cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8; | ||
167 | 171 | ||
168 | ktrace_enter(log->l_grant_trace, | 172 | ktrace_enter(log->l_grant_trace, |
169 | (void *)tic, | 173 | (void *)tic, |
@@ -178,10 +182,10 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) | |||
178 | (void *)((unsigned long)CYCLE_LSN(log->l_tail_lsn)), | 182 | (void *)((unsigned long)CYCLE_LSN(log->l_tail_lsn)), |
179 | (void *)((unsigned long)BLOCK_LSN(log->l_tail_lsn)), | 183 | (void *)((unsigned long)BLOCK_LSN(log->l_tail_lsn)), |
180 | (void *)string, | 184 | (void *)string, |
181 | (void *)((unsigned long)13), | 185 | (void *)((unsigned long)tic->t_trans_type), |
182 | (void *)((unsigned long)14), | 186 | (void *)cnts, |
183 | (void *)((unsigned long)15), | 187 | (void *)((unsigned long)tic->t_curr_res), |
184 | (void *)((unsigned long)16)); | 188 | (void *)((unsigned long)tic->t_unit_res)); |
185 | } | 189 | } |
186 | 190 | ||
187 | void | 191 | void |
@@ -274,9 +278,11 @@ xfs_log_done(xfs_mount_t *mp, | |||
274 | * Release ticket if not permanent reservation or a specifc | 278 | * Release ticket if not permanent reservation or a specifc |
275 | * request has been made to release a permanent reservation. | 279 | * request has been made to release a permanent reservation. |
276 | */ | 280 | */ |
281 | xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)"); | ||
277 | xlog_ungrant_log_space(log, ticket); | 282 | xlog_ungrant_log_space(log, ticket); |
278 | xlog_state_put_ticket(log, ticket); | 283 | xlog_state_put_ticket(log, ticket); |
279 | } else { | 284 | } else { |
285 | xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)"); | ||
280 | xlog_regrant_reserve_log_space(log, ticket); | 286 | xlog_regrant_reserve_log_space(log, ticket); |
281 | } | 287 | } |
282 | 288 | ||
@@ -399,7 +405,8 @@ xfs_log_reserve(xfs_mount_t *mp, | |||
399 | int cnt, | 405 | int cnt, |
400 | xfs_log_ticket_t *ticket, | 406 | xfs_log_ticket_t *ticket, |
401 | __uint8_t client, | 407 | __uint8_t client, |
402 | uint flags) | 408 | uint flags, |
409 | uint t_type) | ||
403 | { | 410 | { |
404 | xlog_t *log = mp->m_log; | 411 | xlog_t *log = mp->m_log; |
405 | xlog_ticket_t *internal_ticket; | 412 | xlog_ticket_t *internal_ticket; |
@@ -421,13 +428,19 @@ xfs_log_reserve(xfs_mount_t *mp, | |||
421 | if (*ticket != NULL) { | 428 | if (*ticket != NULL) { |
422 | ASSERT(flags & XFS_LOG_PERM_RESERV); | 429 | ASSERT(flags & XFS_LOG_PERM_RESERV); |
423 | internal_ticket = (xlog_ticket_t *)*ticket; | 430 | internal_ticket = (xlog_ticket_t *)*ticket; |
431 | xlog_trace_loggrant(log, internal_ticket, "xfs_log_reserve: existing ticket (permanent trans)"); | ||
424 | xlog_grant_push_ail(mp, internal_ticket->t_unit_res); | 432 | xlog_grant_push_ail(mp, internal_ticket->t_unit_res); |
425 | retval = xlog_regrant_write_log_space(log, internal_ticket); | 433 | retval = xlog_regrant_write_log_space(log, internal_ticket); |
426 | } else { | 434 | } else { |
427 | /* may sleep if need to allocate more tickets */ | 435 | /* may sleep if need to allocate more tickets */ |
428 | internal_ticket = xlog_ticket_get(log, unit_bytes, cnt, | 436 | internal_ticket = xlog_ticket_get(log, unit_bytes, cnt, |
429 | client, flags); | 437 | client, flags); |
438 | internal_ticket->t_trans_type = t_type; | ||
430 | *ticket = internal_ticket; | 439 | *ticket = internal_ticket; |
440 | xlog_trace_loggrant(log, internal_ticket, | ||
441 | (internal_ticket->t_flags & XLOG_TIC_PERM_RESERV) ? | ||
442 | "xfs_log_reserve: create new ticket (permanent trans)" : | ||
443 | "xfs_log_reserve: create new ticket"); | ||
431 | xlog_grant_push_ail(mp, | 444 | xlog_grant_push_ail(mp, |
432 | (internal_ticket->t_unit_res * | 445 | (internal_ticket->t_unit_res * |
433 | internal_ticket->t_cnt)); | 446 | internal_ticket->t_cnt)); |
@@ -601,8 +614,9 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
601 | if (! (XLOG_FORCED_SHUTDOWN(log))) { | 614 | if (! (XLOG_FORCED_SHUTDOWN(log))) { |
602 | reg[0].i_addr = (void*)&magic; | 615 | reg[0].i_addr = (void*)&magic; |
603 | reg[0].i_len = sizeof(magic); | 616 | reg[0].i_len = sizeof(magic); |
617 | XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_UNMOUNT); | ||
604 | 618 | ||
605 | error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0); | 619 | error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0); |
606 | if (!error) { | 620 | if (!error) { |
607 | /* remove inited flag */ | 621 | /* remove inited flag */ |
608 | ((xlog_ticket_t *)tic)->t_flags = 0; | 622 | ((xlog_ticket_t *)tic)->t_flags = 0; |
@@ -1272,6 +1286,7 @@ xlog_commit_record(xfs_mount_t *mp, | |||
1272 | 1286 | ||
1273 | reg[0].i_addr = NULL; | 1287 | reg[0].i_addr = NULL; |
1274 | reg[0].i_len = 0; | 1288 | reg[0].i_len = 0; |
1289 | XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_COMMIT); | ||
1275 | 1290 | ||
1276 | ASSERT_ALWAYS(iclog); | 1291 | ASSERT_ALWAYS(iclog); |
1277 | if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, | 1292 | if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, |
@@ -1605,6 +1620,117 @@ xlog_state_finish_copy(xlog_t *log, | |||
1605 | 1620 | ||
1606 | 1621 | ||
1607 | /* | 1622 | /* |
1623 | * print out info relating to regions written which consume | ||
1624 | * the reservation | ||
1625 | */ | ||
1626 | #if defined(XFS_LOG_RES_DEBUG) | ||
1627 | STATIC void | ||
1628 | xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) | ||
1629 | { | ||
1630 | uint i; | ||
1631 | uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t); | ||
1632 | |||
1633 | /* match with XLOG_REG_TYPE_* in xfs_log.h */ | ||
1634 | static char *res_type_str[XLOG_REG_TYPE_MAX] = { | ||
1635 | "bformat", | ||
1636 | "bchunk", | ||
1637 | "efi_format", | ||
1638 | "efd_format", | ||
1639 | "iformat", | ||
1640 | "icore", | ||
1641 | "iext", | ||
1642 | "ibroot", | ||
1643 | "ilocal", | ||
1644 | "iattr_ext", | ||
1645 | "iattr_broot", | ||
1646 | "iattr_local", | ||
1647 | "qformat", | ||
1648 | "dquot", | ||
1649 | "quotaoff", | ||
1650 | "LR header", | ||
1651 | "unmount", | ||
1652 | "commit", | ||
1653 | "trans header" | ||
1654 | }; | ||
1655 | static char *trans_type_str[XFS_TRANS_TYPE_MAX] = { | ||
1656 | "SETATTR_NOT_SIZE", | ||
1657 | "SETATTR_SIZE", | ||
1658 | "INACTIVE", | ||
1659 | "CREATE", | ||
1660 | "CREATE_TRUNC", | ||
1661 | "TRUNCATE_FILE", | ||
1662 | "REMOVE", | ||
1663 | "LINK", | ||
1664 | "RENAME", | ||
1665 | "MKDIR", | ||
1666 | "RMDIR", | ||
1667 | "SYMLINK", | ||
1668 | "SET_DMATTRS", | ||
1669 | "GROWFS", | ||
1670 | "STRAT_WRITE", | ||
1671 | "DIOSTRAT", | ||
1672 | "WRITE_SYNC", | ||
1673 | "WRITEID", | ||
1674 | "ADDAFORK", | ||
1675 | "ATTRINVAL", | ||
1676 | "ATRUNCATE", | ||
1677 | "ATTR_SET", | ||
1678 | "ATTR_RM", | ||
1679 | "ATTR_FLAG", | ||
1680 | "CLEAR_AGI_BUCKET", | ||
1681 | "QM_SBCHANGE", | ||
1682 | "DUMMY1", | ||
1683 | "DUMMY2", | ||
1684 | "QM_QUOTAOFF", | ||
1685 | "QM_DQALLOC", | ||
1686 | "QM_SETQLIM", | ||
1687 | "QM_DQCLUSTER", | ||
1688 | "QM_QINOCREATE", | ||
1689 | "QM_QUOTAOFF_END", | ||
1690 | "SB_UNIT", | ||
1691 | "FSYNC_TS", | ||
1692 | "GROWFSRT_ALLOC", | ||
1693 | "GROWFSRT_ZERO", | ||
1694 | "GROWFSRT_FREE", | ||
1695 | "SWAPEXT" | ||
1696 | }; | ||
1697 | |||
1698 | xfs_fs_cmn_err(CE_WARN, mp, | ||
1699 | "xfs_log_write: reservation summary:\n" | ||
1700 | " trans type = %s (%u)\n" | ||
1701 | " unit res = %d bytes\n" | ||
1702 | " current res = %d bytes\n" | ||
1703 | " total reg = %u bytes (o/flow = %u bytes)\n" | ||
1704 | " ophdrs = %u (ophdr space = %u bytes)\n" | ||
1705 | " ophdr + reg = %u bytes\n" | ||
1706 | " num regions = %u\n", | ||
1707 | ((ticket->t_trans_type <= 0 || | ||
1708 | ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ? | ||
1709 | "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]), | ||
1710 | ticket->t_trans_type, | ||
1711 | ticket->t_unit_res, | ||
1712 | ticket->t_curr_res, | ||
1713 | ticket->t_res_arr_sum, ticket->t_res_o_flow, | ||
1714 | ticket->t_res_num_ophdrs, ophdr_spc, | ||
1715 | ticket->t_res_arr_sum + | ||
1716 | ticket->t_res_o_flow + ophdr_spc, | ||
1717 | ticket->t_res_num); | ||
1718 | |||
1719 | for (i = 0; i < ticket->t_res_num; i++) { | ||
1720 | uint r_type = ticket->t_res_arr[i].r_type; | ||
1721 | cmn_err(CE_WARN, | ||
1722 | "region[%u]: %s - %u bytes\n", | ||
1723 | i, | ||
1724 | ((r_type <= 0 || r_type > XLOG_REG_TYPE_MAX) ? | ||
1725 | "bad-rtype" : res_type_str[r_type-1]), | ||
1726 | ticket->t_res_arr[i].r_len); | ||
1727 | } | ||
1728 | } | ||
1729 | #else | ||
1730 | #define xlog_print_tic_res(mp, ticket) | ||
1731 | #endif | ||
1732 | |||
1733 | /* | ||
1608 | * Write some region out to in-core log | 1734 | * Write some region out to in-core log |
1609 | * | 1735 | * |
1610 | * This will be called when writing externally provided regions or when | 1736 | * This will be called when writing externally provided regions or when |
@@ -1677,16 +1803,21 @@ xlog_write(xfs_mount_t * mp, | |||
1677 | * xlog_op_header_t and may need to be double word aligned. | 1803 | * xlog_op_header_t and may need to be double word aligned. |
1678 | */ | 1804 | */ |
1679 | len = 0; | 1805 | len = 0; |
1680 | if (ticket->t_flags & XLOG_TIC_INITED) /* acct for start rec of xact */ | 1806 | if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */ |
1681 | len += sizeof(xlog_op_header_t); | 1807 | len += sizeof(xlog_op_header_t); |
1808 | XLOG_TIC_ADD_OPHDR(ticket); | ||
1809 | } | ||
1682 | 1810 | ||
1683 | for (index = 0; index < nentries; index++) { | 1811 | for (index = 0; index < nentries; index++) { |
1684 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ | 1812 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ |
1813 | XLOG_TIC_ADD_OPHDR(ticket); | ||
1685 | len += reg[index].i_len; | 1814 | len += reg[index].i_len; |
1815 | XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type); | ||
1686 | } | 1816 | } |
1687 | contwr = *start_lsn = 0; | 1817 | contwr = *start_lsn = 0; |
1688 | 1818 | ||
1689 | if (ticket->t_curr_res < len) { | 1819 | if (ticket->t_curr_res < len) { |
1820 | xlog_print_tic_res(mp, ticket); | ||
1690 | #ifdef DEBUG | 1821 | #ifdef DEBUG |
1691 | xlog_panic( | 1822 | xlog_panic( |
1692 | "xfs_log_write: reservation ran out. Need to up reservation"); | 1823 | "xfs_log_write: reservation ran out. Need to up reservation"); |
@@ -1790,6 +1921,7 @@ xlog_write(xfs_mount_t * mp, | |||
1790 | len += sizeof(xlog_op_header_t); /* from splitting of region */ | 1921 | len += sizeof(xlog_op_header_t); /* from splitting of region */ |
1791 | /* account for new log op header */ | 1922 | /* account for new log op header */ |
1792 | ticket->t_curr_res -= sizeof(xlog_op_header_t); | 1923 | ticket->t_curr_res -= sizeof(xlog_op_header_t); |
1924 | XLOG_TIC_ADD_OPHDR(ticket); | ||
1793 | } | 1925 | } |
1794 | xlog_verify_dest_ptr(log, ptr); | 1926 | xlog_verify_dest_ptr(log, ptr); |
1795 | 1927 | ||
@@ -2282,6 +2414,9 @@ restart: | |||
2282 | */ | 2414 | */ |
2283 | if (log_offset == 0) { | 2415 | if (log_offset == 0) { |
2284 | ticket->t_curr_res -= log->l_iclog_hsize; | 2416 | ticket->t_curr_res -= log->l_iclog_hsize; |
2417 | XLOG_TIC_ADD_REGION(ticket, | ||
2418 | log->l_iclog_hsize, | ||
2419 | XLOG_REG_TYPE_LRHEADER); | ||
2285 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); | 2420 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); |
2286 | ASSIGN_LSN(head->h_lsn, log); | 2421 | ASSIGN_LSN(head->h_lsn, log); |
2287 | ASSERT(log->l_curr_block >= 0); | 2422 | ASSERT(log->l_curr_block >= 0); |
@@ -2468,6 +2603,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2468 | #endif | 2603 | #endif |
2469 | 2604 | ||
2470 | tic->t_curr_res = tic->t_unit_res; | 2605 | tic->t_curr_res = tic->t_unit_res; |
2606 | XLOG_TIC_RESET_RES(tic); | ||
2471 | 2607 | ||
2472 | if (tic->t_cnt > 0) | 2608 | if (tic->t_cnt > 0) |
2473 | return (0); | 2609 | return (0); |
@@ -2608,6 +2744,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2608 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); | 2744 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); |
2609 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); | 2745 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); |
2610 | ticket->t_curr_res = ticket->t_unit_res; | 2746 | ticket->t_curr_res = ticket->t_unit_res; |
2747 | XLOG_TIC_RESET_RES(ticket); | ||
2611 | xlog_trace_loggrant(log, ticket, | 2748 | xlog_trace_loggrant(log, ticket, |
2612 | "xlog_regrant_reserve_log_space: sub current res"); | 2749 | "xlog_regrant_reserve_log_space: sub current res"); |
2613 | xlog_verify_grant_head(log, 1); | 2750 | xlog_verify_grant_head(log, 1); |
@@ -2624,6 +2761,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2624 | xlog_verify_grant_head(log, 0); | 2761 | xlog_verify_grant_head(log, 0); |
2625 | GRANT_UNLOCK(log, s); | 2762 | GRANT_UNLOCK(log, s); |
2626 | ticket->t_curr_res = ticket->t_unit_res; | 2763 | ticket->t_curr_res = ticket->t_unit_res; |
2764 | XLOG_TIC_RESET_RES(ticket); | ||
2627 | } /* xlog_regrant_reserve_log_space */ | 2765 | } /* xlog_regrant_reserve_log_space */ |
2628 | 2766 | ||
2629 | 2767 | ||
@@ -3237,10 +3375,13 @@ xlog_ticket_get(xlog_t *log, | |||
3237 | tic->t_tid = (xlog_tid_t)((__psint_t)tic & 0xffffffff); | 3375 | tic->t_tid = (xlog_tid_t)((__psint_t)tic & 0xffffffff); |
3238 | tic->t_clientid = client; | 3376 | tic->t_clientid = client; |
3239 | tic->t_flags = XLOG_TIC_INITED; | 3377 | tic->t_flags = XLOG_TIC_INITED; |
3378 | tic->t_trans_type = 0; | ||
3240 | if (xflags & XFS_LOG_PERM_RESERV) | 3379 | if (xflags & XFS_LOG_PERM_RESERV) |
3241 | tic->t_flags |= XLOG_TIC_PERM_RESERV; | 3380 | tic->t_flags |= XLOG_TIC_PERM_RESERV; |
3242 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); | 3381 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); |
3243 | 3382 | ||
3383 | XLOG_TIC_RESET_RES(tic); | ||
3384 | |||
3244 | return tic; | 3385 | return tic; |
3245 | } /* xlog_ticket_get */ | 3386 | } /* xlog_ticket_get */ |
3246 | 3387 | ||