cache: work around corner case of dvp == tvp in cache_fplookup_final_modifying

Fixes a panic where the kernel would unlock an unheld lock coming from
rename looking up "foo/." as the source.

Reported by:	markj (syzkaller)
This commit is contained in:
Mateusz Guzik 2020-12-28 21:24:53 +00:00
parent 4f4111d2c5
commit 0c09f4b0cc

View File

@ -4063,6 +4063,19 @@ cache_fplookup_final_modifying(struct cache_fpl *fpl)
return (cache_fpl_handled(fpl, 0));
}
/*
* There are very hairy corner cases concerning various flag combinations
* and locking state. In particular here we only hold one lock instead of
* two.
*
* Skip the complexity as it is of no significance for normal workloads.
*/
if (__predict_false(tvp == dvp)) {
vput(dvp);
vrele(tvp);
return (cache_fpl_aborted(fpl));
}
/*
* Check if the target is either a symlink or a mount point.
* Since we expect this to be the terminal vnode it should