diff options
author | Mateusz Guzik <mjg@FreeBSD.org> | 2021-01-26 22:14:49 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2021-01-31 12:02:46 +0000 |
commit | 8cbd164a179c182e8fd4a71f366bc48fe840eafb (patch) | |
tree | 7ac58adf5e1d41024cad365dd7c250e968050039 /sys/kern/vfs_cache.c | |
parent | 78c93a1721143db656e277f7827ec4d57826044c (diff) | |
download | src-8cbd164a179c182e8fd4a71f366bc48fe840eafb.tar.gz src-8cbd164a179c182e8fd4a71f366bc48fe840eafb.zip |
Diffstat (limited to 'sys/kern/vfs_cache.c')
-rw-r--r-- | sys/kern/vfs_cache.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index ff8aad14001b..b8b876657211 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -4307,11 +4307,22 @@ cache_fplookup_final_modifying(struct cache_fpl *fpl) } /* - * Check if the target is either a symlink or a mount point. - * Since we expect this to be the terminal vnode it should - * almost never be true. + * If they want the symlink itself we are fine, but if they want to + * follow it regular lookup has to be engaged. */ - if (__predict_false(tvp->v_type == VLNK || cache_fplookup_is_mp(fpl))) { + if (tvp->v_type == VLNK) { + if ((cnp->cn_flags & FOLLOW) != 0) { + vput(dvp); + vput(tvp); + return (cache_fpl_aborted(fpl)); + } + } + + /* + * Since we expect this to be the terminal vnode it should almost never + * be a mount point. + */ + if (__predict_false(cache_fplookup_is_mp(fpl))) { vput(dvp); vput(tvp); return (cache_fpl_aborted(fpl)); @@ -4614,7 +4625,15 @@ cache_fplookup_noentry(struct cache_fpl *fpl) return (cache_fpl_handled(fpl)); } - if (__predict_false(tvp->v_type == VLNK || cache_fplookup_is_mp(fpl))) { + if (tvp->v_type == VLNK) { + if ((cnp->cn_flags & FOLLOW) != 0) { + vput(dvp); + vput(tvp); + return (cache_fpl_aborted(fpl)); + } + } + + if (__predict_false(cache_fplookup_is_mp(fpl))) { vput(dvp); vput(tvp); return (cache_fpl_aborted(fpl)); |