Writes on UFS through a mapped region do not allocate disk blocks in holes immediately. The blocks are allocated when the pages are first time paged out. This breaks the algorithm in vn_bmap_seekhole() and ufs_bmap_seekdata(), because VOP_BMAP() report hole for the place which already contains a valid data. Clean pages before doing VOP_BMAP() in the affected functions. In principle, we could clean less by only requesting clean starting from the offset, but it is probably not very important. PR: 269261 Reported by: asomers
Why exactly do we need the exclusive lock? VOP_PUTPAGES doesn't formally require it.
The call chain is vm_object_page_clean()->vm_object_page_collect_flush()->vm_pageout_flush()->vm_pager_put_pages()->vnode_pager_putpages()->VOP_PUTPAGES()->vnode_pager_generic_putpages()->VOP_WRITE()
VOP_PUTPAGES() only requires locked vnode because some filesystems (zfs) only required read-locked vnode for write. But for UFS, VOP_WRITE() must be provided with exclusively-locked vp.
LGTM and it fixes the tests for UFS, though I'm not an expert in this area. The problem with fusefs has a different cause; I'll discuss on bugzilla.