diff options
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_extfree_item.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 161 | ||||
-rw-r--r-- | fs/xfs/xfs_log.h | 38 | ||||
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 68 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 1 |
9 files changed, 265 insertions, 22 deletions
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index f5271b7b1e84..e74eaa7dd1bc 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -509,6 +509,7 @@ xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf, | |||
509 | 509 | ||
510 | log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format); | 510 | log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format); |
511 | log_vector->i_len = sizeof(xfs_qoff_logitem_t); | 511 | log_vector->i_len = sizeof(xfs_qoff_logitem_t); |
512 | XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_QUOTAOFF); | ||
512 | qf->qql_format.qf_size = 1; | 513 | qf->qql_format.qf_size = 1; |
513 | } | 514 | } |
514 | 515 | ||
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 30b8285ad476..a264657acfd9 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -274,6 +274,7 @@ xfs_buf_item_format( | |||
274 | ((bip->bli_format.blf_map_size - 1) * sizeof(uint))); | 274 | ((bip->bli_format.blf_map_size - 1) * sizeof(uint))); |
275 | vecp->i_addr = (xfs_caddr_t)&bip->bli_format; | 275 | vecp->i_addr = (xfs_caddr_t)&bip->bli_format; |
276 | vecp->i_len = base_size; | 276 | vecp->i_len = base_size; |
277 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BFORMAT); | ||
277 | vecp++; | 278 | vecp++; |
278 | nvecs = 1; | 279 | nvecs = 1; |
279 | 280 | ||
@@ -320,12 +321,14 @@ xfs_buf_item_format( | |||
320 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 321 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
321 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 322 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
322 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 323 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
324 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | ||
323 | nvecs++; | 325 | nvecs++; |
324 | break; | 326 | break; |
325 | } else if (next_bit != last_bit + 1) { | 327 | } else if (next_bit != last_bit + 1) { |
326 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 328 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
327 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 329 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
328 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 330 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
331 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | ||
329 | nvecs++; | 332 | nvecs++; |
330 | vecp++; | 333 | vecp++; |
331 | first_bit = next_bit; | 334 | first_bit = next_bit; |
@@ -337,6 +340,7 @@ xfs_buf_item_format( | |||
337 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 340 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
338 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 341 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
339 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 342 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
343 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | ||
340 | /* You would think we need to bump the nvecs here too, but we do not | 344 | /* You would think we need to bump the nvecs here too, but we do not |
341 | * this number is used by recovery, and it gets confused by the boundary | 345 | * this number is used by recovery, and it gets confused by the boundary |
342 | * split here | 346 | * split here |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index db7cbd1bc857..cc7d1494a45d 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -107,6 +107,7 @@ xfs_efi_item_format(xfs_efi_log_item_t *efip, | |||
107 | 107 | ||
108 | log_vector->i_addr = (xfs_caddr_t)&(efip->efi_format); | 108 | log_vector->i_addr = (xfs_caddr_t)&(efip->efi_format); |
109 | log_vector->i_len = size; | 109 | log_vector->i_len = size; |
110 | XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_EFI_FORMAT); | ||
110 | ASSERT(size >= sizeof(xfs_efi_log_format_t)); | 111 | ASSERT(size >= sizeof(xfs_efi_log_format_t)); |
111 | } | 112 | } |
112 | 113 | ||
@@ -426,6 +427,7 @@ xfs_efd_item_format(xfs_efd_log_item_t *efdp, | |||
426 | 427 | ||
427 | log_vector->i_addr = (xfs_caddr_t)&(efdp->efd_format); | 428 | log_vector->i_addr = (xfs_caddr_t)&(efdp->efd_format); |
428 | log_vector->i_len = size; | 429 | log_vector->i_len = size; |
430 | XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_EFD_FORMAT); | ||
429 | ASSERT(size >= sizeof(xfs_efd_log_format_t)); | 431 | ASSERT(size >= sizeof(xfs_efd_log_format_t)); |
430 | } | 432 | } |
431 | 433 | ||
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 0eed30f5cb19..276ec70eb7f9 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -248,6 +248,7 @@ xfs_inode_item_format( | |||
248 | 248 | ||
249 | vecp->i_addr = (xfs_caddr_t)&iip->ili_format; | 249 | vecp->i_addr = (xfs_caddr_t)&iip->ili_format; |
250 | vecp->i_len = sizeof(xfs_inode_log_format_t); | 250 | vecp->i_len = sizeof(xfs_inode_log_format_t); |
251 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IFORMAT); | ||
251 | vecp++; | 252 | vecp++; |
252 | nvecs = 1; | 253 | nvecs = 1; |
253 | 254 | ||
@@ -292,6 +293,7 @@ xfs_inode_item_format( | |||
292 | 293 | ||
293 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; | 294 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; |
294 | vecp->i_len = sizeof(xfs_dinode_core_t); | 295 | vecp->i_len = sizeof(xfs_dinode_core_t); |
296 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); | ||
295 | vecp++; | 297 | vecp++; |
296 | nvecs++; | 298 | nvecs++; |
297 | iip->ili_format.ilf_fields |= XFS_ILOG_CORE; | 299 | iip->ili_format.ilf_fields |= XFS_ILOG_CORE; |
@@ -349,6 +351,7 @@ xfs_inode_item_format( | |||
349 | vecp->i_addr = | 351 | vecp->i_addr = |
350 | (char *)(ip->i_df.if_u1.if_extents); | 352 | (char *)(ip->i_df.if_u1.if_extents); |
351 | vecp->i_len = ip->i_df.if_bytes; | 353 | vecp->i_len = ip->i_df.if_bytes; |
354 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IEXT); | ||
352 | } else | 355 | } else |
353 | #endif | 356 | #endif |
354 | { | 357 | { |
@@ -367,6 +370,7 @@ xfs_inode_item_format( | |||
367 | vecp->i_addr = (xfs_caddr_t)ext_buffer; | 370 | vecp->i_addr = (xfs_caddr_t)ext_buffer; |
368 | vecp->i_len = xfs_iextents_copy(ip, ext_buffer, | 371 | vecp->i_len = xfs_iextents_copy(ip, ext_buffer, |
369 | XFS_DATA_FORK); | 372 | XFS_DATA_FORK); |
373 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IEXT); | ||
370 | } | 374 | } |
371 | ASSERT(vecp->i_len <= ip->i_df.if_bytes); | 375 | ASSERT(vecp->i_len <= ip->i_df.if_bytes); |
372 | iip->ili_format.ilf_dsize = vecp->i_len; | 376 | iip->ili_format.ilf_dsize = vecp->i_len; |
@@ -384,6 +388,7 @@ xfs_inode_item_format( | |||
384 | ASSERT(ip->i_df.if_broot != NULL); | 388 | ASSERT(ip->i_df.if_broot != NULL); |
385 | vecp->i_addr = (xfs_caddr_t)ip->i_df.if_broot; | 389 | vecp->i_addr = (xfs_caddr_t)ip->i_df.if_broot; |
386 | vecp->i_len = ip->i_df.if_broot_bytes; | 390 | vecp->i_len = ip->i_df.if_broot_bytes; |
391 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IBROOT); | ||
387 | vecp++; | 392 | vecp++; |
388 | nvecs++; | 393 | nvecs++; |
389 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; | 394 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; |
@@ -409,6 +414,7 @@ xfs_inode_item_format( | |||
409 | ASSERT((ip->i_df.if_real_bytes == 0) || | 414 | ASSERT((ip->i_df.if_real_bytes == 0) || |
410 | (ip->i_df.if_real_bytes == data_bytes)); | 415 | (ip->i_df.if_real_bytes == data_bytes)); |
411 | vecp->i_len = (int)data_bytes; | 416 | vecp->i_len = (int)data_bytes; |
417 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ILOCAL); | ||
412 | vecp++; | 418 | vecp++; |
413 | nvecs++; | 419 | nvecs++; |
414 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; | 420 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; |
@@ -486,6 +492,7 @@ xfs_inode_item_format( | |||
486 | vecp->i_len = xfs_iextents_copy(ip, ext_buffer, | 492 | vecp->i_len = xfs_iextents_copy(ip, ext_buffer, |
487 | XFS_ATTR_FORK); | 493 | XFS_ATTR_FORK); |
488 | #endif | 494 | #endif |
495 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_EXT); | ||
489 | iip->ili_format.ilf_asize = vecp->i_len; | 496 | iip->ili_format.ilf_asize = vecp->i_len; |
490 | vecp++; | 497 | vecp++; |
491 | nvecs++; | 498 | nvecs++; |
@@ -500,6 +507,7 @@ xfs_inode_item_format( | |||
500 | ASSERT(ip->i_afp->if_broot != NULL); | 507 | ASSERT(ip->i_afp->if_broot != NULL); |
501 | vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_broot; | 508 | vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_broot; |
502 | vecp->i_len = ip->i_afp->if_broot_bytes; | 509 | vecp->i_len = ip->i_afp->if_broot_bytes; |
510 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_BROOT); | ||
503 | vecp++; | 511 | vecp++; |
504 | nvecs++; | 512 | nvecs++; |
505 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; | 513 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; |
@@ -523,6 +531,7 @@ xfs_inode_item_format( | |||
523 | ASSERT((ip->i_afp->if_real_bytes == 0) || | 531 | ASSERT((ip->i_afp->if_real_bytes == 0) || |
524 | (ip->i_afp->if_real_bytes == data_bytes)); | 532 | (ip->i_afp->if_real_bytes == data_bytes)); |
525 | vecp->i_len = (int)data_bytes; | 533 | vecp->i_len = (int)data_bytes; |
534 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_IATTR_LOCAL); | ||
526 | vecp++; | 535 | vecp++; |
527 | nvecs++; | 536 | nvecs++; |
528 | iip->ili_format.ilf_asize = (unsigned)data_bytes; | 537 | iip->ili_format.ilf_asize = (unsigned)data_bytes; |
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 | ||
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 0db122ddda3f..18961119fc65 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
@@ -114,9 +114,44 @@ xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) | |||
114 | #define XFS_VOLUME 0x2 | 114 | #define XFS_VOLUME 0x2 |
115 | #define XFS_LOG 0xaa | 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 | typedef struct xfs_log_iovec { | 149 | typedef struct xfs_log_iovec { |
118 | xfs_caddr_t i_addr; /* beginning address of region */ | 150 | xfs_caddr_t i_addr; /* beginning address of region */ |
119 | int i_len; /* length in bytes of region */ | 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 | } xfs_log_iovec_t; | 155 | } xfs_log_iovec_t; |
121 | 156 | ||
122 | typedef void* xfs_log_ticket_t; | 157 | typedef void* xfs_log_ticket_t; |
@@ -159,7 +194,8 @@ int xfs_log_reserve(struct xfs_mount *mp, | |||
159 | int count, | 194 | int count, |
160 | xfs_log_ticket_t *ticket, | 195 | xfs_log_ticket_t *ticket, |
161 | __uint8_t clientid, | 196 | __uint8_t clientid, |
162 | uint flags); | 197 | uint flags, |
198 | uint t_type); | ||
163 | int xfs_log_write(struct xfs_mount *mp, | 199 | int xfs_log_write(struct xfs_mount *mp, |
164 | xfs_log_iovec_t region[], | 200 | xfs_log_iovec_t region[], |
165 | int nentries, | 201 | int nentries, |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 1a1d452f15f9..eb7fdc6ebc32 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -335,18 +335,66 @@ typedef __uint32_t xlog_tid_t; | |||
335 | 335 | ||
336 | #define XLOG_COVER_OPS 5 | 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 | typedef struct xlog_ticket { | 375 | typedef struct xlog_ticket { |
339 | sv_t t_sema; /* sleep on this semaphore :20 */ | 376 | sv_t t_sema; /* sleep on this semaphore : 20 */ |
340 | struct xlog_ticket *t_next; /* : 4 */ | 377 | struct xlog_ticket *t_next; /* :4|8 */ |
341 | struct xlog_ticket *t_prev; /* : 4 */ | 378 | struct xlog_ticket *t_prev; /* :4|8 */ |
342 | xlog_tid_t t_tid; /* transaction identifier : 4 */ | 379 | xlog_tid_t t_tid; /* transaction identifier : 4 */ |
343 | int t_curr_res; /* current reservation in bytes : 4 */ | 380 | int t_curr_res; /* current reservation in bytes : 4 */ |
344 | int t_unit_res; /* unit reservation in bytes : 4 */ | 381 | int t_unit_res; /* unit reservation in bytes : 4 */ |
345 | __uint8_t t_ocnt; /* original count : 1 */ | 382 | char t_ocnt; /* original count : 1 */ |
346 | __uint8_t t_cnt; /* current count : 1 */ | 383 | char t_cnt; /* current count : 1 */ |
347 | __uint8_t t_clientid; /* who does this belong to; : 1 */ | 384 | char t_clientid; /* who does this belong to; : 1 */ |
348 | __uint8_t t_flags; /* properties of reservation : 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 | } xlog_ticket_t; | 396 | } xlog_ticket_t; |
397 | |||
350 | #endif | 398 | #endif |
351 | 399 | ||
352 | 400 | ||
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 06dfca531f79..92efe272b83d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -276,7 +276,7 @@ xfs_trans_reserve( | |||
276 | 276 | ||
277 | error = xfs_log_reserve(tp->t_mountp, logspace, logcount, | 277 | error = xfs_log_reserve(tp->t_mountp, logspace, logcount, |
278 | &tp->t_ticket, | 278 | &tp->t_ticket, |
279 | XFS_TRANSACTION, log_flags); | 279 | XFS_TRANSACTION, log_flags, tp->t_type); |
280 | if (error) { | 280 | if (error) { |
281 | goto undo_blocks; | 281 | goto undo_blocks; |
282 | } | 282 | } |
@@ -1032,6 +1032,7 @@ xfs_trans_fill_vecs( | |||
1032 | tp->t_header.th_num_items = nitems; | 1032 | tp->t_header.th_num_items = nitems; |
1033 | log_vector->i_addr = (xfs_caddr_t)&tp->t_header; | 1033 | log_vector->i_addr = (xfs_caddr_t)&tp->t_header; |
1034 | log_vector->i_len = sizeof(xfs_trans_header_t); | 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 | ||
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index ec541d66fa2a..9ee5eeee8026 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -112,6 +112,7 @@ typedef struct xfs_trans_header { | |||
112 | #define XFS_TRANS_GROWFSRT_ZERO 38 | 112 | #define XFS_TRANS_GROWFSRT_ZERO 38 |
113 | #define XFS_TRANS_GROWFSRT_FREE 39 | 113 | #define XFS_TRANS_GROWFSRT_FREE 39 |
114 | #define XFS_TRANS_SWAPEXT 40 | 114 | #define XFS_TRANS_SWAPEXT 40 |
115 | #define XFS_TRANS_TYPE_MAX 40 | ||
115 | /* new transaction types need to be reflected in xfs_logprint(8) */ | 116 | /* new transaction types need to be reflected in xfs_logprint(8) */ |
116 | 117 | ||
117 | 118 | ||