aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf_item.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-06-23 04:11:15 -0400
committerAlex Elder <aelder@sgi.com>2010-07-26 14:16:34 -0400
commit9412e3181c0ef82efc3d8e88d73e583ec10c34e9 (patch)
tree10ed24cdebd9922e7cd9414941e5c59e9e5fafab /fs/xfs/xfs_buf_item.c
parente98c414f9a3134fe7efc56ef8f1d394b54bfd40e (diff)
xfs: merge iop_unpin_remove into iop_unpin
The unpin_remove item operation instances always share most of the implementation with the respective unpin implementation. So instead of keeping two different entry points add a remove flag to the unpin operation and share the code more easily. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r--fs/xfs/xfs_buf_item.c74
1 files changed, 28 insertions, 46 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 711f69abbbe4..93899953c603 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -388,20 +388,25 @@ xfs_buf_item_pin(
388 * Also drop the reference to the buf item for the current transaction. 388 * Also drop the reference to the buf item for the current transaction.
389 * If the XFS_BLI_STALE flag is set and we are the last reference, 389 * If the XFS_BLI_STALE flag is set and we are the last reference,
390 * then free up the buf log item and unlock the buffer. 390 * then free up the buf log item and unlock the buffer.
391 *
392 * If the remove flag is set we are called from uncommit in the
393 * forced-shutdown path. If that is true and the reference count on
394 * the log item is going to drop to zero we need to free the item's
395 * descriptor in the transaction.
391 */ 396 */
392STATIC void 397STATIC void
393xfs_buf_item_unpin( 398xfs_buf_item_unpin(
394 xfs_buf_log_item_t *bip) 399 xfs_buf_log_item_t *bip,
400 int remove)
395{ 401{
396 struct xfs_ail *ailp; 402 struct xfs_ail *ailp;
397 xfs_buf_t *bp; 403 xfs_buf_t *bp = bip->bli_buf;
398 int freed; 404 int freed;
399 int stale = bip->bli_flags & XFS_BLI_STALE; 405 int stale = bip->bli_flags & XFS_BLI_STALE;
400 406
401 bp = bip->bli_buf;
402 ASSERT(bp != NULL);
403 ASSERT(XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *) == bip); 407 ASSERT(XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *) == bip);
404 ASSERT(atomic_read(&bip->bli_refcount) > 0); 408 ASSERT(atomic_read(&bip->bli_refcount) > 0);
409
405 trace_xfs_buf_item_unpin(bip); 410 trace_xfs_buf_item_unpin(bip);
406 411
407 freed = atomic_dec_and_test(&bip->bli_refcount); 412 freed = atomic_dec_and_test(&bip->bli_refcount);
@@ -413,8 +418,26 @@ xfs_buf_item_unpin(
413 ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); 418 ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
414 ASSERT(XFS_BUF_ISSTALE(bp)); 419 ASSERT(XFS_BUF_ISSTALE(bp));
415 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); 420 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
421
416 trace_xfs_buf_item_unpin_stale(bip); 422 trace_xfs_buf_item_unpin_stale(bip);
417 423
424 if (remove) {
425 /*
426 * We have to remove the log item from the transaction
427 * as we are about to release our reference to the
428 * buffer. If we don't, the unlock that occurs later
429 * in xfs_trans_uncommit() will ry to reference the
430 * buffer which we no longer have a hold on.
431 */
432 xfs_trans_del_item(&bip->bli_item);
433
434 /*
435 * Since the transaction no longer refers to the buffer,
436 * the buffer should no longer refer to the transaction.
437 */
438 XFS_BUF_SET_FSPRIVATE2(bp, NULL);
439 }
440
418 /* 441 /*
419 * If we get called here because of an IO error, we may 442 * If we get called here because of an IO error, we may
420 * or may not have the item on the AIL. xfs_trans_ail_delete() 443 * or may not have the item on the AIL. xfs_trans_ail_delete()
@@ -436,45 +459,6 @@ xfs_buf_item_unpin(
436} 459}
437 460
438/* 461/*
439 * this is called from uncommit in the forced-shutdown path.
440 * we need to check to see if the reference count on the log item
441 * is going to drop to zero. If so, unpin will free the log item
442 * so we need to free the item's descriptor (that points to the item)
443 * in the transaction.
444 */
445STATIC void
446xfs_buf_item_unpin_remove(
447 xfs_buf_log_item_t *bip,
448 xfs_trans_t *tp)
449{
450 /* will xfs_buf_item_unpin() call xfs_buf_item_relse()? */
451 if ((atomic_read(&bip->bli_refcount) == 1) &&
452 (bip->bli_flags & XFS_BLI_STALE)) {
453 /*
454 * yes -- We can safely do some work here and then call
455 * buf_item_unpin to do the rest because we are
456 * are holding the buffer locked so no one else will be
457 * able to bump up the refcount. We have to remove the
458 * log item from the transaction as we are about to release
459 * our reference to the buffer. If we don't, the unlock that
460 * occurs later in the xfs_trans_uncommit() will try to
461 * reference the buffer which we no longer have a hold on.
462 */
463 ASSERT(XFS_BUF_VALUSEMA(bip->bli_buf) <= 0);
464 trace_xfs_buf_item_unpin_stale(bip);
465
466 xfs_trans_del_item(&bip->bli_item);
467
468 /*
469 * Since the transaction no longer refers to the buffer, the
470 * buffer should no longer refer to the transaction.
471 */
472 XFS_BUF_SET_FSPRIVATE2(bip->bli_buf, NULL);
473 }
474 xfs_buf_item_unpin(bip);
475}
476
477/*
478 * This is called to attempt to lock the buffer associated with this 462 * This is called to attempt to lock the buffer associated with this
479 * buf log item. Don't sleep on the buffer lock. If we can't get 463 * buf log item. Don't sleep on the buffer lock. If we can't get
480 * the lock right away, return 0. If we can get the lock, take a 464 * the lock right away, return 0. If we can get the lock, take a
@@ -669,9 +653,7 @@ static struct xfs_item_ops xfs_buf_item_ops = {
669 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 653 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
670 xfs_buf_item_format, 654 xfs_buf_item_format,
671 .iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin, 655 .iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin,
672 .iop_unpin = (void(*)(xfs_log_item_t*))xfs_buf_item_unpin, 656 .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_buf_item_unpin,
673 .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
674 xfs_buf_item_unpin_remove,
675 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock, 657 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock,
676 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_buf_item_unlock, 658 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_buf_item_unlock,
677 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) 659 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))