Re: [PATCH btrfs/for-next] btrfs: fix fatal extent_buffer readahead vs releasepage race
From: kernel test robot
Date: Wed Jun 17 2020 - 19:26:30 EST
Hi Boris,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on kdave/for-next]
[also build test ERROR on v5.8-rc1 next-20200617]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Boris-Burkov/btrfs-fix-fatal-extent_buffer-readahead-vs-releasepage-race/20200618-002941
base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: x86_64-allyesconfig (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 487ca07fcc75d52755c9fe2ee05bcb3b6eeeec44)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>
All errors (new ones prefixed by >>, old ones prefixed by <<):
In file included from fs/btrfs/extent_io.c:19:
fs/btrfs/ctree.h:2216:8: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]
size_t __const btrfs_get_num_csums(void);
^~~~~~~~
>> fs/btrfs/extent_io.c:3934:2: error: implicit declaration of function 'check_buffer_tree_ref' [-Werror,-Wimplicit-function-declaration]
check_buffer_tree_ref(eb);
^
>> fs/btrfs/extent_io.c:5091:13: error: static declaration of 'check_buffer_tree_ref' follows non-static declaration
static void check_buffer_tree_ref(struct extent_buffer *eb)
^
fs/btrfs/extent_io.c:3934:2: note: previous implicit declaration is here
check_buffer_tree_ref(eb);
^
1 warning and 2 errors generated.
vim +/check_buffer_tree_ref +3934 fs/btrfs/extent_io.c
3915
3916 static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
3917 struct writeback_control *wbc,
3918 struct extent_page_data *epd)
3919 {
3920 u64 offset = eb->start;
3921 u32 nritems;
3922 int i, num_pages;
3923 unsigned long start, end;
3924 unsigned int write_flags = wbc_to_write_flags(wbc) | REQ_META;
3925 int ret = 0;
3926
3927 clear_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags);
3928 num_pages = num_extent_pages(eb);
3929 atomic_set(&eb->io_pages, num_pages);
3930 /*
3931 * It is possible for releasepage to clear the TREE_REF bit before we
3932 * set io_pages. See check_buffer_tree_ref for a more detailed comment.
3933 */
> 3934 check_buffer_tree_ref(eb);
3935
3936 /* set btree blocks beyond nritems with 0 to avoid stale content. */
3937 nritems = btrfs_header_nritems(eb);
3938 if (btrfs_header_level(eb) > 0) {
3939 end = btrfs_node_key_ptr_offset(nritems);
3940
3941 memzero_extent_buffer(eb, end, eb->len - end);
3942 } else {
3943 /*
3944 * leaf:
3945 * header 0 1 2 .. N ... data_N .. data_2 data_1 data_0
3946 */
3947 start = btrfs_item_nr_offset(nritems);
3948 end = BTRFS_LEAF_DATA_OFFSET + leaf_data_end(eb);
3949 memzero_extent_buffer(eb, start, end - start);
3950 }
3951
3952 for (i = 0; i < num_pages; i++) {
3953 struct page *p = eb->pages[i];
3954
3955 clear_page_dirty_for_io(p);
3956 set_page_writeback(p);
3957 ret = submit_extent_page(REQ_OP_WRITE | write_flags, wbc,
3958 p, offset, PAGE_SIZE, 0,
3959 &epd->bio,
3960 end_bio_extent_buffer_writepage,
3961 0, 0, 0, false);
3962 if (ret) {
3963 set_btree_ioerr(p);
3964 if (PageWriteback(p))
3965 end_page_writeback(p);
3966 if (atomic_sub_and_test(num_pages - i, &eb->io_pages))
3967 end_extent_buffer_writeback(eb);
3968 ret = -EIO;
3969 break;
3970 }
3971 offset += PAGE_SIZE;
3972 update_nr_written(wbc, 1);
3973 unlock_page(p);
3974 }
3975
3976 if (unlikely(ret)) {
3977 for (; i < num_pages; i++) {
3978 struct page *p = eb->pages[i];
3979 clear_page_dirty_for_io(p);
3980 unlock_page(p);
3981 }
3982 }
3983
3984 return ret;
3985 }
3986
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx
Attachment:
.config.gz
Description: application/gzip