Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162702695
D58178.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D58178.diff
View Options
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -3292,32 +3292,9 @@
if ((error = namei(&nd)) != 0)
return (error);
- if (nd.ni_vp->v_type == VREG && nd.ni_dvp->v_type != VDIR &&
- (nd.ni_vp->v_vflag & VV_ROOT) != 0) {
- struct vnode *covered_vp;
-
- /*
- * This happens if vp is a file mount. The call to
- * vn_fullpath_hardlink can panic if path resolution can't be
- * handled without the directory.
- *
- * To resolve this, we find the vnode which was mounted on -
- * this should have a unique global path since we disallow
- * mounting on linked files.
- */
- error = vn_lock(nd.ni_vp, LK_SHARED);
- if (error != 0)
- goto out;
- covered_vp = nd.ni_vp->v_mount->mnt_vnodecovered;
- vref(covered_vp);
- VOP_UNLOCK(nd.ni_vp);
- error = vn_fullpath(covered_vp, &retbuf, &freebuf);
- vrele(covered_vp);
- } else {
- error = vn_fullpath_hardlink(nd.ni_vp, nd.ni_dvp,
- nd.ni_cnd.cn_nameptr, nd.ni_cnd.cn_namelen, &retbuf,
- &freebuf, &size);
- }
+ error = vn_fullpath_hardlink(nd.ni_vp, nd.ni_dvp,
+ nd.ni_cnd.cn_nameptr, nd.ni_cnd.cn_namelen, &retbuf,
+ &freebuf, &size);
if (error == 0) {
size_t len;
@@ -3330,7 +3307,6 @@
memcpy(buf, retbuf, len);
free(freebuf, M_TEMP);
}
-out:
vrele(nd.ni_vp);
vrele(nd.ni_dvp);
NDFREE_PNBUF(&nd);
@@ -3839,15 +3815,6 @@
int error;
__enum_uint8(vtype) type;
- if (*buflen < 2)
- return (EINVAL);
- if (*buflen > MAXPATHLEN)
- *buflen = MAXPATHLEN;
-
- buf = malloc(*buflen, M_TEMP, M_WAITOK);
-
- addend = 0;
-
/*
* Check for VBAD to work around the vp_crossmp bug in lookup().
*
@@ -3861,10 +3828,50 @@
* vp == vp_crossmp. Prevent the problem by checking for VBAD.
*/
type = atomic_load_8(&vp->v_type);
- if (type == VBAD) {
- error = ENOENT;
- goto out_bad;
+ if (type == VBAD)
+ return (ENOENT);
+
+ /*
+ * For file mounts dvp is vp_crossmp and unusable; resolve via the
+ * covered vnode instead, whose path is unique since file mounts
+ * require nlink == 1.
+ */
+ if (type != VDIR && (vp->v_vflag & VV_ROOT) != 0) {
+ struct vnode *covered_vp;
+ size_t len;
+
+ error = vn_lock(vp, LK_SHARED);
+ if (error != 0)
+ return (error);
+ /* Recheck under the lock, the unlocked test is racy. */
+ if ((vp->v_vflag & VV_ROOT) == 0) {
+ VOP_UNLOCK(vp);
+ return (ENOENT);
+ }
+ covered_vp = vp->v_mount->mnt_vnodecovered;
+ vref(covered_vp);
+ VOP_UNLOCK(vp);
+ error = vn_fullpath(covered_vp, retbuf, freebuf);
+ vrele(covered_vp);
+ if (error != 0)
+ return (error);
+ len = strlen(*retbuf) + 1;
+ if (len > *buflen) {
+ free(*freebuf, M_TEMP);
+ return (ENAMETOOLONG);
+ }
+ *buflen = len;
+ return (0);
}
+
+ if (*buflen < 2)
+ return (EINVAL);
+ if (*buflen > MAXPATHLEN)
+ *buflen = MAXPATHLEN;
+
+ buf = malloc(*buflen, M_TEMP, M_WAITOK);
+
+ addend = 0;
if (type != VDIR) {
addend = hrdl_name_length + 2;
if (*buflen < addend) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 16, 11:07 PM (10 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35038364
Default Alt Text
D58178.diff (2 KB)
Attached To
Mode
D58178: vfs: handle file mounts in vn_fullpath_hardlink()
Attached
Detach File
Event Timeline
Log In to Comment