diff options
| -rw-r--r-- | fs/xfs/xfs_buf_item.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index a8d0ed911196..becf4a97efc6 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -526,7 +526,25 @@ xfs_buf_item_unpin( | |||
| 526 | } | 526 | } |
| 527 | xfs_buf_relse(bp); | 527 | xfs_buf_relse(bp); |
| 528 | } else if (freed && remove) { | 528 | } else if (freed && remove) { |
| 529 | /* | ||
| 530 | * There are currently two references to the buffer - the active | ||
| 531 | * LRU reference and the buf log item. What we are about to do | ||
| 532 | * here - simulate a failed IO completion - requires 3 | ||
| 533 | * references. | ||
| 534 | * | ||
| 535 | * The LRU reference is removed by the xfs_buf_stale() call. The | ||
| 536 | * buf item reference is removed by the xfs_buf_iodone() | ||
| 537 | * callback that is run by xfs_buf_do_callbacks() during ioend | ||
| 538 | * processing (via the bp->b_iodone callback), and then finally | ||
| 539 | * the ioend processing will drop the IO reference if the buffer | ||
| 540 | * is marked XBF_ASYNC. | ||
| 541 | * | ||
| 542 | * Hence we need to take an additional reference here so that IO | ||
| 543 | * completion processing doesn't free the buffer prematurely. | ||
| 544 | */ | ||
| 529 | xfs_buf_lock(bp); | 545 | xfs_buf_lock(bp); |
| 546 | xfs_buf_hold(bp); | ||
| 547 | bp->b_flags |= XBF_ASYNC; | ||
| 530 | xfs_buf_ioerror(bp, EIO); | 548 | xfs_buf_ioerror(bp, EIO); |
| 531 | XFS_BUF_UNDONE(bp); | 549 | XFS_BUF_UNDONE(bp); |
| 532 | xfs_buf_stale(bp); | 550 | xfs_buf_stale(bp); |
