Commit fdc7ed75 authored by Nathan Scott's avatar Nathan Scott

[XFS] Fix boundary conditions when issuing direct IOs from large userspace

buffers.

SGI-PV: 944820
SGI-Modid: xfs-linux:xfs-kern:24223a
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 2b3b6d07
...@@ -935,15 +935,18 @@ __linvfs_get_block( ...@@ -935,15 +935,18 @@ __linvfs_get_block(
{ {
vnode_t *vp = LINVFS_GET_VP(inode); vnode_t *vp = LINVFS_GET_VP(inode);
xfs_iomap_t iomap; xfs_iomap_t iomap;
xfs_off_t offset;
ssize_t size;
int retpbbm = 1; int retpbbm = 1;
int error; int error;
ssize_t size;
loff_t offset = (loff_t)iblock << inode->i_blkbits;
if (blocks) if (blocks) {
size = blocks << inode->i_blkbits; offset = blocks << inode->i_blkbits; /* 64 bit goodness */
else size = (ssize_t) min_t(xfs_off_t, offset, LONG_MAX);
} else {
size = 1 << inode->i_blkbits; size = 1 << inode->i_blkbits;
}
offset = (xfs_off_t)iblock << inode->i_blkbits;
VOP_BMAP(vp, offset, size, VOP_BMAP(vp, offset, size,
create ? flags : BMAPI_READ, &iomap, &retpbbm, error); create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
...@@ -955,7 +958,7 @@ __linvfs_get_block( ...@@ -955,7 +958,7 @@ __linvfs_get_block(
if (iomap.iomap_bn != IOMAP_DADDR_NULL) { if (iomap.iomap_bn != IOMAP_DADDR_NULL) {
xfs_daddr_t bn; xfs_daddr_t bn;
loff_t delta; xfs_off_t delta;
/* For unwritten extents do not report a disk address on /* For unwritten extents do not report a disk address on
* the read case (treat as if we're reading into a hole). * the read case (treat as if we're reading into a hole).
...@@ -987,9 +990,8 @@ __linvfs_get_block( ...@@ -987,9 +990,8 @@ __linvfs_get_block(
*/ */
if (create && if (create &&
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) || ((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
(offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW))) { (offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW)))
set_buffer_new(bh_result); set_buffer_new(bh_result);
}
if (iomap.iomap_flags & IOMAP_DELAY) { if (iomap.iomap_flags & IOMAP_DELAY) {
BUG_ON(direct); BUG_ON(direct);
...@@ -1001,9 +1003,11 @@ __linvfs_get_block( ...@@ -1001,9 +1003,11 @@ __linvfs_get_block(
} }
if (blocks) { if (blocks) {
bh_result->b_size = (ssize_t)min( ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
(loff_t)(iomap.iomap_bsize - iomap.iomap_delta), offset = min_t(xfs_off_t,
(loff_t)(blocks << inode->i_blkbits)); iomap.iomap_bsize - iomap.iomap_delta,
blocks << inode->i_blkbits);
bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment