Thanks Darrick and Christoph for such a quick look at this! Yes, iomap_funshare sounds more interesting. I will look into it. Wengang > On Dec 14, 2023, at 8:06 PM, Christoph Hellwig <hch@xxxxxxxxxxxxx> wrote: > > On Thu, Dec 14, 2023 at 01:35:02PM -0800, Darrick J. Wong wrote: >> I'm kinda surprised you don't just turn on alwayscow mode, use an >> iomap_funshare-like function to read in and dirty pagecache (which will >> hopefully create a new large cow fork mapping) and then flush it all >> back out with writeback. Then you don't need all this state tracking, >> kthreads management, and copying file data through the buffer cache. >> Wouldn't that be a lot simpler? > > Yes, although with a caveat or two. > > We did that for the zoned XFS project, where a 'defragmentation' like > this which we call garbage collection is an essential part of the > operation to free entire zones. I ended up initially implementing it > using iomap_file_unshare as that is page cache coherent and a nicely > available library function. But it turns out iomap_file_unshare sucks > badly as it will read the data sychronously one block at a time. > > I ended up coming up with my own duplication of iomap_file_unshare > that doesn't do it which is a bit hack by solves this problem. > I'd love to eventually merge it back into iomap_file_unshare, for > which we really need to work on our writeback iterators. > > The relevant commit or the new helper is here: > > > http://git.infradead.org/users/hch/xfs.git/commitdiff/cc4a639e3052fefb385f63a0db5dfe07db4e9d58 > > which also need a hacky readahead helper: > > http://git.infradead.org/users/hch/xfs.git/commitdiff/f6d545fc00300ddfd3e297d17e4f229ad2f15c3e > > The code using this for zoned GC is here: > > http://git.infradead.org/users/hch/xfs.git/blob/refs/heads/xfs-zoned:/fs/xfs/xfs_zone_alloc.c#l764 > > It probably would make sense to be able to also use this for a regular > fs for the online defrag use case, although the wire up would be a bit > different. >