Then, the iomap->type/flag is either IOMAP_UNWRITTEN/IOMAP_F_DIRTY or
IOMAP_MAPPED/IOMAP_F_DIRTY per iter. So the type is not consistent. However
we will set IOMAP_DIO_UNWRITTEN in dio->flags, so call xfs_dio_write_endio()
-> xfs_iomap_write_unwritten() for the complete FSB range.
Do you see a problem with this?
> > The most performant/painful way to fix this would be to make the wholeYes -- if you have a mix of written and unwritten blocks for the same
Please see this also for some more background:
https://urldefense.com/v3/__https://lore.kernel.org/linux- xfs/20240726171358.GA27612@xxxxxx/__;!!ACWV5N9M2RV99hQ! P5jeP96F8wAtRAblbm8NvRo8nlpil03vA26UMMX8qrYa4IzKecAAk7x1l1M45bBshC3Czxn1CkDXypNSAg$
chunk of physical space:
0 7
WUWUWUWU
the directio ioend function will start four separate transactions to
convert blocks 1, 3, 5, and 7 to written status. If the system crashes
midway through, they will see this afterwards:
WWWWW0W0
IOWs, although the*disk write* was completed successfully, the mapping
updates were torn, and the user program sees a torn write.
ioend completion a logged operation so that we could commit to updating
all the unwritten mappings and restart it after a crash.
The least performant of course is to write zeroes at allocation time,
like we do for fsdax.
A possible middle ground would be to detect IOMAP_ATOMIC in the
->iomap_begin method, notice that there are mixed mappings under the
proposed untorn IO, and pre-convert the unwritten blocks by writing
zeroes to disk and updating the mappings
before handing the one single
mapping back to iomap_dio_rw to stage the untorn writes bio. At least
you'd only be suffering that penalty for the (probable) corner case of
someone creating mixed mappings.