diff options
Diffstat (limited to 'fs/xfs/xfs_buf.c')
-rw-r--r-- | fs/xfs/xfs_buf.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 56d1614760cf..fbbb9eb92e32 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -487,6 +487,7 @@ _xfs_buf_find( | |||
487 | struct rb_node *parent; | 487 | struct rb_node *parent; |
488 | xfs_buf_t *bp; | 488 | xfs_buf_t *bp; |
489 | xfs_daddr_t blkno = map[0].bm_bn; | 489 | xfs_daddr_t blkno = map[0].bm_bn; |
490 | xfs_daddr_t eofs; | ||
490 | int numblks = 0; | 491 | int numblks = 0; |
491 | int i; | 492 | int i; |
492 | 493 | ||
@@ -498,6 +499,23 @@ _xfs_buf_find( | |||
498 | ASSERT(!(numbytes < (1 << btp->bt_sshift))); | 499 | ASSERT(!(numbytes < (1 << btp->bt_sshift))); |
499 | ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_smask)); | 500 | ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_smask)); |
500 | 501 | ||
502 | /* | ||
503 | * Corrupted block numbers can get through to here, unfortunately, so we | ||
504 | * have to check that the buffer falls within the filesystem bounds. | ||
505 | */ | ||
506 | eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks); | ||
507 | if (blkno >= eofs) { | ||
508 | /* | ||
509 | * XXX (dgc): we should really be returning EFSCORRUPTED here, | ||
510 | * but none of the higher level infrastructure supports | ||
511 | * returning a specific error on buffer lookup failures. | ||
512 | */ | ||
513 | xfs_alert(btp->bt_mount, | ||
514 | "%s: Block out of range: block 0x%llx, EOFS 0x%llx ", | ||
515 | __func__, blkno, eofs); | ||
516 | return NULL; | ||
517 | } | ||
518 | |||
501 | /* get tree root */ | 519 | /* get tree root */ |
502 | pag = xfs_perag_get(btp->bt_mount, | 520 | pag = xfs_perag_get(btp->bt_mount, |
503 | xfs_daddr_to_agno(btp->bt_mount, blkno)); | 521 | xfs_daddr_to_agno(btp->bt_mount, blkno)); |
@@ -1487,6 +1505,8 @@ restart: | |||
1487 | while (!list_empty(&btp->bt_lru)) { | 1505 | while (!list_empty(&btp->bt_lru)) { |
1488 | 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); |
1489 | 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); | ||
1490 | spin_unlock(&btp->bt_lru_lock); | 1510 | spin_unlock(&btp->bt_lru_lock); |
1491 | delay(100); | 1511 | delay(100); |
1492 | goto restart; | 1512 | goto restart; |