summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McDonald <danmcd@mnx.io>2022-05-02 20:56:31 -0400
committerDan McDonald <danmcd@mnx.io>2022-05-02 20:56:31 -0400
commite9f6569a02449ea535efa06fb1c4f3b93bb85a35 (patch)
treee958255ac4fbe2d05fdff88094d02116d0d157b7
parent6b1923e3b8d5b0582fb17f95b315aa664d0c45a5 (diff)
parentfad76a8aa8247c36be908a3a4de1674f5b444484 (diff)
downloadillumos-joyent-e9f6569a02449ea535efa06fb1c4f3b93bb85a35.tar.gz
[illumos-gate merge]
commit fad76a8aa8247c36be908a3a4de1674f5b444484 14646 vnode_valid_pn() always fails for symlinks Conflicts: usr/src/uts/common/fs/lookup.c
-rw-r--r--usr/src/uts/common/fs/lookup.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/usr/src/uts/common/fs/lookup.c b/usr/src/uts/common/fs/lookup.c
index 32a3d19708..71e2aeb48b 100644
--- a/usr/src/uts/common/fs/lookup.c
+++ b/usr/src/uts/common/fs/lookup.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2016 Joyent, Inc.
*/
@@ -436,7 +435,7 @@ checkforroot:
* Traverse mount points.
* XXX why don't we need to hold a read lock here (call vn_vfsrlock)?
* What prevents a concurrent update to v_vfsmountedhere?
- * Possible answer: if mounting, we might not see the mount
+ * Possible answer: if mounting, we might not see the mount
* if it is concurrently coming into existence, but that's
* really not much different from the thread running a bit slower.
* If unmounting, we may get into traverse() when we shouldn't,
@@ -1055,7 +1054,26 @@ vnode_valid_pn(vnode_t *vp, vnode_t *vrootp, pathname_t *pn, pathname_t *rpn,
VN_HOLD(vrootp);
if (vrootp != rootdir)
VN_HOLD(vrootp);
- if (lookuppnvp(pn, rpn, FOLLOW | flags, NULL, &compvp, vrootp, vrootp,
+
+ /*
+ * The FOLLOW flag only determines, if the final path component
+ * is a symlink, whether lookuppnvp will return the symlink, or its
+ * target.
+ *
+ * If the vp is a VLNK, then passing the FOLLOW flag will cause
+ * lookuppnvp to return the vnode of its target, instead of itself, and
+ * so vn_compare will fail. Therefore, we do not pass FOLLOW when our vp
+ * is a symlink.
+ *
+ * If the vp is not a VLNK, then we pass FOLLOW on the off-chance that
+ * the stored v_path ends at a symlink, instead of the symlink's target.
+ */
+ if (vp->v_type != VLNK)
+ flags |= FOLLOW;
+ else
+ flags &= ~FOLLOW;
+
+ if (lookuppnvp(pn, rpn, flags, NULL, &compvp, vrootp, vrootp,
cr) == 0) {
/*
* Check to see if the returned vnode is the same as the one we