Commit 7e9c63961558092d584936a874cf3fee80002eb6
Committed by
Nathan Scott
1 parent
32fb9b57ae
[XFS] 929956 add log debugging and tracing info
SGI-PV: 931456 SGI-Modid: xfs-linux:xfs-kern:23155a Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Showing 9 changed files with 265 additions and 22 deletions Side-by-side Diff
fs/xfs/quota/xfs_dquot_item.c
fs/xfs/xfs_buf_item.c
... | ... | @@ -274,6 +274,7 @@ |
274 | 274 | ((bip->bli_format.blf_map_size - 1) * sizeof(uint))); |
275 | 275 | vecp->i_addr = (xfs_caddr_t)&bip->bli_format; |
276 | 276 | vecp->i_len = base_size; |
277 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BFORMAT); | |
277 | 278 | vecp++; |
278 | 279 | nvecs = 1; |
279 | 280 | |
280 | 281 | |
... | ... | @@ -320,12 +321,14 @@ |
320 | 321 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
321 | 322 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
322 | 323 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
324 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | |
323 | 325 | nvecs++; |
324 | 326 | break; |
325 | 327 | } else if (next_bit != last_bit + 1) { |
326 | 328 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
327 | 329 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
328 | 330 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
331 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | |
329 | 332 | nvecs++; |
330 | 333 | vecp++; |
331 | 334 | first_bit = next_bit; |
... | ... | @@ -337,6 +340,7 @@ |
337 | 340 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
338 | 341 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
339 | 342 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
343 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | |
340 | 344 | /* You would think we need to bump the nvecs here too, but we do not |
341 | 345 | * this number is used by recovery, and it gets confused by the boundary |
342 | 346 | * split here |
fs/xfs/xfs_extfree_item.c
... | ... | @@ -107,6 +107,7 @@ |
107 | 107 | |
108 | 108 | log_vector->i_addr = (xfs_caddr_t)&(efip->efi_format); |
109 | 109 | log_vector->i_len = size; |
110 | + XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_EFI_FORMAT); | |
110 | 111 | ASSERT(size >= sizeof(xfs_efi_log_format_t)); |
111 | 112 | } |
112 | 113 | |
... | ... | @@ -426,6 +427,7 @@ |
426 | 427 | |
427 | 428 | log_vector->i_addr = (xfs_caddr_t)&(efdp->efd_format); |
428 | 429 | log_vector->i_len = size; |
430 | + XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_EFD_FORMAT); | |
429 | 431 | ASSERT(size >= sizeof(xfs_efd_log_format_t)); |
430 | 432 | } |
431 | 433 |
fs/xfs/xfs_inode_item.c
... | ... | @@ -248,6 +248,7 @@ |
248 | 248 | |
249 | 249 | vecp->i_addr = (xfs_caddr_t)&iip->ili_format; |
250 | 250 | vecp->i_len = sizeof(xfs_inode_log_format_t); |
251 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IFORMAT); | |
251 | 252 | vecp++; |
252 | 253 | nvecs = 1; |
253 | 254 | |
... | ... | @@ -292,6 +293,7 @@ |
292 | 293 | |
293 | 294 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; |
294 | 295 | vecp->i_len = sizeof(xfs_dinode_core_t); |
296 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); | |
295 | 297 | vecp++; |
296 | 298 | nvecs++; |
297 | 299 | iip->ili_format.ilf_fields |= XFS_ILOG_CORE; |
... | ... | @@ -349,6 +351,7 @@ |
349 | 351 | vecp->i_addr = |
350 | 352 | (char *)(ip->i_df.if_u1.if_extents); |
351 | 353 | vecp->i_len = ip->i_df.if_bytes; |
354 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IEXT); | |
352 | 355 | } else |
353 | 356 | #endif |
354 | 357 | { |
... | ... | @@ -367,6 +370,7 @@ |
367 | 370 | vecp->i_addr = (xfs_caddr_t)ext_buffer; |
368 | 371 | vecp->i_len = xfs_iextents_copy(ip, ext_buffer, |
369 | 372 | XFS_DATA_FORK); |
373 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IEXT); | |
370 | 374 | } |
371 | 375 | ASSERT(vecp->i_len <= ip->i_df.if_bytes); |
372 | 376 | iip->ili_format.ilf_dsize = vecp->i_len; |
... | ... | @@ -384,6 +388,7 @@ |
384 | 388 | ASSERT(ip->i_df.if_broot != NULL); |
385 | 389 | vecp->i_addr = (xfs_caddr_t)ip->i_df.if_broot; |
386 | 390 | vecp->i_len = ip->i_df.if_broot_bytes; |
391 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IBROOT); | |
387 | 392 | vecp++; |
388 | 393 | nvecs++; |
389 | 394 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; |
... | ... | @@ -409,6 +414,7 @@ |
409 | 414 | ASSERT((ip->i_df.if_real_bytes == 0) || |
410 | 415 | (ip->i_df.if_real_bytes == data_bytes)); |
411 | 416 | vecp->i_len = (int)data_bytes; |
417 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ILOCAL); | |
412 | 418 | vecp++; |
413 | 419 | nvecs++; |
414 | 420 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; |
... | ... | @@ -486,6 +492,7 @@ |
486 | 492 | vecp->i_len = xfs_iextents_copy(ip, ext_buffer, |
487 | 493 | XFS_ATTR_FORK); |
488 | 494 | #endif |
495 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_EXT); | |
489 | 496 | iip->ili_format.ilf_asize = vecp->i_len; |
490 | 497 | vecp++; |
491 | 498 | nvecs++; |
... | ... | @@ -500,6 +507,7 @@ |
500 | 507 | ASSERT(ip->i_afp->if_broot != NULL); |
501 | 508 | vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_broot; |
502 | 509 | vecp->i_len = ip->i_afp->if_broot_bytes; |
510 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_BROOT); | |
503 | 511 | vecp++; |
504 | 512 | nvecs++; |
505 | 513 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; |
... | ... | @@ -523,6 +531,7 @@ |
523 | 531 | ASSERT((ip->i_afp->if_real_bytes == 0) || |
524 | 532 | (ip->i_afp->if_real_bytes == data_bytes)); |
525 | 533 | vecp->i_len = (int)data_bytes; |
534 | + XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_LOCAL); | |
526 | 535 | vecp++; |
527 | 536 | nvecs++; |
528 | 537 | iip->ili_format.ilf_asize = (unsigned)data_bytes; |
fs/xfs/xfs_log.c
... | ... | @@ -159,11 +159,15 @@ |
159 | 159 | void |
160 | 160 | xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) |
161 | 161 | { |
162 | - if (! log->l_grant_trace) { | |
163 | - log->l_grant_trace = ktrace_alloc(1024, KM_NOSLEEP); | |
164 | - if (! log->l_grant_trace) | |
162 | + unsigned long cnts; | |
163 | + | |
164 | + if (!log->l_grant_trace) { | |
165 | + log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP); | |
166 | + if (!log->l_grant_trace) | |
165 | 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 | 172 | ktrace_enter(log->l_grant_trace, |
169 | 173 | (void *)tic, |
... | ... | @@ -178,10 +182,10 @@ |
178 | 182 | (void *)((unsigned long)CYCLE_LSN(log->l_tail_lsn)), |
179 | 183 | (void *)((unsigned long)BLOCK_LSN(log->l_tail_lsn)), |
180 | 184 | (void *)string, |
181 | - (void *)((unsigned long)13), | |
182 | - (void *)((unsigned long)14), | |
183 | - (void *)((unsigned long)15), | |
184 | - (void *)((unsigned long)16)); | |
185 | + (void *)((unsigned long)tic->t_trans_type), | |
186 | + (void *)cnts, | |
187 | + (void *)((unsigned long)tic->t_curr_res), | |
188 | + (void *)((unsigned long)tic->t_unit_res)); | |
185 | 189 | } |
186 | 190 | |
187 | 191 | void |
188 | 192 | |
... | ... | @@ -274,9 +278,11 @@ |
274 | 278 | * Release ticket if not permanent reservation or a specifc |
275 | 279 | * request has been made to release a permanent reservation. |
276 | 280 | */ |
281 | + xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)"); | |
277 | 282 | xlog_ungrant_log_space(log, ticket); |
278 | 283 | xlog_state_put_ticket(log, ticket); |
279 | 284 | } else { |
285 | + xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)"); | |
280 | 286 | xlog_regrant_reserve_log_space(log, ticket); |
281 | 287 | } |
282 | 288 | |
... | ... | @@ -399,7 +405,8 @@ |
399 | 405 | int cnt, |
400 | 406 | xfs_log_ticket_t *ticket, |
401 | 407 | __uint8_t client, |
402 | - uint flags) | |
408 | + uint flags, | |
409 | + uint t_type) | |
403 | 410 | { |
404 | 411 | xlog_t *log = mp->m_log; |
405 | 412 | xlog_ticket_t *internal_ticket; |
406 | 413 | |
407 | 414 | |
... | ... | @@ -421,13 +428,19 @@ |
421 | 428 | if (*ticket != NULL) { |
422 | 429 | ASSERT(flags & XFS_LOG_PERM_RESERV); |
423 | 430 | internal_ticket = (xlog_ticket_t *)*ticket; |
431 | + xlog_trace_loggrant(log, internal_ticket, "xfs_log_reserve: existing ticket (permanent trans)"); | |
424 | 432 | xlog_grant_push_ail(mp, internal_ticket->t_unit_res); |
425 | 433 | retval = xlog_regrant_write_log_space(log, internal_ticket); |
426 | 434 | } else { |
427 | 435 | /* may sleep if need to allocate more tickets */ |
428 | 436 | internal_ticket = xlog_ticket_get(log, unit_bytes, cnt, |
429 | 437 | client, flags); |
438 | + internal_ticket->t_trans_type = t_type; | |
430 | 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 | 444 | xlog_grant_push_ail(mp, |
432 | 445 | (internal_ticket->t_unit_res * |
433 | 446 | internal_ticket->t_cnt)); |
434 | 447 | |
... | ... | @@ -601,8 +614,9 @@ |
601 | 614 | if (! (XLOG_FORCED_SHUTDOWN(log))) { |
602 | 615 | reg[0].i_addr = (void*)&magic; |
603 | 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 | 620 | if (!error) { |
607 | 621 | /* remove inited flag */ |
608 | 622 | ((xlog_ticket_t *)tic)->t_flags = 0; |
... | ... | @@ -1272,6 +1286,7 @@ |
1272 | 1286 | |
1273 | 1287 | reg[0].i_addr = NULL; |
1274 | 1288 | reg[0].i_len = 0; |
1289 | + XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_COMMIT); | |
1275 | 1290 | |
1276 | 1291 | ASSERT_ALWAYS(iclog); |
1277 | 1292 | if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, |
... | ... | @@ -1605,6 +1620,117 @@ |
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 | 1734 | * Write some region out to in-core log |
1609 | 1735 | * |
1610 | 1736 | * This will be called when writing externally provided regions or when |
1611 | 1737 | |
1612 | 1738 | |
1613 | 1739 | |
1614 | 1740 | |
... | ... | @@ -1677,16 +1803,21 @@ |
1677 | 1803 | * xlog_op_header_t and may need to be double word aligned. |
1678 | 1804 | */ |
1679 | 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 | 1807 | len += sizeof(xlog_op_header_t); |
1808 | + XLOG_TIC_ADD_OPHDR(ticket); | |
1809 | + } | |
1682 | 1810 | |
1683 | 1811 | for (index = 0; index < nentries; index++) { |
1684 | 1812 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ |
1813 | + XLOG_TIC_ADD_OPHDR(ticket); | |
1685 | 1814 | len += reg[index].i_len; |
1815 | + XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type); | |
1686 | 1816 | } |
1687 | 1817 | contwr = *start_lsn = 0; |
1688 | 1818 | |
1689 | 1819 | if (ticket->t_curr_res < len) { |
1820 | + xlog_print_tic_res(mp, ticket); | |
1690 | 1821 | #ifdef DEBUG |
1691 | 1822 | xlog_panic( |
1692 | 1823 | "xfs_log_write: reservation ran out. Need to up reservation"); |
... | ... | @@ -1790,6 +1921,7 @@ |
1790 | 1921 | len += sizeof(xlog_op_header_t); /* from splitting of region */ |
1791 | 1922 | /* account for new log op header */ |
1792 | 1923 | ticket->t_curr_res -= sizeof(xlog_op_header_t); |
1924 | + XLOG_TIC_ADD_OPHDR(ticket); | |
1793 | 1925 | } |
1794 | 1926 | xlog_verify_dest_ptr(log, ptr); |
1795 | 1927 | |
... | ... | @@ -2282,6 +2414,9 @@ |
2282 | 2414 | */ |
2283 | 2415 | if (log_offset == 0) { |
2284 | 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 | 2420 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); |
2286 | 2421 | ASSIGN_LSN(head->h_lsn, log); |
2287 | 2422 | ASSERT(log->l_curr_block >= 0); |
... | ... | @@ -2468,6 +2603,7 @@ |
2468 | 2603 | #endif |
2469 | 2604 | |
2470 | 2605 | tic->t_curr_res = tic->t_unit_res; |
2606 | + XLOG_TIC_RESET_RES(tic); | |
2471 | 2607 | |
2472 | 2608 | if (tic->t_cnt > 0) |
2473 | 2609 | return (0); |
... | ... | @@ -2608,6 +2744,7 @@ |
2608 | 2744 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w'); |
2609 | 2745 | XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r'); |
2610 | 2746 | ticket->t_curr_res = ticket->t_unit_res; |
2747 | + XLOG_TIC_RESET_RES(ticket); | |
2611 | 2748 | xlog_trace_loggrant(log, ticket, |
2612 | 2749 | "xlog_regrant_reserve_log_space: sub current res"); |
2613 | 2750 | xlog_verify_grant_head(log, 1); |
... | ... | @@ -2624,6 +2761,7 @@ |
2624 | 2761 | xlog_verify_grant_head(log, 0); |
2625 | 2762 | GRANT_UNLOCK(log, s); |
2626 | 2763 | ticket->t_curr_res = ticket->t_unit_res; |
2764 | + XLOG_TIC_RESET_RES(ticket); | |
2627 | 2765 | } /* xlog_regrant_reserve_log_space */ |
2628 | 2766 | |
2629 | 2767 | |
2630 | 2768 | |
... | ... | @@ -3237,9 +3375,12 @@ |
3237 | 3375 | tic->t_tid = (xlog_tid_t)((__psint_t)tic & 0xffffffff); |
3238 | 3376 | tic->t_clientid = client; |
3239 | 3377 | tic->t_flags = XLOG_TIC_INITED; |
3378 | + tic->t_trans_type = 0; | |
3240 | 3379 | if (xflags & XFS_LOG_PERM_RESERV) |
3241 | 3380 | tic->t_flags |= XLOG_TIC_PERM_RESERV; |
3242 | 3381 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); |
3382 | + | |
3383 | + XLOG_TIC_RESET_RES(tic); | |
3243 | 3384 | |
3244 | 3385 | return tic; |
3245 | 3386 | } /* xlog_ticket_get */ |
fs/xfs/xfs_log.h
... | ... | @@ -114,9 +114,44 @@ |
114 | 114 | #define XFS_VOLUME 0x2 |
115 | 115 | #define XFS_LOG 0xaa |
116 | 116 | |
117 | + | |
118 | +/* Region types for iovec's i_type */ | |
119 | +#if defined(XFS_LOG_RES_DEBUG) | |
120 | +#define XLOG_REG_TYPE_BFORMAT 1 | |
121 | +#define XLOG_REG_TYPE_BCHUNK 2 | |
122 | +#define XLOG_REG_TYPE_EFI_FORMAT 3 | |
123 | +#define XLOG_REG_TYPE_EFD_FORMAT 4 | |
124 | +#define XLOG_REG_TYPE_IFORMAT 5 | |
125 | +#define XLOG_REG_TYPE_ICORE 6 | |
126 | +#define XLOG_REG_TYPE_IEXT 7 | |
127 | +#define XLOG_REG_TYPE_IBROOT 8 | |
128 | +#define XLOG_REG_TYPE_ILOCAL 9 | |
129 | +#define XLOG_REG_TYPE_IATTR_EXT 10 | |
130 | +#define XLOG_REG_TYPE_IATTR_BROOT 11 | |
131 | +#define XLOG_REG_TYPE_IATTR_LOCAL 12 | |
132 | +#define XLOG_REG_TYPE_QFORMAT 13 | |
133 | +#define XLOG_REG_TYPE_DQUOT 14 | |
134 | +#define XLOG_REG_TYPE_QUOTAOFF 15 | |
135 | +#define XLOG_REG_TYPE_LRHEADER 16 | |
136 | +#define XLOG_REG_TYPE_UNMOUNT 17 | |
137 | +#define XLOG_REG_TYPE_COMMIT 18 | |
138 | +#define XLOG_REG_TYPE_TRANSHDR 19 | |
139 | +#define XLOG_REG_TYPE_MAX 19 | |
140 | +#endif | |
141 | + | |
142 | +#if defined(XFS_LOG_RES_DEBUG) | |
143 | +#define XLOG_VEC_SET_TYPE(vecp, t) ((vecp)->i_type = (t)) | |
144 | +#else | |
145 | +#define XLOG_VEC_SET_TYPE(vecp, t) | |
146 | +#endif | |
147 | + | |
148 | + | |
117 | 149 | typedef struct xfs_log_iovec { |
118 | 150 | xfs_caddr_t i_addr; /* beginning address of region */ |
119 | 151 | int i_len; /* length in bytes of region */ |
152 | +#if defined(XFS_LOG_RES_DEBUG) | |
153 | + uint i_type; /* type of region */ | |
154 | +#endif | |
120 | 155 | } xfs_log_iovec_t; |
121 | 156 | |
122 | 157 | typedef void* xfs_log_ticket_t; |
... | ... | @@ -159,7 +194,8 @@ |
159 | 194 | int count, |
160 | 195 | xfs_log_ticket_t *ticket, |
161 | 196 | __uint8_t clientid, |
162 | - uint flags); | |
197 | + uint flags, | |
198 | + uint t_type); | |
163 | 199 | int xfs_log_write(struct xfs_mount *mp, |
164 | 200 | xfs_log_iovec_t region[], |
165 | 201 | int nentries, |
fs/xfs/xfs_log_priv.h
... | ... | @@ -335,18 +335,66 @@ |
335 | 335 | |
336 | 336 | #define XLOG_COVER_OPS 5 |
337 | 337 | |
338 | + | |
339 | +/* Ticket reservation region accounting */ | |
340 | +#if defined(XFS_LOG_RES_DEBUG) | |
341 | +#define XLOG_TIC_LEN_MAX 15 | |
342 | +#define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \ | |
343 | + (t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0) | |
344 | +#define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++) | |
345 | +#define XLOG_TIC_ADD_REGION(t, len, type) \ | |
346 | + do { \ | |
347 | + if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \ | |
348 | + /* add to overflow and start again */ \ | |
349 | + (t)->t_res_o_flow += (t)->t_res_arr_sum; \ | |
350 | + (t)->t_res_num = 0; \ | |
351 | + (t)->t_res_arr_sum = 0; \ | |
352 | + } \ | |
353 | + (t)->t_res_arr[(t)->t_res_num].r_len = (len); \ | |
354 | + (t)->t_res_arr[(t)->t_res_num].r_type = (type); \ | |
355 | + (t)->t_res_arr_sum += (len); \ | |
356 | + (t)->t_res_num++; \ | |
357 | + } while (0) | |
358 | + | |
359 | +/* | |
360 | + * Reservation region | |
361 | + * As would be stored in xfs_log_iovec but without the i_addr which | |
362 | + * we don't care about. | |
363 | + */ | |
364 | +typedef struct xlog_res { | |
365 | + uint r_len; | |
366 | + uint r_type; | |
367 | +} xlog_res_t; | |
368 | +#else | |
369 | +#define XLOG_TIC_RESET_RES(t) | |
370 | +#define XLOG_TIC_ADD_OPHDR(t) | |
371 | +#define XLOG_TIC_ADD_REGION(t, len, type) | |
372 | +#endif | |
373 | + | |
374 | + | |
338 | 375 | typedef struct xlog_ticket { |
339 | - sv_t t_sema; /* sleep on this semaphore :20 */ | |
340 | - struct xlog_ticket *t_next; /* : 4 */ | |
341 | - struct xlog_ticket *t_prev; /* : 4 */ | |
342 | - xlog_tid_t t_tid; /* transaction identifier : 4 */ | |
343 | - int t_curr_res; /* current reservation in bytes : 4 */ | |
344 | - int t_unit_res; /* unit reservation in bytes : 4 */ | |
345 | - __uint8_t t_ocnt; /* original count : 1 */ | |
346 | - __uint8_t t_cnt; /* current count : 1 */ | |
347 | - __uint8_t t_clientid; /* who does this belong to; : 1 */ | |
348 | - __uint8_t t_flags; /* properties of reservation : 1 */ | |
376 | + sv_t t_sema; /* sleep on this semaphore : 20 */ | |
377 | + struct xlog_ticket *t_next; /* :4|8 */ | |
378 | + struct xlog_ticket *t_prev; /* :4|8 */ | |
379 | + xlog_tid_t t_tid; /* transaction identifier : 4 */ | |
380 | + int t_curr_res; /* current reservation in bytes : 4 */ | |
381 | + int t_unit_res; /* unit reservation in bytes : 4 */ | |
382 | + char t_ocnt; /* original count : 1 */ | |
383 | + char t_cnt; /* current count : 1 */ | |
384 | + char t_clientid; /* who does this belong to; : 1 */ | |
385 | + char t_flags; /* properties of reservation : 1 */ | |
386 | + uint t_trans_type; /* transaction type : 4 */ | |
387 | + | |
388 | +#if defined (XFS_LOG_RES_DEBUG) | |
389 | + /* reservation array fields */ | |
390 | + uint t_res_num; /* num in array : 4 */ | |
391 | + xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : X */ | |
392 | + uint t_res_num_ophdrs; /* num op hdrs : 4 */ | |
393 | + uint t_res_arr_sum; /* array sum : 4 */ | |
394 | + uint t_res_o_flow; /* sum overflow : 4 */ | |
395 | +#endif | |
349 | 396 | } xlog_ticket_t; |
397 | + | |
350 | 398 | #endif |
351 | 399 | |
352 | 400 |
fs/xfs/xfs_trans.c
... | ... | @@ -276,7 +276,7 @@ |
276 | 276 | |
277 | 277 | error = xfs_log_reserve(tp->t_mountp, logspace, logcount, |
278 | 278 | &tp->t_ticket, |
279 | - XFS_TRANSACTION, log_flags); | |
279 | + XFS_TRANSACTION, log_flags, tp->t_type); | |
280 | 280 | if (error) { |
281 | 281 | goto undo_blocks; |
282 | 282 | } |
... | ... | @@ -1032,6 +1032,7 @@ |
1032 | 1032 | tp->t_header.th_num_items = nitems; |
1033 | 1033 | log_vector->i_addr = (xfs_caddr_t)&tp->t_header; |
1034 | 1034 | log_vector->i_len = sizeof(xfs_trans_header_t); |
1035 | + XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_TRANSHDR); | |
1035 | 1036 | } |
1036 | 1037 | |
1037 | 1038 |
fs/xfs/xfs_trans.h