git: fa7217a71232 - stable/13 - Add vn_path_to_global_path_hardlink
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 06 Jan 2023 09:46:32 UTC
The branch stable/13 has been updated by dfr:
URL: https://cgit.FreeBSD.org/src/commit/?id=fa7217a7123209366eb82c09a198ebdd1f0b9cc4
commit fa7217a7123209366eb82c09a198ebdd1f0b9cc4
Author: Doug Rabson <dfr@FreeBSD.org>
AuthorDate: 2022-12-02 14:09:31 +0000
Commit: Doug Rabson <dfr@FreeBSD.org>
CommitDate: 2023-01-06 07:57:57 +0000
Add vn_path_to_global_path_hardlink
This is similar to vn_path_to_global_path but allows for regular files
which may not be present in the cache.
Reviewed by: mjg, kib
Tested by: pho
(cherry picked from commit 78d35459a2586da024ac18e8768b44893c7184e7)
---
sys/kern/vfs_cache.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++--
sys/sys/vnode.h | 3 +++
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index c358de15f779..b422b30da3e2 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -3797,6 +3797,71 @@ out:
return (error);
}
+/*
+ * This is similar to vn_path_to_global_path but allows for regular
+ * files which may not be present in the cache.
+ *
+ * Requires a locked, referenced vnode.
+ * Vnode is re-locked on success or ENODEV, otherwise unlocked.
+ */
+int
+vn_path_to_global_path_hardlink(struct thread *td, struct vnode *vp,
+ struct vnode *dvp, char *path, u_int pathlen, const char *leaf_name,
+ size_t leaf_length)
+{
+ struct nameidata nd;
+ struct vnode *vp1;
+ char *rpath, *fbuf;
+ size_t len;
+ int error;
+
+ ASSERT_VOP_ELOCKED(vp, __func__);
+
+ /*
+ * Construct global filesystem path from dvp, vp and leaf
+ * name.
+ */
+ VOP_UNLOCK(vp);
+ error = vn_fullpath_hardlink(vp, dvp, leaf_name, leaf_length,
+ &rpath, &fbuf, &len);
+
+ if (error != 0) {
+ vrele(vp);
+ goto out;
+ }
+
+ if (strlen(rpath) >= pathlen) {
+ vrele(vp);
+ error = ENAMETOOLONG;
+ goto out;
+ }
+
+ /*
+ * Re-lookup the vnode by path to detect a possible rename.
+ * As a side effect, the vnode is relocked.
+ * If vnode was renamed, return ENOENT.
+ */
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_SYSSPACE, path, td);
+ error = namei(&nd);
+ if (error != 0) {
+ vrele(vp);
+ goto out;
+ }
+ NDFREE_PNBUF(&nd);
+ vp1 = nd.ni_vp;
+ vrele(vp);
+ if (vp1 == vp)
+ strcpy(path, rpath);
+ else {
+ vput(vp1);
+ error = ENOENT;
+ }
+
+out:
+ free(fbuf, M_TEMP);
+ return (error);
+}
+
#ifdef DDB
static void
db_print_vpath(struct vnode *vp)
@@ -5349,7 +5414,7 @@ cache_fplookup_climb_mount(struct cache_fpl *fpl)
vp = fpl->tvp;
vp_seqc = fpl->tvp_seqc;
- VNPASS(vp->v_type == VDIR || vp->v_type == VBAD, vp);
+ VNPASS(vp->v_type == VDIR || vp->v_type == VREG || vp->v_type == VBAD, vp);
mp = atomic_load_ptr(&vp->v_mountedhere);
if (__predict_false(mp == NULL)) {
return (0);
@@ -5406,7 +5471,7 @@ cache_fplookup_cross_mount(struct cache_fpl *fpl)
vp = fpl->tvp;
vp_seqc = fpl->tvp_seqc;
- VNPASS(vp->v_type == VDIR || vp->v_type == VBAD, vp);
+ VNPASS(vp->v_type == VDIR || vp->v_type == VREG || vp->v_type == VBAD, vp);
mp = atomic_load_ptr(&vp->v_mountedhere);
if (__predict_false(mp == NULL)) {
return (0);
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 529c69ccf7c7..2011f429141c 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -704,6 +704,9 @@ struct vnode *
int vn_commname(struct vnode *vn, char *buf, u_int buflen);
int vn_path_to_global_path(struct thread *td, struct vnode *vp,
char *path, u_int pathlen);
+int vn_path_to_global_path_hardlink(struct thread *td, struct vnode *vp,
+ struct vnode *dvp, char *path, u_int pathlen, const char *leaf_name,
+ size_t leaf_length);
int vaccess(enum vtype type, mode_t file_mode, uid_t file_uid,
gid_t file_gid, accmode_t accmode, struct ucred *cred);
int vaccess_vexec_smr(mode_t file_mode, uid_t file_uid, gid_t file_gid,