On 2018/08/28 14:21, Qu Wenruo wrote: > On 2018/8/24 下午4:09, Misono Tomohiro wrote: > [snip] >>> >>> BTW, what's the possibility of such problem in your test environment? >> >> It's like one in several times. >> It may depend on hardware performance? (the machine is not so fast), >> >> I also noticed following warning happens too (not always): >> > > After digging into the case, it's more complex than just my patch. > > Firstly, we lacks a lot of underflow check when modifying bytes_may_use. > So we need to do all the underflow detection for every modifier of > bytes_may_use. > > Secondly, btrfs_cross_ref_exist() check makes NODATACOW check in > __btrfs_buffered_write() unreliable. > > For the following case, at __btrfs_buffered_write() time we're pretty > sure we could do NODATACOW, but at sync time, due to cloned range, > btrfs_cross_ref_exist() would detect reflinked prealloc extent, then > falls back to CoW, and finally cause bytes_may_use underflow: > > --- > mkfs.btrfs -f $dev > $full_log > > mount $dev $mnt -o nospace_cache > btrfs quota enable $mnt > btrfs quota rescan -w $mnt > > xfs_io -f -c "falloc 0 2M" $mnt/file1 > /dev/null > xfs_io -c "pwrite -b 1M 0 1M" $mnt/file1 > /dev/null > xfs_io -c "reflink $mnt/file1 1M 4M 1M" $mnt/file1 > /dev/null > sync > ----
Thanks for the explanation. I will try to understand the relevant code. > > Even without my patch, the "pwrite" command is still CoWed, which could > be avoided. > And that's the reason my patch is causing the underflow. > > To fix this, we need more accurate btrfs_cross_ref_exist() check, not > only for @disk_bytenr but also check @len. > > Or we could try to flush the whole inode in clone_range() so we could go > through NOCOW routine before clone really happens. So as your RFC patch does not work, the option is first one? Thanks, Misono > > Thanks, > Qu >