This patch has three changes squashed together for the review.
- In vm_fault(), perform the check for the object size under the vnode lock, if the object has vnode type. The object lock is not enough to guarantee tht the internal fs data is consistent, so when we relock the vnode and try to page-in the faulted page, it is possible to get surprising results. I do not believe that this is an issue for the local filesystems, due to the way writes are usually structured.
- Ensure that nfsclient always calls vnode_pager_setsize() with the vnode exclusively locked. This ensures that page fault always can find the backing page if the object size check succeeded.
The main offender breaking the interface in nfsclient is nfs_loadattrcache(), which is used whenever server responded with updated attributes, which can happen on non-changing operations as well. Also, iod threads only have buffers locked (and even that is LK_KERNPROC), but they still may call nfs_loadattrcache() on RPC response.
Instead of immediately calling vnode_pager_setsize() if server response indicated changed file size, but the vnode is not exclusively locked, set a new node flag NVNSETSZSKIP. When the vnode exclusively locked, or when we can temporary upgrade the lock to exclusive, call vnode_pager_setsize(), by providing the nfsclient VOP_LOCK() implementation.
- Uncomment assert in vnode_pager_setsize() and require that all calls are done with the vnode exclusively locked.
The previous version of the patched kernel was used on NFS-booted machine and survived buildworld/buildkernel and nightly periodic run.