msdosfs_rename: Use the same locking algorithm for msdosfs_rename() as used by ufs_rename(). Convert doscheckpath() to non-sleeping version.
PR: 257522
ufs_rename and msdosfs_rename: add a lock to ensure stability of the path check (ufs_checkpath and doscheckpath). From the UFS commit description:
```
ufs rename
vfs_hash_insert: ensure that the result of ufs_checkpath()predicate is stabletrue
ufs_rename() calls ufs_checkpath() to ensure that the target directory
is not a child of the source. If notAfter vnode lock, rename would create a loop.
For instance:
source->X1->X2->target
and if source moved under target,recheck v_hash. we get corrupted filesystem.
Suppose that we initially have
source->X1 ....When vfs_hash_insert() is used with a predicate, and X2->target
where X1 is not on path from root to X2. Then ufs_checkpath() accepts
the inodes,recheck it after the selected vnode is locked. but thereSince vfs_hash_lock is nothing preventing parallel rename of X2 to become
under X1dropped, vnode could be rehashed during the sleep for the vnode lock, after checkpath finishedwhich could go unnoticed there.
Ensure stability of ufs_checkpath() result by taking a per-mount sx in
ufs_rename right before ufs_checkpath() and till the end.[The addition of the excl lock assert into vfs_hash_rehash()] is not going to be committed right now]
Reviewed by: chs
```Tested by: pho
Per-commit view is available at https://kib.kiev.ua/git/gitweb.cgi?p=deviant3.git;a=shortlog;h=refs/heads/msdosfs_rename