Page MenuHomeFreeBSD

D61315.1794320945.diff
No OneTemporary

Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None

D61315.1794320945.diff

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3332,6 +3332,8 @@
VFS_SMR_ASSERT_ENTERED();
fd = ndp->ni_dirfd;
+ MPASS(fd >= 0);
+
rights = *ndp->ni_rightsneeded;
cap_rights_set_one(&rights, CAP_LOOKUP);
@@ -3397,6 +3399,8 @@
VFS_SMR_ASSERT_ENTERED();
fd = ndp->ni_dirfd;
+ MPASS(fd >= 0);
+
fdp = curproc->p_fd;
fdt = fdp->fd_files;
if (__predict_false((u_int)fd >= fdt->fdt_nfiles))
@@ -3438,6 +3442,8 @@
int error;
uint8_t flags;
+ MPASS(ndp->ni_dirfd >= 0);
+
td = curthread;
rights = *ndp->ni_rightsneeded;
cap_rights_set_one(&rights, CAP_LOOKUP);
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -76,12 +76,15 @@
/*
* Reset ndp to its original state.
+ * namei() supplies the starting directory again on restart, so unlike
+ * NDREINIT(), NAMEI_DBG_HADSTARTDIR can be set there.
*/
#define NDRESET(ndp) do { \
- NDREINIT_DBG(ndp); \
+ NDRESET_DBG(ndp); \
ndp->ni_resflags = 0; \
ndp->ni_cnd.cn_flags &= ~NAMEI_INTERNAL_FLAGS; \
} while (0)
+
/*
* Prepare namei() to restart. Reset components to its original state and set
* ISRESTARTED flag which signals the underlying lookup code to change the root
@@ -618,6 +621,7 @@
namei(struct nameidata *ndp)
{
struct vnode *dp; /* the directory we are searching */
+ struct vnode *atvp; /* NDINIT_ATVP() starting directory */
struct componentname *cnp;
struct thread *td;
struct pwd *pwd;
@@ -635,6 +639,7 @@
cnp = &ndp->ni_cnd;
td = curthread;
+ atvp = ndp->ni_startdir;
abi_symlink = NULL;
abi_symlink_len = 0;
abi_suffix_len = 0;
@@ -709,6 +714,8 @@
* We may need to start from scratch or pick up where it left off.
*/
error = cache_fplookup(ndp, &status, &pwd);
+ /* cache_can_fplookup() rejects ni_startdir. */
+ MPASS(atvp == NULL || status == CACHE_FPL_STATUS_ABORTED);
switch (status) {
case CACHE_FPL_STATUS_UNSET:
__assert_unreachable();
@@ -751,8 +758,17 @@
false, ndp);
return (ENOENT);
}
+ /*
+ * namei_setup() and vfs_lookup() consume the reference
+ * on ni_startdir. Hold the NDINIT_ATVP() vnode so that
+ * a restart can reference it again.
+ */
+ if (atvp != NULL)
+ vhold(atvp);
error = namei_setup(ndp, &dp, &pwd);
if (error != 0) {
+ if (atvp != NULL)
+ vdrop(atvp);
namei_cleanup_cnp(cnp);
nameicap_cleanup(ndp, error);
return (error);
@@ -831,6 +847,11 @@
if (abi_restart)
was_restarted = ISRESTARTED;
ndp->ni_cnd.cn_flags |= was_restarted;
+ if (atvp != NULL) {
+ vref(atvp);
+ ndp->ni_startdir = atvp;
+ vdrop(atvp);
+ }
goto restart;
}
@@ -843,6 +864,8 @@
nameicap_cleanup(ndp, 0);
pwd_drop(pwd);
uma_zfree(namei_zone, abi_symlink);
+ if (atvp != NULL)
+ vdrop(atvp);
NDVALIDATE(ndp);
return (0);
}
@@ -916,6 +939,8 @@
nameicap_cleanup(ndp, error);
pwd_drop(pwd);
uma_zfree(namei_zone, abi_symlink);
+ if (atvp != NULL)
+ vdrop(atvp);
return (error);
}
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -216,6 +216,7 @@
/*
* Initialization of a nameidata structure.
*/
+#define AT_ATVP (-101) /* NDINIT_ATVP dirfd */
#define NDINIT(ndp, op, flags, segflg, namep) \
NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, &cap_no_rights)
#define NDINIT_AT(ndp, op, flags, segflg, namep, dirfd) \
@@ -223,7 +224,7 @@
#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rightsp) \
NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rightsp)
#define NDINIT_ATVP(ndp, op, flags, segflg, namep, vp) \
- NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, &cap_no_rights)
+ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_ATVP, vp, &cap_no_rights)
/*
* Note the constant pattern may *hide* bugs.
@@ -235,19 +236,23 @@
#define NDINIT_PREFILL(arg) memset(arg, 0xff, offsetof(struct nameidata, \
ni_dvp_seqc))
#define NDINIT_DBG(arg) { (arg)->ni_debugflags = NAMEI_DBG_INITED; }
-#define NDREINIT_DBG(arg) { \
+#define NDRESET_DBG(arg) { \
if (((arg)->ni_debugflags & NAMEI_DBG_INITED) == 0) \
panic("namei data not inited"); \
- if (((arg)->ni_debugflags & NAMEI_DBG_HADSTARTDIR) != 0) \
- panic("NDREINIT on namei data with NAMEI_DBG_HADSTARTDIR"); \
if ((arg)->ni_nctrack_mnt != NULL) \
panic("NDREINIT on namei data with leaked ni_nctrack_mnt"); \
if (!TAILQ_EMPTY(&(arg)->ni_cap_tracker)) \
panic("NDREINIT on namei data with leaked ni_cap_tracker"); \
+}
+#define NDREINIT_DBG(arg) { \
+ NDRESET_DBG(arg); \
+ if (((arg)->ni_debugflags & NAMEI_DBG_HADSTARTDIR) != 0) \
+ panic("NDREINIT on namei data with NAMEI_DBG_HADSTARTDIR"); \
(arg)->ni_debugflags = NAMEI_DBG_INITED; \
}
#else
#define NDINIT_PREFILL(arg) do { } while (0)
+#define NDRESET_DBG(arg) do { } while (0)
#define NDINIT_DBG(arg) do { } while (0)
#define NDREINIT_DBG(arg) do { } while (0)
#endif

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 10, 2:29 PM (9 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41622007
Default Alt Text
D61315.1794320945.diff (4 KB)

Event Timeline