aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_buf.c')
-rw-r--r--fs/xfs/xfs_buf.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 26673a0b20e7..fbbb9eb92e32 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -175,7 +175,7 @@ xfs_buf_get_maps(
175 bp->b_map_count = map_count; 175 bp->b_map_count = map_count;
176 176
177 if (map_count == 1) { 177 if (map_count == 1) {
178 bp->b_maps = &bp->b_map; 178 bp->b_maps = &bp->__b_map;
179 return 0; 179 return 0;
180 } 180 }
181 181
@@ -193,7 +193,7 @@ static void
193xfs_buf_free_maps( 193xfs_buf_free_maps(
194 struct xfs_buf *bp) 194 struct xfs_buf *bp)
195{ 195{
196 if (bp->b_maps != &bp->b_map) { 196 if (bp->b_maps != &bp->__b_map) {
197 kmem_free(bp->b_maps); 197 kmem_free(bp->b_maps);
198 bp->b_maps = NULL; 198 bp->b_maps = NULL;
199 } 199 }
@@ -377,8 +377,8 @@ xfs_buf_allocate_memory(
377 } 377 }
378 378
379use_alloc_page: 379use_alloc_page:
380 start = BBTOB(bp->b_map.bm_bn) >> PAGE_SHIFT; 380 start = BBTOB(bp->b_maps[0].bm_bn) >> PAGE_SHIFT;
381 end = (BBTOB(bp->b_map.bm_bn + bp->b_length) + PAGE_SIZE - 1) 381 end = (BBTOB(bp->b_maps[0].bm_bn + bp->b_length) + PAGE_SIZE - 1)
382 >> PAGE_SHIFT; 382 >> PAGE_SHIFT;
383 page_count = end - start; 383 page_count = end - start;
384 error = _xfs_buf_get_pages(bp, page_count, flags); 384 error = _xfs_buf_get_pages(bp, page_count, flags);
@@ -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));
@@ -640,7 +658,7 @@ _xfs_buf_read(
640 xfs_buf_flags_t flags) 658 xfs_buf_flags_t flags)
641{ 659{
642 ASSERT(!(flags & XBF_WRITE)); 660 ASSERT(!(flags & XBF_WRITE));
643 ASSERT(bp->b_map.bm_bn != XFS_BUF_DADDR_NULL); 661 ASSERT(bp->b_maps[0].bm_bn != XFS_BUF_DADDR_NULL);
644 662
645 bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); 663 bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD);
646 bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); 664 bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD);
@@ -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;
@@ -1709,7 +1729,7 @@ xfs_buf_cmp(
1709 struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list); 1729 struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list);
1710 xfs_daddr_t diff; 1730 xfs_daddr_t diff;
1711 1731
1712 diff = ap->b_map.bm_bn - bp->b_map.bm_bn; 1732 diff = ap->b_maps[0].bm_bn - bp->b_maps[0].bm_bn;
1713 if (diff < 0) 1733 if (diff < 0)
1714 return -1; 1734 return -1;
1715 if (diff > 0) 1735 if (diff > 0)