aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_aops.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index e0a793113ea9..0479c32c5eb1 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1344,6 +1344,14 @@ __xfs_get_blocks(
1344 /* 1344 /*
1345 * If this is O_DIRECT or the mpage code calling tell them how large 1345 * If this is O_DIRECT or the mpage code calling tell them how large
1346 * the mapping is, so that we can avoid repeated get_blocks calls. 1346 * the mapping is, so that we can avoid repeated get_blocks calls.
1347 *
1348 * If the mapping spans EOF, then we have to break the mapping up as the
1349 * mapping for blocks beyond EOF must be marked new so that sub block
1350 * regions can be correctly zeroed. We can't do this for mappings within
1351 * EOF unless the mapping was just allocated or is unwritten, otherwise
1352 * the callers would overwrite existing data with zeros. Hence we have
1353 * to split the mapping into a range up to and including EOF, and a
1354 * second mapping for beyond EOF.
1347 */ 1355 */
1348 if (direct || size > (1 << inode->i_blkbits)) { 1356 if (direct || size > (1 << inode->i_blkbits)) {
1349 xfs_off_t mapping_size; 1357 xfs_off_t mapping_size;
@@ -1354,6 +1362,12 @@ __xfs_get_blocks(
1354 ASSERT(mapping_size > 0); 1362 ASSERT(mapping_size > 0);
1355 if (mapping_size > size) 1363 if (mapping_size > size)
1356 mapping_size = size; 1364 mapping_size = size;
1365 if (offset < i_size_read(inode) &&
1366 offset + mapping_size >= i_size_read(inode)) {
1367 /* limit mapping to block that spans EOF */
1368 mapping_size = roundup_64(i_size_read(inode) - offset,
1369 1 << inode->i_blkbits);
1370 }
1357 if (mapping_size > LONG_MAX) 1371 if (mapping_size > LONG_MAX)
1358 mapping_size = LONG_MAX; 1372 mapping_size = LONG_MAX;
1359 1373