aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/inode.c60
-rw-r--r--fs/btrfs/ordered-data.c13
-rw-r--r--fs/btrfs/ordered-data.h7
3 files changed, 62 insertions, 18 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4d4e2de3e879..f0e41b840739 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2562,8 +2562,10 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
2562 struct extent_state *cached_state = NULL; 2562 struct extent_state *cached_state = NULL;
2563 struct new_sa_defrag_extent *new = NULL; 2563 struct new_sa_defrag_extent *new = NULL;
2564 int compress_type = 0; 2564 int compress_type = 0;
2565 int ret; 2565 int ret = 0;
2566 u64 logical_len = ordered_extent->len;
2566 bool nolock; 2567 bool nolock;
2568 bool truncated = false;
2567 2569
2568 nolock = btrfs_is_free_space_inode(inode); 2570 nolock = btrfs_is_free_space_inode(inode);
2569 2571
@@ -2572,6 +2574,14 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
2572 goto out; 2574 goto out;
2573 } 2575 }
2574 2576
2577 if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
2578 truncated = true;
2579 logical_len = ordered_extent->truncated_len;
2580 /* Truncated the entire extent, don't bother adding */
2581 if (!logical_len)
2582 goto out;
2583 }
2584
2575 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { 2585 if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
2576 BUG_ON(!list_empty(&ordered_extent->list)); /* Logic error */ 2586 BUG_ON(!list_empty(&ordered_extent->list)); /* Logic error */
2577 btrfs_ordered_update_i_size(inode, 0, ordered_extent); 2587 btrfs_ordered_update_i_size(inode, 0, ordered_extent);
@@ -2627,15 +2637,14 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
2627 ret = btrfs_mark_extent_written(trans, inode, 2637 ret = btrfs_mark_extent_written(trans, inode,
2628 ordered_extent->file_offset, 2638 ordered_extent->file_offset,
2629 ordered_extent->file_offset + 2639 ordered_extent->file_offset +
2630 ordered_extent->len); 2640 logical_len);
2631 } else { 2641 } else {
2632 BUG_ON(root == root->fs_info->tree_root); 2642 BUG_ON(root == root->fs_info->tree_root);
2633 ret = insert_reserved_file_extent(trans, inode, 2643 ret = insert_reserved_file_extent(trans, inode,
2634 ordered_extent->file_offset, 2644 ordered_extent->file_offset,
2635 ordered_extent->start, 2645 ordered_extent->start,
2636 ordered_extent->disk_len, 2646 ordered_extent->disk_len,
2637 ordered_extent->len, 2647 logical_len, logical_len,
2638 ordered_extent->len,
2639 compress_type, 0, 0, 2648 compress_type, 0, 0,
2640 BTRFS_FILE_EXTENT_REG); 2649 BTRFS_FILE_EXTENT_REG);
2641 } 2650 }
@@ -2667,17 +2676,27 @@ out:
2667 if (trans) 2676 if (trans)
2668 btrfs_end_transaction(trans, root); 2677 btrfs_end_transaction(trans, root);
2669 2678
2670 if (ret) { 2679 if (ret || truncated) {
2671 clear_extent_uptodate(io_tree, ordered_extent->file_offset, 2680 u64 start, end;
2672 ordered_extent->file_offset + 2681
2673 ordered_extent->len - 1, NULL, GFP_NOFS); 2682 if (truncated)
2683 start = ordered_extent->file_offset + logical_len;
2684 else
2685 start = ordered_extent->file_offset;
2686 end = ordered_extent->file_offset + ordered_extent->len - 1;
2687 clear_extent_uptodate(io_tree, start, end, NULL, GFP_NOFS);
2688
2689 /* Drop the cache for the part of the extent we didn't write. */
2690 btrfs_drop_extent_cache(inode, start, end, 0);
2674 2691
2675 /* 2692 /*
2676 * If the ordered extent had an IOERR or something else went 2693 * If the ordered extent had an IOERR or something else went
2677 * wrong we need to return the space for this ordered extent 2694 * wrong we need to return the space for this ordered extent
2678 * back to the allocator. 2695 * back to the allocator. We only free the extent in the
2696 * truncated case if we didn't write out the extent at all.
2679 */ 2697 */
2680 if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) && 2698 if ((ret || !logical_len) &&
2699 !test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
2681 !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) 2700 !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags))
2682 btrfs_free_reserved_extent(root, ordered_extent->start, 2701 btrfs_free_reserved_extent(root, ordered_extent->start,
2683 ordered_extent->disk_len); 2702 ordered_extent->disk_len);
@@ -7336,10 +7355,23 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset,
7336 * whoever cleared the private bit is responsible 7355 * whoever cleared the private bit is responsible
7337 * for the finish_ordered_io 7356 * for the finish_ordered_io
7338 */ 7357 */
7339 if (TestClearPagePrivate2(page) && 7358 if (TestClearPagePrivate2(page)) {
7340 btrfs_dec_test_ordered_pending(inode, &ordered, page_start, 7359 struct btrfs_ordered_inode_tree *tree;
7341 PAGE_CACHE_SIZE, 1)) { 7360 u64 new_len;
7342 btrfs_finish_ordered_io(ordered); 7361
7362 tree = &BTRFS_I(inode)->ordered_tree;
7363
7364 spin_lock_irq(&tree->lock);
7365 set_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags);
7366 new_len = page_start - ordered->file_offset;
7367 if (new_len < ordered->truncated_len)
7368 ordered->truncated_len = new_len;
7369 spin_unlock_irq(&tree->lock);
7370
7371 if (btrfs_dec_test_ordered_pending(inode, &ordered,
7372 page_start,
7373 PAGE_CACHE_SIZE, 1))
7374 btrfs_finish_ordered_io(ordered);
7343 } 7375 }
7344 btrfs_put_ordered_extent(ordered); 7376 btrfs_put_ordered_extent(ordered);
7345 cached_state = NULL; 7377 cached_state = NULL;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index f2023ccb7cf6..966b413a33b8 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -205,6 +205,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
205 entry->bytes_left = len; 205 entry->bytes_left = len;
206 entry->inode = igrab(inode); 206 entry->inode = igrab(inode);
207 entry->compress_type = compress_type; 207 entry->compress_type = compress_type;
208 entry->truncated_len = (u64)-1;
208 if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) 209 if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)
209 set_bit(type, &entry->flags); 210 set_bit(type, &entry->flags);
210 211
@@ -920,12 +921,16 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
920 struct btrfs_ordered_extent *test; 921 struct btrfs_ordered_extent *test;
921 int ret = 1; 922 int ret = 1;
922 923
923 if (ordered) 924 spin_lock_irq(&tree->lock);
925 if (ordered) {
924 offset = entry_end(ordered); 926 offset = entry_end(ordered);
925 else 927 if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags))
928 offset = min(offset,
929 ordered->file_offset +
930 ordered->truncated_len);
931 } else {
926 offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); 932 offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
927 933 }
928 spin_lock_irq(&tree->lock);
929 disk_i_size = BTRFS_I(inode)->disk_i_size; 934 disk_i_size = BTRFS_I(inode)->disk_i_size;
930 935
931 /* truncate file */ 936 /* truncate file */
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 68844d59ee6f..d9a5aa097b4f 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -69,6 +69,7 @@ struct btrfs_ordered_sum {
69 * the isize. */ 69 * the isize. */
70#define BTRFS_ORDERED_LOGGED_CSUM 8 /* We've logged the csums on this ordered 70#define BTRFS_ORDERED_LOGGED_CSUM 8 /* We've logged the csums on this ordered
71 ordered extent */ 71 ordered extent */
72#define BTRFS_ORDERED_TRUNCATED 9 /* Set when we have to truncate an extent */
72 73
73struct btrfs_ordered_extent { 74struct btrfs_ordered_extent {
74 /* logical offset in the file */ 75 /* logical offset in the file */
@@ -96,6 +97,12 @@ struct btrfs_ordered_extent {
96 */ 97 */
97 u64 outstanding_isize; 98 u64 outstanding_isize;
98 99
100 /*
101 * If we get truncated we need to adjust the file extent we enter for
102 * this ordered extent so that we do not expose stale data.
103 */
104 u64 truncated_len;
105
99 /* flags (described above) */ 106 /* flags (described above) */
100 unsigned long flags; 107 unsigned long flags;
101 108