diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2019-05-31 18:48:45 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-05-31 18:48:45 -0400 |
| commit | 24e8a2ca1f74574ad2ed1ac7af0260dd90fd911e (patch) | |
| tree | c863dd43c84579d853f3a2ae0ee6ead46c967703 /fs/btrfs | |
| parent | 66f61c92889ff3ca365161fb29dd36d6354682ba (diff) | |
| parent | d724c9e54939a597592de3659541da11fc7aa112 (diff) | |
Merge tag 'kvm-ppc-fixes-5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into kvm-master
PPC KVM fixes for 5.2
- Several bug fixes for the new XIVE-native code.
- Replace kvm->lock by other mutexes in several places where we hold a
vcpu mutex, to avoid lock order inversions.
- Fix a lockdep warning on guest entry for radix-mode guests.
- Fix a bug causing user-visible corruption of SPRG3 on the host.
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/compression.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 15 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 16 | ||||
| -rw-r--r-- | fs/btrfs/props.c | 30 | ||||
| -rw-r--r-- | fs/btrfs/root-tree.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/sysfs.c | 7 | ||||
| -rw-r--r-- | fs/btrfs/tree-checker.c | 49 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 1 |
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 | ||
| 759 | static void add_pinned_bytes(struct btrfs_fs_info *fs_info, | 759 | static 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 | } |
| 7191 | out: | 7192 | out: |
| 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 | ||
| 831 | int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info) | 836 | int 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 | ||
| 110 | static 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 | |||
| 110 | static int check_extent_data_item(struct extent_buffer *leaf, | 127 | static 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 | */ |
| 776 | static int check_leaf_item(struct extent_buffer *leaf, | 816 | static 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 | } |
