diff options
| -rw-r--r-- | fs/xfs/xfs_buf_item.c | 110 |
1 files changed, 50 insertions, 60 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 240340a4727b..4cd5f615371d 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -341,10 +341,15 @@ xfs_buf_item_format( | |||
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | /* | 343 | /* |
| 344 | * This is called to pin the buffer associated with the buf log | 344 | * This is called to pin the buffer associated with the buf log item in memory |
| 345 | * item in memory so it cannot be written out. Simply call bpin() | 345 | * so it cannot be written out. Simply call bpin() on the buffer to do this. |
| 346 | * on the buffer to do this. | 346 | * |
| 347 | * We also always take a reference to the buffer log item here so that the bli | ||
| 348 | * is held while the item is pinned in memory. This means that we can | ||
| 349 | * unconditionally drop the reference count a transaction holds when the | ||
| 350 | * transaction is completed. | ||
| 347 | */ | 351 | */ |
| 352 | |||
| 348 | STATIC void | 353 | STATIC void |
| 349 | xfs_buf_item_pin( | 354 | xfs_buf_item_pin( |
| 350 | xfs_buf_log_item_t *bip) | 355 | xfs_buf_log_item_t *bip) |
| @@ -356,6 +361,7 @@ xfs_buf_item_pin( | |||
| 356 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 361 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
| 357 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || | 362 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || |
| 358 | (bip->bli_flags & XFS_BLI_STALE)); | 363 | (bip->bli_flags & XFS_BLI_STALE)); |
| 364 | atomic_inc(&bip->bli_refcount); | ||
| 359 | trace_xfs_buf_item_pin(bip); | 365 | trace_xfs_buf_item_pin(bip); |
| 360 | xfs_bpin(bp); | 366 | xfs_bpin(bp); |
| 361 | } | 367 | } |
| @@ -489,20 +495,23 @@ xfs_buf_item_trylock( | |||
| 489 | } | 495 | } |
| 490 | 496 | ||
| 491 | /* | 497 | /* |
| 492 | * Release the buffer associated with the buf log item. | 498 | * Release the buffer associated with the buf log item. If there is no dirty |
| 493 | * If there is no dirty logged data associated with the | 499 | * logged data associated with the buffer recorded in the buf log item, then |
| 494 | * buffer recorded in the buf log item, then free the | 500 | * free the buf log item and remove the reference to it in the buffer. |
| 495 | * buf log item and remove the reference to it in the | ||
| 496 | * buffer. | ||
| 497 | * | 501 | * |
| 498 | * This call ignores the recursion count. It is only called | 502 | * This call ignores the recursion count. It is only called when the buffer |
| 499 | * when the buffer should REALLY be unlocked, regardless | 503 | * should REALLY be unlocked, regardless of the recursion count. |
| 500 | * of the recursion count. | ||
| 501 | * | 504 | * |
| 502 | * If the XFS_BLI_HOLD flag is set in the buf log item, then | 505 | * We unconditionally drop the transaction's reference to the log item. If the |
| 503 | * free the log item if necessary but do not unlock the buffer. | 506 | * item was logged, then another reference was taken when it was pinned, so we |
| 504 | * This is for support of xfs_trans_bhold(). Make sure the | 507 | * can safely drop the transaction reference now. This also allows us to avoid |
| 505 | * XFS_BLI_HOLD field is cleared if we don't free the item. | 508 | * potential races with the unpin code freeing the bli by not referencing the |
| 509 | * bli after we've dropped the reference count. | ||
| 510 | * | ||
| 511 | * If the XFS_BLI_HOLD flag is set in the buf log item, then free the log item | ||
| 512 | * if necessary but do not unlock the buffer. This is for support of | ||
| 513 | * xfs_trans_bhold(). Make sure the XFS_BLI_HOLD field is cleared if we don't | ||
| 514 | * free the item. | ||
| 506 | */ | 515 | */ |
| 507 | STATIC void | 516 | STATIC void |
| 508 | xfs_buf_item_unlock( | 517 | xfs_buf_item_unlock( |
| @@ -514,73 +523,54 @@ xfs_buf_item_unlock( | |||
| 514 | 523 | ||
| 515 | bp = bip->bli_buf; | 524 | bp = bip->bli_buf; |
| 516 | 525 | ||
| 517 | /* | 526 | /* Clear the buffer's association with this transaction. */ |
| 518 | * Clear the buffer's association with this transaction. | ||
| 519 | */ | ||
| 520 | XFS_BUF_SET_FSPRIVATE2(bp, NULL); | 527 | XFS_BUF_SET_FSPRIVATE2(bp, NULL); |
| 521 | 528 | ||
| 522 | /* | 529 | /* |
| 523 | * If this is a transaction abort, don't return early. | 530 | * If this is a transaction abort, don't return early. Instead, allow |
| 524 | * Instead, allow the brelse to happen. | 531 | * the brelse to happen. Normally it would be done for stale |
| 525 | * Normally it would be done for stale (cancelled) buffers | 532 | * (cancelled) buffers at unpin time, but we'll never go through the |
| 526 | * at unpin time, but we'll never go through the pin/unpin | 533 | * pin/unpin cycle if we abort inside commit. |
| 527 | * cycle if we abort inside commit. | ||
| 528 | */ | 534 | */ |
| 529 | aborted = (bip->bli_item.li_flags & XFS_LI_ABORTED) != 0; | 535 | aborted = (bip->bli_item.li_flags & XFS_LI_ABORTED) != 0; |
| 530 | 536 | ||
| 531 | /* | 537 | /* |
| 532 | * If the buf item is marked stale, then don't do anything. | 538 | * Before possibly freeing the buf item, determine if we should |
| 533 | * We'll unlock the buffer and free the buf item when the | 539 | * release the buffer at the end of this routine. |
| 534 | * buffer is unpinned for the last time. | 540 | */ |
| 541 | hold = bip->bli_flags & XFS_BLI_HOLD; | ||
| 542 | |||
| 543 | /* Clear the per transaction state. */ | ||
| 544 | bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD); | ||
| 545 | |||
| 546 | /* | ||
| 547 | * If the buf item is marked stale, then don't do anything. We'll | ||
| 548 | * unlock the buffer and free the buf item when the buffer is unpinned | ||
| 549 | * for the last time. | ||
| 535 | */ | 550 | */ |
| 536 | if (bip->bli_flags & XFS_BLI_STALE) { | 551 | if (bip->bli_flags & XFS_BLI_STALE) { |
| 537 | bip->bli_flags &= ~XFS_BLI_LOGGED; | ||
| 538 | trace_xfs_buf_item_unlock_stale(bip); | 552 | trace_xfs_buf_item_unlock_stale(bip); |
| 539 | ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); | 553 | ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); |
| 540 | if (!aborted) | 554 | if (!aborted) { |
| 555 | atomic_dec(&bip->bli_refcount); | ||
| 541 | return; | 556 | return; |
| 557 | } | ||
| 542 | } | 558 | } |
| 543 | 559 | ||
| 544 | /* | ||
| 545 | * Drop the transaction's reference to the log item if | ||
| 546 | * it was not logged as part of the transaction. Otherwise | ||
| 547 | * we'll drop the reference in xfs_buf_item_unpin() when | ||
| 548 | * the transaction is really through with the buffer. | ||
| 549 | */ | ||
| 550 | if (!(bip->bli_flags & XFS_BLI_LOGGED)) { | ||
| 551 | atomic_dec(&bip->bli_refcount); | ||
| 552 | } else { | ||
| 553 | /* | ||
| 554 | * Clear the logged flag since this is per | ||
| 555 | * transaction state. | ||
| 556 | */ | ||
| 557 | bip->bli_flags &= ~XFS_BLI_LOGGED; | ||
| 558 | } | ||
| 559 | |||
| 560 | /* | ||
| 561 | * Before possibly freeing the buf item, determine if we should | ||
| 562 | * release the buffer at the end of this routine. | ||
| 563 | */ | ||
| 564 | hold = bip->bli_flags & XFS_BLI_HOLD; | ||
| 565 | trace_xfs_buf_item_unlock(bip); | 560 | trace_xfs_buf_item_unlock(bip); |
| 566 | 561 | ||
| 567 | /* | 562 | /* |
| 568 | * If the buf item isn't tracking any data, free it. | 563 | * If the buf item isn't tracking any data, free it, otherwise drop the |
| 569 | * Otherwise, if XFS_BLI_HOLD is set clear it. | 564 | * reference we hold to it. |
| 570 | */ | 565 | */ |
| 571 | if (xfs_bitmap_empty(bip->bli_format.blf_data_map, | 566 | if (xfs_bitmap_empty(bip->bli_format.blf_data_map, |
| 572 | bip->bli_format.blf_map_size)) { | 567 | bip->bli_format.blf_map_size)) |
| 573 | xfs_buf_item_relse(bp); | 568 | xfs_buf_item_relse(bp); |
| 574 | } else if (hold) { | 569 | else |
| 575 | bip->bli_flags &= ~XFS_BLI_HOLD; | 570 | atomic_dec(&bip->bli_refcount); |
| 576 | } | ||
| 577 | 571 | ||
| 578 | /* | 572 | if (!hold) |
| 579 | * Release the buffer if XFS_BLI_HOLD was not set. | ||
| 580 | */ | ||
| 581 | if (!hold) { | ||
| 582 | xfs_buf_relse(bp); | 573 | xfs_buf_relse(bp); |
| 583 | } | ||
| 584 | } | 574 | } |
| 585 | 575 | ||
| 586 | /* | 576 | /* |
