rw<->ro remounts are not atomic, filesystem is accessible by other threads during the process. As result, its internal state is inconsistent. Just blocking writers with suspend is not enough.
Instead, set fs_ronly = 1 and clear MNT_SOFTDEP flags very early in the process of unmount, while allowing SU code that needs to modify filesystem for final sync to process by changing the test from MNT_SOFTDEP flag to um_softdep != NULL.
Also ensure that non-NULL um_softdep is fully initialized when observed, which is important for ro->rw remounts.
Nullfs changes are not strictly related but were discovered during tests. They are separate commits with its own explanations.
The split into individual commits is available at https://kib.kiev.ua/git/gitweb.cgi?p=deviant3.git;a=shortlog;h=refs/heads/ufs