diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b93fe05a39c7..e1a7f3cb5be9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -378,6 +378,7 @@ struct async_cow { | |||
378 | struct page *locked_page; | 378 | struct page *locked_page; |
379 | u64 start; | 379 | u64 start; |
380 | u64 end; | 380 | u64 end; |
381 | unsigned int write_flags; | ||
381 | struct list_head extents; | 382 | struct list_head extents; |
382 | struct btrfs_work work; | 383 | struct btrfs_work work; |
383 | }; | 384 | }; |
@@ -857,7 +858,8 @@ retry: | |||
857 | async_extent->ram_size, | 858 | async_extent->ram_size, |
858 | ins.objectid, | 859 | ins.objectid, |
859 | ins.offset, async_extent->pages, | 860 | ins.offset, async_extent->pages, |
860 | async_extent->nr_pages)) { | 861 | async_extent->nr_pages, |
862 | async_cow->write_flags)) { | ||
861 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; | 863 | struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; |
862 | struct page *p = async_extent->pages[0]; | 864 | struct page *p = async_extent->pages[0]; |
863 | const u64 start = async_extent->start; | 865 | const u64 start = async_extent->start; |
@@ -1191,7 +1193,8 @@ static noinline void async_cow_free(struct btrfs_work *work) | |||
1191 | 1193 | ||
1192 | static int cow_file_range_async(struct inode *inode, struct page *locked_page, | 1194 | static int cow_file_range_async(struct inode *inode, struct page *locked_page, |
1193 | u64 start, u64 end, int *page_started, | 1195 | u64 start, u64 end, int *page_started, |
1194 | unsigned long *nr_written) | 1196 | unsigned long *nr_written, |
1197 | unsigned int write_flags) | ||
1195 | { | 1198 | { |
1196 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 1199 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
1197 | struct async_cow *async_cow; | 1200 | struct async_cow *async_cow; |
@@ -1208,6 +1211,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, | |||
1208 | async_cow->root = root; | 1211 | async_cow->root = root; |
1209 | async_cow->locked_page = locked_page; | 1212 | async_cow->locked_page = locked_page; |
1210 | async_cow->start = start; | 1213 | async_cow->start = start; |
1214 | async_cow->write_flags = write_flags; | ||
1211 | 1215 | ||
1212 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && | 1216 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && |
1213 | !btrfs_test_opt(fs_info, FORCE_COMPRESS)) | 1217 | !btrfs_test_opt(fs_info, FORCE_COMPRESS)) |
@@ -1577,11 +1581,13 @@ static inline int need_force_cow(struct inode *inode, u64 start, u64 end) | |||
1577 | */ | 1581 | */ |
1578 | static int run_delalloc_range(void *private_data, struct page *locked_page, | 1582 | static int run_delalloc_range(void *private_data, struct page *locked_page, |
1579 | u64 start, u64 end, int *page_started, | 1583 | u64 start, u64 end, int *page_started, |
1580 | unsigned long *nr_written) | 1584 | unsigned long *nr_written, |
1585 | struct writeback_control *wbc) | ||
1581 | { | 1586 | { |
1582 | struct inode *inode = private_data; | 1587 | struct inode *inode = private_data; |
1583 | int ret; | 1588 | int ret; |
1584 | int force_cow = need_force_cow(inode, start, end); | 1589 | int force_cow = need_force_cow(inode, start, end); |
1590 | unsigned int write_flags = wbc_to_write_flags(wbc); | ||
1585 | 1591 | ||
1586 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) { | 1592 | if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) { |
1587 | ret = run_delalloc_nocow(inode, locked_page, start, end, | 1593 | ret = run_delalloc_nocow(inode, locked_page, start, end, |
@@ -1596,7 +1602,8 @@ static int run_delalloc_range(void *private_data, struct page *locked_page, | |||
1596 | set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | 1602 | set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, |
1597 | &BTRFS_I(inode)->runtime_flags); | 1603 | &BTRFS_I(inode)->runtime_flags); |
1598 | ret = cow_file_range_async(inode, locked_page, start, end, | 1604 | ret = cow_file_range_async(inode, locked_page, start, end, |
1599 | page_started, nr_written); | 1605 | page_started, nr_written, |
1606 | write_flags); | ||
1600 | } | 1607 | } |
1601 | if (ret) | 1608 | if (ret) |
1602 | btrfs_cleanup_ordered_extents(inode, start, end - start + 1); | 1609 | btrfs_cleanup_ordered_extents(inode, start, end - start + 1); |
@@ -2025,11 +2032,12 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
2025 | } | 2032 | } |
2026 | 2033 | ||
2027 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 2034 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
2035 | unsigned int extra_bits, | ||
2028 | struct extent_state **cached_state, int dedupe) | 2036 | struct extent_state **cached_state, int dedupe) |
2029 | { | 2037 | { |
2030 | WARN_ON((end & (PAGE_SIZE - 1)) == 0); | 2038 | WARN_ON((end & (PAGE_SIZE - 1)) == 0); |
2031 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, | 2039 | return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, |
2032 | cached_state); | 2040 | extra_bits, cached_state); |
2033 | } | 2041 | } |
2034 | 2042 | ||
2035 | /* see btrfs_writepage_start_hook for details on why this is required */ | 2043 | /* see btrfs_writepage_start_hook for details on why this is required */ |
@@ -2090,7 +2098,7 @@ again: | |||
2090 | goto out; | 2098 | goto out; |
2091 | } | 2099 | } |
2092 | 2100 | ||
2093 | btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state, | 2101 | btrfs_set_extent_delalloc(inode, page_start, page_end, 0, &cached_state, |
2094 | 0); | 2102 | 0); |
2095 | ClearPageChecked(page); | 2103 | ClearPageChecked(page); |
2096 | set_page_dirty(page); | 2104 | set_page_dirty(page); |
@@ -2997,6 +3005,8 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) | |||
2997 | compress_type = ordered_extent->compress_type; | 3005 | compress_type = ordered_extent->compress_type; |
2998 | if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { | 3006 | if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { |
2999 | BUG_ON(compress_type); | 3007 | BUG_ON(compress_type); |
3008 | btrfs_qgroup_free_data(inode, NULL, ordered_extent->file_offset, | ||
3009 | ordered_extent->len); | ||
3000 | ret = btrfs_mark_extent_written(trans, BTRFS_I(inode), | 3010 | ret = btrfs_mark_extent_written(trans, BTRFS_I(inode), |
3001 | ordered_extent->file_offset, | 3011 | ordered_extent->file_offset, |
3002 | ordered_extent->file_offset + | 3012 | ordered_extent->file_offset + |
@@ -4790,7 +4800,7 @@ again: | |||
4790 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, | 4800 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, |
4791 | 0, 0, &cached_state, GFP_NOFS); | 4801 | 0, 0, &cached_state, GFP_NOFS); |
4792 | 4802 | ||
4793 | ret = btrfs_set_extent_delalloc(inode, block_start, block_end, | 4803 | ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 0, |
4794 | &cached_state, 0); | 4804 | &cached_state, 0); |
4795 | if (ret) { | 4805 | if (ret) { |
4796 | unlock_extent_cached(io_tree, block_start, block_end, | 4806 | unlock_extent_cached(io_tree, block_start, block_end, |
@@ -5438,6 +5448,14 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, | |||
5438 | goto out_err; | 5448 | goto out_err; |
5439 | 5449 | ||
5440 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, location); | 5450 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, location); |
5451 | if (location->type != BTRFS_INODE_ITEM_KEY && | ||
5452 | location->type != BTRFS_ROOT_ITEM_KEY) { | ||
5453 | btrfs_warn(root->fs_info, | ||
5454 | "%s gets something invalid in DIR_ITEM (name %s, directory ino %llu, location(%llu %u %llu))", | ||
5455 | __func__, name, btrfs_ino(BTRFS_I(dir)), | ||
5456 | location->objectid, location->type, location->offset); | ||
5457 | goto out_err; | ||
5458 | } | ||
5441 | out: | 5459 | out: |
5442 | btrfs_free_path(path); | 5460 | btrfs_free_path(path); |
5443 | return ret; | 5461 | return ret; |
@@ -5754,8 +5772,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
5754 | return inode; | 5772 | return inode; |
5755 | } | 5773 | } |
5756 | 5774 | ||
5757 | BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); | ||
5758 | |||
5759 | index = srcu_read_lock(&fs_info->subvol_srcu); | 5775 | index = srcu_read_lock(&fs_info->subvol_srcu); |
5760 | ret = fixup_tree_root_location(fs_info, dir, dentry, | 5776 | ret = fixup_tree_root_location(fs_info, dir, dentry, |
5761 | &location, &sub_root); | 5777 | &location, &sub_root); |
@@ -9150,7 +9166,7 @@ again: | |||
9150 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, | 9166 | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, |
9151 | 0, 0, &cached_state, GFP_NOFS); | 9167 | 0, 0, &cached_state, GFP_NOFS); |
9152 | 9168 | ||
9153 | ret = btrfs_set_extent_delalloc(inode, page_start, end, | 9169 | ret = btrfs_set_extent_delalloc(inode, page_start, end, 0, |
9154 | &cached_state, 0); | 9170 | &cached_state, 0); |
9155 | if (ret) { | 9171 | if (ret) { |
9156 | unlock_extent_cached(io_tree, page_start, page_end, | 9172 | unlock_extent_cached(io_tree, page_start, page_end, |