Page MenuHomeFreeBSD

D61315.1794578554.diff
No OneTemporary

Authored By
Unknown
Size
3 KB
Referenced Files
None
Subscribers
None

D61315.1794578554.diff

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
@@ -610,6 +613,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;
@@ -627,6 +631,7 @@
cnp = &ndp->ni_cnd;
td = curthread;
+ atvp = ndp->ni_startdir;
abi_symlink = NULL;
abi_symlink_len = 0;
abi_suffix_len = 0;
@@ -701,6 +706,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();
@@ -743,8 +750,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);
@@ -823,6 +839,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;
}
@@ -835,6 +856,8 @@
nameicap_cleanup(ndp, 0);
pwd_drop(pwd);
uma_zfree(namei_zone, abi_symlink);
+ if (atvp != NULL)
+ vdrop(atvp);
NDVALIDATE(ndp);
return (0);
}
@@ -908,6 +931,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
@@ -235,19 +235,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
Fri, Nov 13, 2:02 PM (9 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41657861
Default Alt Text
D61315.1794578554.diff (3 KB)

Event Timeline