On Thu, Feb 20, 2020 at 09:29:47AM -0500, Josef Bacik wrote: > In my stress testing we were still seeing some hole's with my patches to > fix missing hole extents. Turns out we do not fill in holes during hole > punch if the punch is past i_size. I incorrectly assumed this was fine, > because anybody extending would use btrfs_cont_expand, however there is > a corner that still can give us trouble. Start with an empty file and > > fallocate KEEP_SIZE 1m-2m > > We now have a 0 length file, and a hole file extent from 0-1m, and a > prealloc extent from 1m-2m. Now > > punch 1m-1.5m > > Because this is past i_size we have > > [HOLE EXTENT][ NOTHING ][PREALLOC] > [0 1m][1m 1.5m][1.5m 2m] > > with an i_size of 0. Now if we pwrite 0-1.5m we'll increas our i_size > to 1.5m, but our disk_i_size is still 0 until the ordered extent > completes. > > However if we now immediately truncate 2m on the file we'll just call > btrfs_cont_expand(inode, 1.5m, 2m), since our old i_size is 1.5m. If we > commit the transaction here and crash we'll expose the gap. > > To fix this we need to clear the file extent mapping for the range that > we punched but didn't insert a corresponding file extent for. This will > mean the truncate will only get an disk_i_size set to 1m if we crash > before the finish ordered io happens. > > I've written an xfstest to reproduce the problem and validate this fix. > > Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx> > --- > - Dave, this needs to be folded into "btrfs: use the file extent tree > infrastructure" and the changelog needs to be adjusted since I incorrectly > point out that we don't need to clear for hole punch. We definitely need to > clear for the case that we're punching past i_size as we aren't inserting hole > file extents. Ok, folded to the patch. I added the hole puching as 7) and appended this changelog so it describes the tricky corner case. Let me know if there are more updates needed. Thanks.
