aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf.c2
-rw-r--r--fs/xfs/xfs_buf_item.c12
-rw-r--r--fs/xfs/xfs_trace.h1
3 files changed, 13 insertions, 2 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 689d72655ea6..fbbb9eb92e32 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1505,6 +1505,8 @@ restart:
1505 while (!list_empty(&btp->bt_lru)) { 1505 while (!list_empty(&btp->bt_lru)) {
1506 bp = list_first_entry(&btp->bt_lru, struct xfs_buf, b_lru); 1506 bp = list_first_entry(&btp->bt_lru, struct xfs_buf, b_lru);
1507 if (atomic_read(&bp->b_hold) > 1) { 1507 if (atomic_read(&bp->b_hold) > 1) {
1508 trace_xfs_buf_wait_buftarg(bp, _RET_IP_);
1509 list_move_tail(&bp->b_lru, &btp->bt_lru);
1508 spin_unlock(&btp->bt_lru_lock); 1510 spin_unlock(&btp->bt_lru_lock);
1509 delay(100); 1511 delay(100);
1510 goto restart; 1512 goto restart;
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 77b09750e92c..3f9949fee391 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -652,7 +652,10 @@ xfs_buf_item_unlock(
652 652
653 /* 653 /*
654 * If the buf item isn't tracking any data, free it, otherwise drop the 654 * If the buf item isn't tracking any data, free it, otherwise drop the
655 * reference we hold to it. 655 * reference we hold to it. If we are aborting the transaction, this may
656 * be the only reference to the buf item, so we free it anyway
657 * regardless of whether it is dirty or not. A dirty abort implies a
658 * shutdown, anyway.
656 */ 659 */
657 clean = 1; 660 clean = 1;
658 for (i = 0; i < bip->bli_format_count; i++) { 661 for (i = 0; i < bip->bli_format_count; i++) {
@@ -664,7 +667,12 @@ xfs_buf_item_unlock(
664 } 667 }
665 if (clean) 668 if (clean)
666 xfs_buf_item_relse(bp); 669 xfs_buf_item_relse(bp);
667 else 670 else if (aborted) {
671 if (atomic_dec_and_test(&bip->bli_refcount)) {
672 ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
673 xfs_buf_item_relse(bp);
674 }
675 } else
668 atomic_dec(&bip->bli_refcount); 676 atomic_dec(&bip->bli_refcount);
669 677
670 if (!hold) 678 if (!hold)
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 2e137d4a85ae..16a812977eab 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -341,6 +341,7 @@ DEFINE_BUF_EVENT(xfs_buf_item_relse);
341DEFINE_BUF_EVENT(xfs_buf_item_iodone); 341DEFINE_BUF_EVENT(xfs_buf_item_iodone);
342DEFINE_BUF_EVENT(xfs_buf_item_iodone_async); 342DEFINE_BUF_EVENT(xfs_buf_item_iodone_async);
343DEFINE_BUF_EVENT(xfs_buf_error_relse); 343DEFINE_BUF_EVENT(xfs_buf_error_relse);
344DEFINE_BUF_EVENT(xfs_buf_wait_buftarg);
344DEFINE_BUF_EVENT(xfs_trans_read_buf_io); 345DEFINE_BUF_EVENT(xfs_trans_read_buf_io);
345DEFINE_BUF_EVENT(xfs_trans_read_buf_shut); 346DEFINE_BUF_EVENT(xfs_trans_read_buf_shut);
346 347