On Fri, Aug 04, 2017 at 04:43:50PM -0700, Dan Williams wrote: > On Fri, Aug 4, 2017 at 4:31 PM, Dave Chinner <david@xxxxxxxxxxxxx> wrote: > > On Thu, Aug 03, 2017 at 07:28:17PM -0700, Dan Williams wrote: > >> diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > >> index fe0f8f7f4bb7..46d8eb9e19fc 100644 > >> --- a/fs/xfs/xfs_bmap_util.c > >> +++ b/fs/xfs/xfs_bmap_util.c > >> @@ -1393,6 +1393,107 @@ xfs_zero_file_space( > >> > >> } > >> > >> +/* Return 1 if hole detected, 0 if not, and < 0 if fail to determine */ > >> +STATIC int > >> +xfs_file_has_holes( > >> + struct xfs_inode *ip) > >> +{ > > > > Why do we need this function? > > > > We've just run xfs_alloc_file_space() across the entire range we > > are sealing, so we've already guaranteed that it won't have holes > > in it. > > I'm sure this is due to my ignorance of the scope of XFS_IOLOCK_EXCL > vs XFS_ILOCK_EXCL. I had assumed that since we drop and retake > XFS_ILOCK_EXCL that we need to re-validate the block map before > setting S_IOMAP_IMMUTABLE. THe ILOCK is there to protect the inode metadata when there is concurrent access through the IO/MMAP lock paths. However, if we hold the IOLOCK_EXCL and the MMAPLOCK_EXCL, then nothing can get through the IO interfaces to modify the data in the file. This is required because APIs that directly modify the extent map (e.g. fallocate, truncate, etc) have to lock out the IO path to ensure there are no IOs in flight across the range we are manipulating. Holding these locks also locks out other APIs that modify the extent map and so effectively nothing else can be accessing or modifying the extent map while a fallocate or truncate operation is in progress. Cheers, Dave. -- Dave Chinner david@xxxxxxxxxxxxx