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.