diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 6feecd279470..1d51bdde5748 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -1536,16 +1536,23 @@ __xfs_get_blocks( | |||
1536 | } | 1536 | } |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | /* | ||
1540 | * If this is O_DIRECT or the mpage code calling tell them how large | ||
1541 | * the mapping is, so that we can avoid repeated get_blocks calls. | ||
1542 | */ | ||
1539 | if (direct || size > (1 << inode->i_blkbits)) { | 1543 | if (direct || size > (1 << inode->i_blkbits)) { |
1540 | struct xfs_mount *mp = XFS_I(inode)->i_mount; | 1544 | xfs_off_t mapping_size; |
1541 | xfs_off_t iomap_offset = XFS_FSB_TO_B(mp, imap.br_startoff); | 1545 | |
1542 | xfs_off_t iomap_delta = offset - iomap_offset; | 1546 | mapping_size = imap.br_startoff + imap.br_blockcount - iblock; |
1543 | xfs_off_t iomap_bsize = XFS_FSB_TO_B(mp, imap.br_blockcount); | 1547 | mapping_size <<= inode->i_blkbits; |
1544 | 1548 | ||
1545 | ASSERT(iomap_bsize - iomap_delta > 0); | 1549 | ASSERT(mapping_size > 0); |
1546 | offset = min_t(xfs_off_t, | 1550 | if (mapping_size > size) |
1547 | iomap_bsize - iomap_delta, size); | 1551 | mapping_size = size; |
1548 | bh_result->b_size = (ssize_t)min_t(xfs_off_t, LONG_MAX, offset); | 1552 | if (mapping_size > LONG_MAX) |
1553 | mapping_size = LONG_MAX; | ||
1554 | |||
1555 | bh_result->b_size = mapping_size; | ||
1549 | } | 1556 | } |
1550 | 1557 | ||
1551 | return 0; | 1558 | return 0; |