Message ID | 1530021456-20749-1-git-send-email-nborisov@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Nikolay, Thank you for the patch! Yet something to improve: [auto build test ERROR on next-20180626] [cannot apply to btrfs/next v4.18-rc2 v4.18-rc1 v4.17 v4.18-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Nikolay-Borisov/btrfs-Add-graceful-handling-of-V0-extents/20180626-231445 config: x86_64-randconfig-x015-201825 (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): fs//btrfs/extent-tree.c: In function 'btrfs_lookup_extent_info': >> fs//btrfs/extent-tree.c:871:4: error: implicit declaration of function 'btrfs_print_v0_err'; did you mean 'btrfs_print_tree'? [-Werror=implicit-function-declaration] btrfs_print_v0_err(fs_info); ^~~~~~~~~~~~~~~~~~ btrfs_print_tree fs//btrfs/extent-tree.c: In function 'remove_extent_data_ref': >> fs//btrfs/extent-tree.c:1308:22: error: 'fs_info' undeclared (first use in this function); did you mean 'qc_info'? btrfs_print_v0_err(fs_info); ^~~~~~~ qc_info fs//btrfs/extent-tree.c:1308:22: note: each undeclared identifier is reported only once for each function it appears in cc1: some warnings being treated as errors -- fs//btrfs/print-tree.c: In function 'print_extent_item': >> fs//btrfs/print-tree.c:56:3: error: implicit declaration of function 'btrfs_print_v0_err'; did you mean 'btrfs_print_tree'? [-Werror=implicit-function-declaration] btrfs_print_v0_err(eb->fs_info); ^~~~~~~~~~~~~~~~~~ btrfs_print_tree cc1: some warnings being treated as errors -- fs//btrfs/relocation.c: In function 'find_inline_backref': >> fs//btrfs/relocation.c:602:3: error: implicit declaration of function 'btrfs_print_v0_err'; did you mean 'btrfs_print_tree'? [-Werror=implicit-function-declaration] btrfs_print_v0_err(leaf->fs_info); ^~~~~~~~~~~~~~~~~~ btrfs_print_tree cc1: some warnings being treated as errors vim +871 fs//btrfs/extent-tree.c 794 795 /* 796 * helper function to lookup reference count and flags of a tree block. 797 * 798 * the head node for delayed ref is used to store the sum of all the 799 * reference count modifications queued up in the rbtree. the head 800 * node may also store the extent flags to set. This way you can check 801 * to see what the reference count and extent flags would be if all of 802 * the delayed refs are not processed. 803 */ 804 int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, 805 struct btrfs_fs_info *fs_info, u64 bytenr, 806 u64 offset, int metadata, u64 *refs, u64 *flags) 807 { 808 struct btrfs_delayed_ref_head *head; 809 struct btrfs_delayed_ref_root *delayed_refs; 810 struct btrfs_path *path; 811 struct btrfs_extent_item *ei; 812 struct extent_buffer *leaf; 813 struct btrfs_key key; 814 u32 item_size; 815 u64 num_refs; 816 u64 extent_flags; 817 int ret; 818 819 /* 820 * If we don't have skinny metadata, don't bother doing anything 821 * different 822 */ 823 if (metadata && !btrfs_fs_incompat(fs_info, SKINNY_METADATA)) { 824 offset = fs_info->nodesize; 825 metadata = 0; 826 } 827 828 path = btrfs_alloc_path(); 829 if (!path) 830 return -ENOMEM; 831 832 if (!trans) { 833 path->skip_locking = 1; 834 path->search_commit_root = 1; 835 } 836 837 search_again: 838 key.objectid = bytenr; 839 key.offset = offset; 840 if (metadata) 841 key.type = BTRFS_METADATA_ITEM_KEY; 842 else 843 key.type = BTRFS_EXTENT_ITEM_KEY; 844 845 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); 846 if (ret < 0) 847 goto out_free; 848 849 if (ret > 0 && metadata && key.type == BTRFS_METADATA_ITEM_KEY) { 850 if (path->slots[0]) { 851 path->slots[0]--; 852 btrfs_item_key_to_cpu(path->nodes[0], &key, 853 path->slots[0]); 854 if (key.objectid == bytenr && 855 key.type == BTRFS_EXTENT_ITEM_KEY && 856 key.offset == fs_info->nodesize) 857 ret = 0; 858 } 859 } 860 861 if (ret == 0) { 862 leaf = path->nodes[0]; 863 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 864 if (item_size >= sizeof(*ei)) { 865 ei = btrfs_item_ptr(leaf, path->slots[0], 866 struct btrfs_extent_item); 867 num_refs = btrfs_extent_refs(leaf, ei); 868 extent_flags = btrfs_extent_flags(leaf, ei); 869 } else { 870 ret = -EINVAL; > 871 btrfs_print_v0_err(fs_info); 872 if (trans) 873 btrfs_abort_transaction(trans, ret); 874 else 875 btrfs_handle_fs_error(fs_info, ret, NULL); 876 877 goto out_free; 878 } 879 880 BUG_ON(num_refs == 0); 881 } else { 882 num_refs = 0; 883 extent_flags = 0; 884 ret = 0; 885 } 886 887 if (!trans) 888 goto out; 889 890 delayed_refs = &trans->transaction->delayed_refs; 891 spin_lock(&delayed_refs->lock); 892 head = btrfs_find_delayed_ref_head(delayed_refs, bytenr); 893 if (head) { 894 if (!mutex_trylock(&head->mutex)) { 895 refcount_inc(&head->refs); 896 spin_unlock(&delayed_refs->lock); 897 898 btrfs_release_path(path); 899 900 /* 901 * Mutex was contended, block until it's released and try 902 * again 903 */ 904 mutex_lock(&head->mutex); 905 mutex_unlock(&head->mutex); 906 btrfs_put_delayed_ref_head(head); 907 goto search_again; 908 } 909 spin_lock(&head->lock); 910 if (head->extent_op && head->extent_op->update_flags) 911 extent_flags |= head->extent_op->flags_to_set; 912 else 913 BUG_ON(num_refs == 0); 914 915 num_refs += head->ref_mod; 916 spin_unlock(&head->lock); 917 mutex_unlock(&head->mutex); 918 } 919 spin_unlock(&delayed_refs->lock); 920 out: 921 WARN_ON(num_refs == 0); 922 if (refs) 923 *refs = num_refs; 924 if (flags) 925 *flags = extent_flags; 926 out_free: 927 btrfs_free_path(path); 928 return ret; 929 } 930 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Wed, Jun 27, 2018 at 12:05:39AM +0800, kbuild test robot wrote: > Hi Nikolay, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on next-20180626] > [cannot apply to btrfs/next v4.18-rc2 v4.18-rc1 v4.17 v4.18-rc2] > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] > > url: https://github.com/0day-ci/linux/commits/Nikolay-Borisov/btrfs-Add-graceful-handling-of-V0-extents/20180626-231445 > config: x86_64-randconfig-x015-201825 (attached as .config) > compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 > reproduce: > # save the attached .config to linux build tree > make ARCH=x86_64 > > All errors (new ones prefixed by >>): > > fs//btrfs/extent-tree.c: In function 'btrfs_lookup_extent_info': > >> fs//btrfs/extent-tree.c:871:4: error: implicit declaration of function 'btrfs_print_v0_err'; did you mean 'btrfs_print_tree'? [-Werror=implicit-function-declaration] > btrfs_print_v0_err(fs_info); > ^~~~~~~~~~~~~~~~~~ Fixed by using trans->fs_info in the original patch so the followup that removes 'fs_info' does not break compilation. Updated for-next branch pushed. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Nikolay, Thank you for the patch! Yet something to improve: [auto build test ERROR on next-20180626] [cannot apply to btrfs/next v4.18-rc2 v4.18-rc1 v4.17 v4.18-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Nikolay-Borisov/btrfs-Add-graceful-handling-of-V0-extents/20180626-231445 config: i386-randconfig-s1-201825 (attached as .config) compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): fs/btrfs/extent-tree.c: In function 'btrfs_lookup_extent_info': >> fs/btrfs/extent-tree.c:871:4: error: implicit declaration of function 'btrfs_print_v0_err' [-Werror=implicit-function-declaration] btrfs_print_v0_err(fs_info); ^~~~~~~~~~~~~~~~~~ fs/btrfs/extent-tree.c: In function 'remove_extent_data_ref': >> fs/btrfs/extent-tree.c:1308:22: error: 'fs_info' undeclared (first use in this function) btrfs_print_v0_err(fs_info); ^~~~~~~ fs/btrfs/extent-tree.c:1308:22: note: each undeclared identifier is reported only once for each function it appears in cc1: some warnings being treated as errors -- fs/btrfs/print-tree.c: In function 'print_extent_item': >> fs/btrfs/print-tree.c:56:3: error: implicit declaration of function 'btrfs_print_v0_err' [-Werror=implicit-function-declaration] btrfs_print_v0_err(eb->fs_info); ^~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors -- fs/btrfs/relocation.c: In function 'find_inline_backref': >> fs/btrfs/relocation.c:602:3: error: implicit declaration of function 'btrfs_print_v0_err' [-Werror=implicit-function-declaration] btrfs_print_v0_err(leaf->fs_info); ^~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +/btrfs_print_v0_err +871 fs/btrfs/extent-tree.c 794 795 /* 796 * helper function to lookup reference count and flags of a tree block. 797 * 798 * the head node for delayed ref is used to store the sum of all the 799 * reference count modifications queued up in the rbtree. the head 800 * node may also store the extent flags to set. This way you can check 801 * to see what the reference count and extent flags would be if all of 802 * the delayed refs are not processed. 803 */ 804 int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, 805 struct btrfs_fs_info *fs_info, u64 bytenr, 806 u64 offset, int metadata, u64 *refs, u64 *flags) 807 { 808 struct btrfs_delayed_ref_head *head; 809 struct btrfs_delayed_ref_root *delayed_refs; 810 struct btrfs_path *path; 811 struct btrfs_extent_item *ei; 812 struct extent_buffer *leaf; 813 struct btrfs_key key; 814 u32 item_size; 815 u64 num_refs; 816 u64 extent_flags; 817 int ret; 818 819 /* 820 * If we don't have skinny metadata, don't bother doing anything 821 * different 822 */ 823 if (metadata && !btrfs_fs_incompat(fs_info, SKINNY_METADATA)) { 824 offset = fs_info->nodesize; 825 metadata = 0; 826 } 827 828 path = btrfs_alloc_path(); 829 if (!path) 830 return -ENOMEM; 831 832 if (!trans) { 833 path->skip_locking = 1; 834 path->search_commit_root = 1; 835 } 836 837 search_again: 838 key.objectid = bytenr; 839 key.offset = offset; 840 if (metadata) 841 key.type = BTRFS_METADATA_ITEM_KEY; 842 else 843 key.type = BTRFS_EXTENT_ITEM_KEY; 844 845 ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); 846 if (ret < 0) 847 goto out_free; 848 849 if (ret > 0 && metadata && key.type == BTRFS_METADATA_ITEM_KEY) { 850 if (path->slots[0]) { 851 path->slots[0]--; 852 btrfs_item_key_to_cpu(path->nodes[0], &key, 853 path->slots[0]); 854 if (key.objectid == bytenr && 855 key.type == BTRFS_EXTENT_ITEM_KEY && 856 key.offset == fs_info->nodesize) 857 ret = 0; 858 } 859 } 860 861 if (ret == 0) { 862 leaf = path->nodes[0]; 863 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 864 if (item_size >= sizeof(*ei)) { 865 ei = btrfs_item_ptr(leaf, path->slots[0], 866 struct btrfs_extent_item); 867 num_refs = btrfs_extent_refs(leaf, ei); 868 extent_flags = btrfs_extent_flags(leaf, ei); 869 } else { 870 ret = -EINVAL; > 871 btrfs_print_v0_err(fs_info); 872 if (trans) 873 btrfs_abort_transaction(trans, ret); 874 else 875 btrfs_handle_fs_error(fs_info, ret, NULL); 876 877 goto out_free; 878 } 879 880 BUG_ON(num_refs == 0); 881 } else { 882 num_refs = 0; 883 extent_flags = 0; 884 ret = 0; 885 } 886 887 if (!trans) 888 goto out; 889 890 delayed_refs = &trans->transaction->delayed_refs; 891 spin_lock(&delayed_refs->lock); 892 head = btrfs_find_delayed_ref_head(delayed_refs, bytenr); 893 if (head) { 894 if (!mutex_trylock(&head->mutex)) { 895 refcount_inc(&head->refs); 896 spin_unlock(&delayed_refs->lock); 897 898 btrfs_release_path(path); 899 900 /* 901 * Mutex was contended, block until it's released and try 902 * again 903 */ 904 mutex_lock(&head->mutex); 905 mutex_unlock(&head->mutex); 906 btrfs_put_delayed_ref_head(head); 907 goto search_again; 908 } 909 spin_lock(&head->lock); 910 if (head->extent_op && head->extent_op->update_flags) 911 extent_flags |= head->extent_op->flags_to_set; 912 else 913 BUG_ON(num_refs == 0); 914 915 num_refs += head->ref_mod; 916 spin_unlock(&head->lock); 917 mutex_unlock(&head->mutex); 918 } 919 spin_unlock(&delayed_refs->lock); 920 out: 921 WARN_ON(num_refs == 0); 922 if (refs) 923 *refs = num_refs; 924 if (flags) 925 *flags = extent_flags; 926 out_free: 927 btrfs_free_path(path); 928 return ret; 929 } 930 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index bc52bf7ac572..629ae1977d2c 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3457,6 +3457,13 @@ static inline void assfail(char *expr, char *file, int line) BUG(); } +__cold +static inline void btrfs_print_v0_err(struct btrfs_fs_info *fs_info) +{ + btrfs_err(fs_info, + "Unsupported V0 extent filesystem detected. Aborting... Please re-create your filesystem with a newer kernel"); +} + #define ASSERT(expr) \ (likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) #else diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4129831523a2..dd3ef8699b67 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -870,8 +870,16 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, num_refs = btrfs_extent_refs(leaf, ei); extent_flags = btrfs_extent_flags(leaf, ei); } else { - BUG(); + ret = -EINVAL; + btrfs_print_v0_err(fs_info); + if (trans) + btrfs_abort_transaction(trans, ret); + else + btrfs_handle_fs_error(fs_info, ret, NULL); + + goto out_free; } + BUG_ON(num_refs == 0); } else { num_refs = 0; @@ -1302,6 +1310,10 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans, ref2 = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_shared_data_ref); num_refs = btrfs_shared_data_ref_count(leaf, ref2); + } else if (key.type == BTRFS_EXTENT_REF_V0_KEY) { + btrfs_print_v0_err(fs_info); + btrfs_abort_transaction(trans, -EINVAL); + return -EINVAL; } else { BUG(); } @@ -1334,6 +1346,8 @@ static noinline u32 extent_data_ref_count(struct btrfs_path *path, leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); + + BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY); if (iref) { /* * If type is invalid, we should have bailed out earlier than @@ -1549,7 +1563,12 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); - BUG_ON(item_size < sizeof(*ei)); + if (item_size < sizeof(*ei)) { + err = -EINVAL; + btrfs_print_v0_err(fs_info); + btrfs_abort_transaction(trans, err); + goto out; + } ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); flags = btrfs_extent_flags(leaf, ei); @@ -2282,7 +2301,14 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); - BUG_ON(item_size < sizeof(*ei)); + + if (item_size < sizeof(*ei)) { + err = -EINVAL; + btrfs_print_v0_err(fs_info); + btrfs_abort_transaction(trans, err); + goto out; + } + ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); __run_delayed_extent_op(extent_op, leaf, ei); @@ -6815,7 +6841,12 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, extent_slot); - BUG_ON(item_size < sizeof(*ei)); + if (item_size < sizeof(*ei)) { + ret = -EINVAL; + btrfs_print_v0_err(info); + btrfs_abort_transaction(trans, ret); + goto out; + } ei = btrfs_item_ptr(leaf, extent_slot, struct btrfs_extent_item); if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID && diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index b03040b84fe9..772560eecfa6 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -52,8 +52,10 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type) u64 offset; int ref_index = 0; - if (item_size < sizeof(*ei)) - BUG(); + if (item_size < sizeof(*ei)) { + btrfs_print_v0_err(eb->fs_info); + btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL); + } ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item); flags = btrfs_extent_flags(eb, ei); @@ -256,7 +258,8 @@ void btrfs_print_leaf(struct extent_buffer *l) btrfs_file_extent_ram_bytes(l, fi)); break; case BTRFS_EXTENT_REF_V0_KEY: - BUG(); + btrfs_print_v0_err(fs_info); + btrfs_handle_fs_error(fs_info, -EINVAL, NULL); break; case BTRFS_BLOCK_GROUP_ITEM_KEY: bi = btrfs_item_ptr(l, i, diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 52c1e3e6802d..6fcd88c856d3 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -598,6 +598,11 @@ int find_inline_backref(struct extent_buffer *leaf, int slot, btrfs_item_key_to_cpu(leaf, &key, slot); item_size = btrfs_item_size_nr(leaf, slot); + if (item_size < sizeof(*ei)) { + btrfs_print_v0_err(leaf->fs_info); + btrfs_handle_fs_error(leaf->fs_info, -EINVAL, NULL); + return 1; + } ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item); WARN_ON(!(btrfs_extent_flags(leaf, ei) & BTRFS_EXTENT_FLAG_TREE_BLOCK)); @@ -782,8 +787,13 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, goto next; } - ASSERT(key.type != BTRFS_EXTENT_REF_V0_KEY); - if (key.type == BTRFS_SHARED_BLOCK_REF_KEY) { + if (key.type == BTRFS_EXTENT_REF_V0_KEY) { + err = -EINVAL; + btrfs_print_v0_err(rc->extent_root->fs_info); + btrfs_handle_fs_error(rc->extent_root->fs_info, err, + NULL); + goto out; + } else if (key.type == BTRFS_SHARED_BLOCK_REF_KEY) { if (key.objectid == key.offset) { /* * only root blocks of reloc trees use @@ -3315,6 +3325,10 @@ static int add_tree_block(struct reloc_control *rc, level = (int)extent_key->offset; } generation = btrfs_extent_generation(eb, ei); + } else if (item_size == sizeof(struct btrfs_extent_item_v0)) { + btrfs_print_v0_err(eb->fs_info); + btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL); + return -EINVAL; } else { BUG(); } @@ -3720,8 +3734,11 @@ int add_data_references(struct reloc_control *rc, if (key.objectid != extent_key->objectid) break; - BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY); - if (key.type == BTRFS_SHARED_DATA_REF_KEY) { + if (key.type == BTRFS_EXTENT_REF_V0_KEY) { + btrfs_print_v0_err(eb->fs_info); + btrfs_handle_fs_error(eb->fs_info, -EINVAL, NULL); + ret = -EINVAL; + } else if (key.type == BTRFS_SHARED_DATA_REF_KEY) { ret = __add_tree_block(rc, key.offset, blocksize, blocks); } else if (key.type == BTRFS_EXTENT_DATA_REF_KEY) { @@ -3967,7 +3984,11 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) flags = btrfs_extent_flags(path->nodes[0], ei); ret = check_extent_flags(flags); BUG_ON(ret); - + } else if (item_size == sizeof(struct btrfs_extent_item_v0)) { + err = -EINVAL; + btrfs_print_v0_err(trans->fs_info); + btrfs_abort_transaction(trans, err); + break; } else { BUG(); }
Following the removal of the v0 handling code let's be courteous and print an error message when such extents are handled. In the cases where we have a transaction just abort it, otherwise just call btrfs_handle_fs_error. Both cases result in the FS being re-mounted RO. Signed-off-by: Nikolay Borisov <nborisov@suse.com> --- V2: * Replaced open-coded error printing with a helper function for consistency. fs/btrfs/ctree.h | 7 +++++++ fs/btrfs/extent-tree.c | 39 +++++++++++++++++++++++++++++++++++---- fs/btrfs/print-tree.c | 9 ++++++--- fs/btrfs/relocation.c | 31 ++++++++++++++++++++++++++----- 4 files changed, 74 insertions(+), 12 deletions(-)