diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a18ceabd99a8..e4090259569b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1428,7 +1428,7 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos, | |||
1428 | u64 num_bytes; | 1428 | u64 num_bytes; |
1429 | int ret; | 1429 | int ret; |
1430 | 1430 | ||
1431 | ret = btrfs_start_nocow_write(root); | 1431 | ret = btrfs_start_write_no_snapshoting(root); |
1432 | if (!ret) | 1432 | if (!ret) |
1433 | return -ENOSPC; | 1433 | return -ENOSPC; |
1434 | 1434 | ||
@@ -1451,7 +1451,7 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos, | |||
1451 | ret = can_nocow_extent(inode, lockstart, &num_bytes, NULL, NULL, NULL); | 1451 | ret = can_nocow_extent(inode, lockstart, &num_bytes, NULL, NULL, NULL); |
1452 | if (ret <= 0) { | 1452 | if (ret <= 0) { |
1453 | ret = 0; | 1453 | ret = 0; |
1454 | btrfs_end_nocow_write(root); | 1454 | btrfs_end_write_no_snapshoting(root); |
1455 | } else { | 1455 | } else { |
1456 | *write_bytes = min_t(size_t, *write_bytes , | 1456 | *write_bytes = min_t(size_t, *write_bytes , |
1457 | num_bytes - pos + lockstart); | 1457 | num_bytes - pos + lockstart); |
@@ -1543,7 +1543,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1543 | btrfs_free_reserved_data_space(inode, | 1543 | btrfs_free_reserved_data_space(inode, |
1544 | reserve_bytes); | 1544 | reserve_bytes); |
1545 | else | 1545 | else |
1546 | btrfs_end_nocow_write(root); | 1546 | btrfs_end_write_no_snapshoting(root); |
1547 | break; | 1547 | break; |
1548 | } | 1548 | } |
1549 | 1549 | ||
@@ -1632,7 +1632,7 @@ again: | |||
1632 | 1632 | ||
1633 | release_bytes = 0; | 1633 | release_bytes = 0; |
1634 | if (only_release_metadata) | 1634 | if (only_release_metadata) |
1635 | btrfs_end_nocow_write(root); | 1635 | btrfs_end_write_no_snapshoting(root); |
1636 | 1636 | ||
1637 | if (only_release_metadata && copied > 0) { | 1637 | if (only_release_metadata && copied > 0) { |
1638 | u64 lockstart = round_down(pos, root->sectorsize); | 1638 | u64 lockstart = round_down(pos, root->sectorsize); |
@@ -1661,7 +1661,7 @@ again: | |||
1661 | 1661 | ||
1662 | if (release_bytes) { | 1662 | if (release_bytes) { |
1663 | if (only_release_metadata) { | 1663 | if (only_release_metadata) { |
1664 | btrfs_end_nocow_write(root); | 1664 | btrfs_end_write_no_snapshoting(root); |
1665 | btrfs_delalloc_release_metadata(inode, release_bytes); | 1665 | btrfs_delalloc_release_metadata(inode, release_bytes); |
1666 | } else { | 1666 | } else { |
1667 | btrfs_delalloc_release_space(inode, release_bytes); | 1667 | btrfs_delalloc_release_space(inode, release_bytes); |
@@ -1676,6 +1676,7 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, | |||
1676 | loff_t pos) | 1676 | loff_t pos) |
1677 | { | 1677 | { |
1678 | struct file *file = iocb->ki_filp; | 1678 | struct file *file = iocb->ki_filp; |
1679 | struct inode *inode = file_inode(file); | ||
1679 | ssize_t written; | 1680 | ssize_t written; |
1680 | ssize_t written_buffered; | 1681 | ssize_t written_buffered; |
1681 | loff_t endbyte; | 1682 | loff_t endbyte; |
@@ -1692,8 +1693,15 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, | |||
1692 | err = written_buffered; | 1693 | err = written_buffered; |
1693 | goto out; | 1694 | goto out; |
1694 | } | 1695 | } |
1696 | /* | ||
1697 | * Ensure all data is persisted. We want the next direct IO read to be | ||
1698 | * able to read what was just written. | ||
1699 | */ | ||
1695 | endbyte = pos + written_buffered - 1; | 1700 | endbyte = pos + written_buffered - 1; |
1696 | err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte); | 1701 | err = btrfs_fdatawrite_range(inode, pos, endbyte); |
1702 | if (err) | ||
1703 | goto out; | ||
1704 | err = filemap_fdatawait_range(inode->i_mapping, pos, endbyte); | ||
1697 | if (err) | 1705 | if (err) |
1698 | goto out; | 1706 | goto out; |
1699 | written += written_buffered; | 1707 | written += written_buffered; |
@@ -1854,10 +1862,7 @@ static int start_ordered_ops(struct inode *inode, loff_t start, loff_t end) | |||
1854 | int ret; | 1862 | int ret; |
1855 | 1863 | ||
1856 | atomic_inc(&BTRFS_I(inode)->sync_writers); | 1864 | atomic_inc(&BTRFS_I(inode)->sync_writers); |
1857 | ret = filemap_fdatawrite_range(inode->i_mapping, start, end); | 1865 | ret = btrfs_fdatawrite_range(inode, start, end); |
1858 | if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | ||
1859 | &BTRFS_I(inode)->runtime_flags)) | ||
1860 | ret = filemap_fdatawrite_range(inode->i_mapping, start, end); | ||
1861 | atomic_dec(&BTRFS_I(inode)->sync_writers); | 1866 | atomic_dec(&BTRFS_I(inode)->sync_writers); |
1862 | 1867 | ||
1863 | return ret; | 1868 | return ret; |
@@ -2810,3 +2815,29 @@ int btrfs_auto_defrag_init(void) | |||
2810 | 2815 | ||
2811 | return 0; | 2816 | return 0; |
2812 | } | 2817 | } |
2818 | |||
2819 | int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end) | ||
2820 | { | ||
2821 | int ret; | ||
2822 | |||
2823 | /* | ||
2824 | * So with compression we will find and lock a dirty page and clear the | ||
2825 | * first one as dirty, setup an async extent, and immediately return | ||
2826 | * with the entire range locked but with nobody actually marked with | ||
2827 | * writeback. So we can't just filemap_write_and_wait_range() and | ||
2828 | * expect it to work since it will just kick off a thread to do the | ||
2829 | * actual work. So we need to call filemap_fdatawrite_range _again_ | ||
2830 | * since it will wait on the page lock, which won't be unlocked until | ||
2831 | * after the pages have been marked as writeback and so we're good to go | ||
2832 | * from there. We have to do this otherwise we'll miss the ordered | ||
2833 | * extents and that results in badness. Please Josef, do not think you | ||
2834 | * know better and pull this out at some point in the future, it is | ||
2835 | * right and you are wrong. | ||
2836 | */ | ||
2837 | ret = filemap_fdatawrite_range(inode->i_mapping, start, end); | ||
2838 | if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | ||
2839 | &BTRFS_I(inode)->runtime_flags)) | ||
2840 | ret = filemap_fdatawrite_range(inode->i_mapping, start, end); | ||
2841 | |||
2842 | return ret; | ||
2843 | } | ||