summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-20 12:52:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-20 12:52:35 -0400
commitf49aa1de98363b6c5fba4637678d6b0ba3d18065 (patch)
treef02df2090c2d5baf0276ab6fa53c80db783c4765 /fs
parent78e03651849fd3e8aa9ab3288bc1d3726c4c6129 (diff)
parent4e9845eff5a8027b5181d5bff56a02991fe46d48 (diff)
Merge tag 'for-5.2-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Notable highlights: - fixes for some long-standing bugs in fsync that were quite hard to catch but now finaly fixed - some fixups to error handling paths that did not properly clean up (locking, memory) - fix to space reservation for inheriting properties" * tag 'for-5.2-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: Btrfs: tree-checker: detect file extent items with overlapping ranges Btrfs: fix race between ranged fsync and writeback of adjacent ranges Btrfs: avoid fallback to transaction commit during fsync of files with holes btrfs: extent-tree: Fix a bug that btrfs is unable to add pinned bytes btrfs: sysfs: don't leak memory when failing add fsid btrfs: sysfs: Fix error path kobject memory leak Btrfs: do not abort transaction at btrfs_update_root() after failure to COW path btrfs: use the existing reserved items for our first prop for inheritance btrfs: don't double unlock on error in btrfs_punch_hole btrfs: Check the compression level before getting a workspace
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/compression.c1
-rw-r--r--fs/btrfs/extent-tree.c15
-rw-r--r--fs/btrfs/file.c16
-rw-r--r--fs/btrfs/props.c30
-rw-r--r--fs/btrfs/root-tree.c4
-rw-r--r--fs/btrfs/sysfs.c7
-rw-r--r--fs/btrfs/tree-checker.c49
-rw-r--r--fs/btrfs/tree-log.c1
8 files changed, 97 insertions, 26 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index daf7908d1e35..84dd4a8980c5 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -1008,6 +1008,7 @@ int btrfs_compress_pages(unsigned int type_level, struct address_space *mapping,
1008 struct list_head *workspace; 1008 struct list_head *workspace;
1009 int ret; 1009 int ret;
1010 1010
1011 level = btrfs_compress_op[type]->set_level(level);
1011 workspace = get_workspace(type, level); 1012 workspace = get_workspace(type, level);
1012 ret = btrfs_compress_op[type]->compress_pages(workspace, mapping, 1013 ret = btrfs_compress_op[type]->compress_pages(workspace, mapping,
1013 start, pages, 1014 start, pages,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f79e477a378e..1aee51a9f3bf 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -757,12 +757,14 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
757} 757}
758 758
759static void add_pinned_bytes(struct btrfs_fs_info *fs_info, 759static void add_pinned_bytes(struct btrfs_fs_info *fs_info,
760 struct btrfs_ref *ref) 760 struct btrfs_ref *ref, int sign)
761{ 761{
762 struct btrfs_space_info *space_info; 762 struct btrfs_space_info *space_info;
763 s64 num_bytes = -ref->len; 763 s64 num_bytes;
764 u64 flags; 764 u64 flags;
765 765
766 ASSERT(sign == 1 || sign == -1);
767 num_bytes = sign * ref->len;
766 if (ref->type == BTRFS_REF_METADATA) { 768 if (ref->type == BTRFS_REF_METADATA) {
767 if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID) 769 if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID)
768 flags = BTRFS_BLOCK_GROUP_SYSTEM; 770 flags = BTRFS_BLOCK_GROUP_SYSTEM;
@@ -2063,7 +2065,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
2063 btrfs_ref_tree_mod(fs_info, generic_ref); 2065 btrfs_ref_tree_mod(fs_info, generic_ref);
2064 2066
2065 if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0) 2067 if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0)
2066 add_pinned_bytes(fs_info, generic_ref); 2068 add_pinned_bytes(fs_info, generic_ref, -1);
2067 2069
2068 return ret; 2070 return ret;
2069} 2071}
@@ -3882,8 +3884,7 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags)
3882 info->space_info_kobj, "%s", 3884 info->space_info_kobj, "%s",
3883 alloc_name(space_info->flags)); 3885 alloc_name(space_info->flags));
3884 if (ret) { 3886 if (ret) {
3885 percpu_counter_destroy(&space_info->total_bytes_pinned); 3887 kobject_put(&space_info->kobj);
3886 kfree(space_info);
3887 return ret; 3888 return ret;
3888 } 3889 }
3889 3890
@@ -7190,7 +7191,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
7190 } 7191 }
7191out: 7192out:
7192 if (pin) 7193 if (pin)
7193 add_pinned_bytes(fs_info, &generic_ref); 7194 add_pinned_bytes(fs_info, &generic_ref, 1);
7194 7195
7195 if (last_ref) { 7196 if (last_ref) {
7196 /* 7197 /*
@@ -7238,7 +7239,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref)
7238 btrfs_ref_tree_mod(fs_info, ref); 7239 btrfs_ref_tree_mod(fs_info, ref);
7239 7240
7240 if (ret == 0 && old_ref_mod >= 0 && new_ref_mod < 0) 7241 if (ret == 0 && old_ref_mod >= 0 && new_ref_mod < 0)
7241 add_pinned_bytes(fs_info, ref); 7242 add_pinned_bytes(fs_info, ref, 1);
7242 7243
7243 return ret; 7244 return ret;
7244} 7245}
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 7e85dca0e6f2..89f5be2bfb43 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2068,6 +2068,18 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
2068 u64 len; 2068 u64 len;
2069 2069
2070 /* 2070 /*
2071 * If the inode needs a full sync, make sure we use a full range to
2072 * avoid log tree corruption, due to hole detection racing with ordered
2073 * extent completion for adjacent ranges, and assertion failures during
2074 * hole detection.
2075 */
2076 if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
2077 &BTRFS_I(inode)->runtime_flags)) {
2078 start = 0;
2079 end = LLONG_MAX;
2080 }
2081
2082 /*
2071 * The range length can be represented by u64, we have to do the typecasts 2083 * The range length can be represented by u64, we have to do the typecasts
2072 * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync() 2084 * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
2073 */ 2085 */
@@ -2554,10 +2566,8 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
2554 2566
2555 ret = btrfs_punch_hole_lock_range(inode, lockstart, lockend, 2567 ret = btrfs_punch_hole_lock_range(inode, lockstart, lockend,
2556 &cached_state); 2568 &cached_state);
2557 if (ret) { 2569 if (ret)
2558 inode_unlock(inode);
2559 goto out_only_mutex; 2570 goto out_only_mutex;
2560 }
2561 2571
2562 path = btrfs_alloc_path(); 2572 path = btrfs_alloc_path();
2563 if (!path) { 2573 if (!path) {
diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c
index ca2716917e37..a9e2e66152ee 100644
--- a/fs/btrfs/props.c
+++ b/fs/btrfs/props.c
@@ -332,6 +332,7 @@ static int inherit_props(struct btrfs_trans_handle *trans,
332 struct btrfs_fs_info *fs_info = root->fs_info; 332 struct btrfs_fs_info *fs_info = root->fs_info;
333 int ret; 333 int ret;
334 int i; 334 int i;
335 bool need_reserve = false;
335 336
336 if (!test_bit(BTRFS_INODE_HAS_PROPS, 337 if (!test_bit(BTRFS_INODE_HAS_PROPS,
337 &BTRFS_I(parent)->runtime_flags)) 338 &BTRFS_I(parent)->runtime_flags))
@@ -357,11 +358,20 @@ static int inherit_props(struct btrfs_trans_handle *trans,
357 if (ret) 358 if (ret)
358 continue; 359 continue;
359 360
360 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1); 361 /*
361 ret = btrfs_block_rsv_add(root, trans->block_rsv, 362 * Currently callers should be reserving 1 item for properties,
362 num_bytes, BTRFS_RESERVE_NO_FLUSH); 363 * since we only have 1 property that we currently support. If
363 if (ret) 364 * we add more in the future we need to try and reserve more
364 return ret; 365 * space for them. But we should also revisit how we do space
366 * reservations if we do add more properties in the future.
367 */
368 if (need_reserve) {
369 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
370 ret = btrfs_block_rsv_add(root, trans->block_rsv,
371 num_bytes, BTRFS_RESERVE_NO_FLUSH);
372 if (ret)
373 return ret;
374 }
365 375
366 ret = btrfs_setxattr(trans, inode, h->xattr_name, value, 376 ret = btrfs_setxattr(trans, inode, h->xattr_name, value,
367 strlen(value), 0); 377 strlen(value), 0);
@@ -375,9 +385,13 @@ static int inherit_props(struct btrfs_trans_handle *trans,
375 &BTRFS_I(inode)->runtime_flags); 385 &BTRFS_I(inode)->runtime_flags);
376 } 386 }
377 387
378 btrfs_block_rsv_release(fs_info, trans->block_rsv, num_bytes); 388 if (need_reserve) {
379 if (ret) 389 btrfs_block_rsv_release(fs_info, trans->block_rsv,
380 return ret; 390 num_bytes);
391 if (ret)
392 return ret;
393 }
394 need_reserve = true;
381 } 395 }
382 396
383 return 0; 397 return 0;
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 1b9a5d0de139..22124122728c 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -132,10 +132,8 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
132 return -ENOMEM; 132 return -ENOMEM;
133 133
134 ret = btrfs_search_slot(trans, root, key, path, 0, 1); 134 ret = btrfs_search_slot(trans, root, key, path, 0, 1);
135 if (ret < 0) { 135 if (ret < 0)
136 btrfs_abort_transaction(trans, ret);
137 goto out; 136 goto out;
138 }
139 137
140 if (ret > 0) { 138 if (ret > 0) {
141 btrfs_crit(fs_info, 139 btrfs_crit(fs_info,
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index 5a5930e3d32b..2f078b77fe14 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -825,7 +825,12 @@ int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
825 fs_devs->fsid_kobj.kset = btrfs_kset; 825 fs_devs->fsid_kobj.kset = btrfs_kset;
826 error = kobject_init_and_add(&fs_devs->fsid_kobj, 826 error = kobject_init_and_add(&fs_devs->fsid_kobj,
827 &btrfs_ktype, parent, "%pU", fs_devs->fsid); 827 &btrfs_ktype, parent, "%pU", fs_devs->fsid);
828 return error; 828 if (error) {
829 kobject_put(&fs_devs->fsid_kobj);
830 return error;
831 }
832
833 return 0;
829} 834}
830 835
831int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info) 836int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info)
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 748cd1598255..96fce4bef4e7 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -107,8 +107,26 @@ static void file_extent_err(const struct extent_buffer *eb, int slot,
107 (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))); \ 107 (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))); \
108}) 108})
109 109
110static u64 file_extent_end(struct extent_buffer *leaf,
111 struct btrfs_key *key,
112 struct btrfs_file_extent_item *extent)
113{
114 u64 end;
115 u64 len;
116
117 if (btrfs_file_extent_type(leaf, extent) == BTRFS_FILE_EXTENT_INLINE) {
118 len = btrfs_file_extent_ram_bytes(leaf, extent);
119 end = ALIGN(key->offset + len, leaf->fs_info->sectorsize);
120 } else {
121 len = btrfs_file_extent_num_bytes(leaf, extent);
122 end = key->offset + len;
123 }
124 return end;
125}
126
110static int check_extent_data_item(struct extent_buffer *leaf, 127static int check_extent_data_item(struct extent_buffer *leaf,
111 struct btrfs_key *key, int slot) 128 struct btrfs_key *key, int slot,
129 struct btrfs_key *prev_key)
112{ 130{
113 struct btrfs_fs_info *fs_info = leaf->fs_info; 131 struct btrfs_fs_info *fs_info = leaf->fs_info;
114 struct btrfs_file_extent_item *fi; 132 struct btrfs_file_extent_item *fi;
@@ -188,6 +206,28 @@ static int check_extent_data_item(struct extent_buffer *leaf,
188 CHECK_FE_ALIGNED(leaf, slot, fi, offset, sectorsize) || 206 CHECK_FE_ALIGNED(leaf, slot, fi, offset, sectorsize) ||
189 CHECK_FE_ALIGNED(leaf, slot, fi, num_bytes, sectorsize)) 207 CHECK_FE_ALIGNED(leaf, slot, fi, num_bytes, sectorsize))
190 return -EUCLEAN; 208 return -EUCLEAN;
209
210 /*
211 * Check that no two consecutive file extent items, in the same leaf,
212 * present ranges that overlap each other.
213 */
214 if (slot > 0 &&
215 prev_key->objectid == key->objectid &&
216 prev_key->type == BTRFS_EXTENT_DATA_KEY) {
217 struct btrfs_file_extent_item *prev_fi;
218 u64 prev_end;
219
220 prev_fi = btrfs_item_ptr(leaf, slot - 1,
221 struct btrfs_file_extent_item);
222 prev_end = file_extent_end(leaf, prev_key, prev_fi);
223 if (prev_end > key->offset) {
224 file_extent_err(leaf, slot - 1,
225"file extent end range (%llu) goes beyond start offset (%llu) of the next file extent",
226 prev_end, key->offset);
227 return -EUCLEAN;
228 }
229 }
230
191 return 0; 231 return 0;
192} 232}
193 233
@@ -774,14 +814,15 @@ static int check_inode_item(struct extent_buffer *leaf,
774 * Common point to switch the item-specific validation. 814 * Common point to switch the item-specific validation.
775 */ 815 */
776static int check_leaf_item(struct extent_buffer *leaf, 816static int check_leaf_item(struct extent_buffer *leaf,
777 struct btrfs_key *key, int slot) 817 struct btrfs_key *key, int slot,
818 struct btrfs_key *prev_key)
778{ 819{
779 int ret = 0; 820 int ret = 0;
780 struct btrfs_chunk *chunk; 821 struct btrfs_chunk *chunk;
781 822
782 switch (key->type) { 823 switch (key->type) {
783 case BTRFS_EXTENT_DATA_KEY: 824 case BTRFS_EXTENT_DATA_KEY:
784 ret = check_extent_data_item(leaf, key, slot); 825 ret = check_extent_data_item(leaf, key, slot, prev_key);
785 break; 826 break;
786 case BTRFS_EXTENT_CSUM_KEY: 827 case BTRFS_EXTENT_CSUM_KEY:
787 ret = check_csum_item(leaf, key, slot); 828 ret = check_csum_item(leaf, key, slot);
@@ -928,7 +969,7 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
928 * Check if the item size and content meet other 969 * Check if the item size and content meet other
929 * criteria 970 * criteria
930 */ 971 */
931 ret = check_leaf_item(leaf, &key, slot); 972 ret = check_leaf_item(leaf, &key, slot, &prev_key);
932 if (ret < 0) 973 if (ret < 0)
933 return ret; 974 return ret;
934 } 975 }
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 6adcd8a2c5c7..6c47f6ed3e94 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4182,6 +4182,7 @@ fill_holes:
4182 *last_extent, 0, 4182 *last_extent, 0,
4183 0, len, 0, len, 4183 0, len, 0, len,
4184 0, 0, 0); 4184 0, 0, 0);
4185 *last_extent += len;
4185 } 4186 }
4186 } 4187 }
4187 } 4188 }