diff options
Diffstat (limited to 'fs/xfs/xfs_aops.c')
-rw-r--r-- | fs/xfs/xfs_aops.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 75df77d09f75..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 | ||
@@ -1566,6 +1580,16 @@ xfs_vm_write_failed( | |||
1566 | 1580 | ||
1567 | xfs_vm_kill_delalloc_range(inode, block_offset, | 1581 | xfs_vm_kill_delalloc_range(inode, block_offset, |
1568 | block_offset + bh->b_size); | 1582 | block_offset + bh->b_size); |
1583 | |||
1584 | /* | ||
1585 | * This buffer does not contain data anymore. make sure anyone | ||
1586 | * who finds it knows that for certain. | ||
1587 | */ | ||
1588 | clear_buffer_delay(bh); | ||
1589 | clear_buffer_uptodate(bh); | ||
1590 | clear_buffer_mapped(bh); | ||
1591 | clear_buffer_new(bh); | ||
1592 | clear_buffer_dirty(bh); | ||
1569 | } | 1593 | } |
1570 | 1594 | ||
1571 | } | 1595 | } |
@@ -1599,12 +1623,21 @@ xfs_vm_write_begin( | |||
1599 | status = __block_write_begin(page, pos, len, xfs_get_blocks); | 1623 | status = __block_write_begin(page, pos, len, xfs_get_blocks); |
1600 | if (unlikely(status)) { | 1624 | if (unlikely(status)) { |
1601 | struct inode *inode = mapping->host; | 1625 | struct inode *inode = mapping->host; |
1626 | size_t isize = i_size_read(inode); | ||
1602 | 1627 | ||
1603 | xfs_vm_write_failed(inode, page, pos, len); | 1628 | xfs_vm_write_failed(inode, page, pos, len); |
1604 | unlock_page(page); | 1629 | unlock_page(page); |
1605 | 1630 | ||
1606 | if (pos + len > i_size_read(inode)) | 1631 | /* |
1607 | truncate_pagecache(inode, i_size_read(inode)); | 1632 | * If the write is beyond EOF, we only want to kill blocks |
1633 | * allocated in this write, not blocks that were previously | ||
1634 | * written successfully. | ||
1635 | */ | ||
1636 | if (pos + len > isize) { | ||
1637 | ssize_t start = max_t(ssize_t, pos, isize); | ||
1638 | |||
1639 | truncate_pagecache_range(inode, start, pos + len); | ||
1640 | } | ||
1608 | 1641 | ||
1609 | page_cache_release(page); | 1642 | page_cache_release(page); |
1610 | page = NULL; | 1643 | page = NULL; |
@@ -1615,9 +1648,12 @@ xfs_vm_write_begin( | |||
1615 | } | 1648 | } |
1616 | 1649 | ||
1617 | /* | 1650 | /* |
1618 | * On failure, we only need to kill delalloc blocks beyond EOF because they | 1651 | * On failure, we only need to kill delalloc blocks beyond EOF in the range of |
1619 | * will never be written. For blocks within EOF, generic_write_end() zeros them | 1652 | * this specific write because they will never be written. Previous writes |
1620 | * so they are safe to leave alone and be written with all the other valid data. | 1653 | * beyond EOF where block allocation succeeded do not need to be trashed, so |
1654 | * only new blocks from this write should be trashed. For blocks within | ||
1655 | * EOF, generic_write_end() zeros them so they are safe to leave alone and be | ||
1656 | * written with all the other valid data. | ||
1621 | */ | 1657 | */ |
1622 | STATIC int | 1658 | STATIC int |
1623 | xfs_vm_write_end( | 1659 | xfs_vm_write_end( |
@@ -1640,8 +1676,11 @@ xfs_vm_write_end( | |||
1640 | loff_t to = pos + len; | 1676 | loff_t to = pos + len; |
1641 | 1677 | ||
1642 | if (to > isize) { | 1678 | if (to > isize) { |
1643 | truncate_pagecache(inode, isize); | 1679 | /* only kill blocks in this write beyond EOF */ |
1680 | if (pos > isize) | ||
1681 | isize = pos; | ||
1644 | xfs_vm_kill_delalloc_range(inode, isize, to); | 1682 | xfs_vm_kill_delalloc_range(inode, isize, to); |
1683 | truncate_pagecache_range(inode, isize, to); | ||
1645 | } | 1684 | } |
1646 | } | 1685 | } |
1647 | return ret; | 1686 | return ret; |