I spent a fair amount of time looking over this change, and I am starting to feel very bad about it. iomap_apply() has pretty clear semantics of either return an error, or return the bytes processed, and in general these semantics work just fine. The thing that breaks this concept is the btrfs submit_bio hook, which allows the file system to keep state for each bio actually submitted. But I think you can simply keep the length internally in btrfs - use the space in iomap->private as a counter of how much was allocated, pass the iomap to the submit_io hook, and update it there, and then deal with the rest in ->iomap_end. That assumes ->iomap_end actually is the right place - can someone explain what the expected call site for __endio_write_update_ordered is? It kinda sorta looks to me like something that would want to be called after I/O completion, not after I/O submission, but maybe I misunderstand the code.