Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Clean up. Move some more code across from nfsd's private...
details: https://anonhg.NetBSD.org/src/rev/c3eb6f6fbc20
branches: trunk
changeset: 764045:c3eb6f6fbc20
user: dholland <dholland%NetBSD.org@localhost>
date: Mon Apr 11 01:33:04 2011 +0000
description:
Clean up. Move some more code across from nfsd's private entry points.
diffstat:
sys/kern/vfs_lookup.c | 291 +++++++++++++++++++++++++++++--------------------
sys/nfs/nfs_serv.c | 7 +-
sys/nfs/nfs_srvsubs.c | 9 +-
3 files changed, 177 insertions(+), 130 deletions(-)
diffs (truncated from 491 to 300 lines):
diff -r dfa606181482 -r c3eb6f6fbc20 sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c Mon Apr 11 00:21:45 2011 +0000
+++ b/sys/kern/vfs_lookup.c Mon Apr 11 01:33:04 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_lookup.c,v 1.132 2011/03/22 15:16:23 pooka Exp $ */
+/* $NetBSD: vfs_lookup.c,v 1.133 2011/04/11 01:33:04 dholland Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.132 2011/03/22 15:16:23 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.133 2011/04/11 01:33:04 dholland Exp $");
#include "opt_magiclinks.h"
@@ -415,9 +415,6 @@
int slashes;
};
-/* XXX reorder things to make this decl unnecessary */
-static int do_lookup(struct namei_state *state, struct vnode *startdir);
-
/*
* Initialize the namei working state.
@@ -437,6 +434,21 @@
state->rdonly = 0;
state->dp = NULL;
state->slashes = 0;
+
+#ifdef DIAGNOSTIC
+ if (!state->cnp->cn_cred)
+ panic("namei: bad cred/proc");
+ if (state->cnp->cn_nameiop & (~OPMASK))
+ panic("namei: nameiop contaminated with flags");
+ if (state->cnp->cn_flags & OPMASK)
+ panic("namei: flags contaminated with nameiops");
+#endif
+
+ /*
+ * The buffer for name translation shall be the one inside the
+ * pathbuf.
+ */
+ state->ndp->ni_pnbuf = state->ndp->ni_pathbuf->pb_path;
}
/*
@@ -457,42 +469,131 @@
//////////////////////////////
/*
- * Start up namei. Early portion.
- *
- * This is divided from namei_start2 by the emul_retry: point.
+ * Get the directory context.
+ * Initializes the rootdir and erootdir state and returns a reference
+ * to the starting dir.
+ */
+static struct vnode *
+namei_getstartdir(struct namei_state *state)
+{
+ struct nameidata *ndp = state->ndp;
+ struct componentname *cnp = state->cnp;
+ struct cwdinfo *cwdi; /* pointer to cwd state */
+ struct lwp *self = curlwp; /* thread doing namei() */
+ struct vnode *rootdir, *erootdir, *curdir, *startdir;
+
+ cwdi = self->l_proc->p_cwdi;
+ rw_enter(&cwdi->cwdi_lock, RW_READER);
+
+ /* root dir */
+ if (cwdi->cwdi_rdir == NULL || (cnp->cn_flags & NOCHROOT)) {
+ rootdir = rootvnode;
+ } else {
+ rootdir = cwdi->cwdi_rdir;
+ }
+
+ /* emulation root dir, if any */
+ if ((cnp->cn_flags & TRYEMULROOT) == 0) {
+ /* if we don't want it, don't fetch it */
+ erootdir = NULL;
+ } else if (cnp->cn_flags & EMULROOTSET) {
+ /* explicitly set emulroot; "/../" doesn't override this */
+ erootdir = ndp->ni_erootdir;
+ } else if (!strncmp(ndp->ni_pnbuf, "/../", 4)) {
+ /* explicit reference to real rootdir */
+ erootdir = NULL;
+ } else {
+ /* may be null */
+ erootdir = cwdi->cwdi_edir;
+ }
+
+ /* current dir */
+ curdir = cwdi->cwdi_cdir;
+
+ if (ndp->ni_pnbuf[0] != '/') {
+ startdir = curdir;
+ erootdir = NULL;
+ } else if (cnp->cn_flags & TRYEMULROOT && erootdir != NULL) {
+ startdir = erootdir;
+ } else {
+ startdir = rootdir;
+ erootdir = NULL;
+ }
+
+ state->ndp->ni_rootdir = rootdir;
+ state->ndp->ni_erootdir = erootdir;
+
+ /*
+ * Get a reference to the start dir so we can safely unlock cwdi.
+ *
+ * XXX: should we hold references to rootdir and erootdir while
+ * we're running? What happens if a multithreaded process chroots
+ * during namei?
+ */
+ vref(startdir);
+
+ rw_exit(&cwdi->cwdi_lock);
+ return startdir;
+}
+
+/*
+ * Get the directory context for the nfsd case, in parallel to
+ * getstartdir. Initializes the rootdir and erootdir state and
+ * returns a reference to the passed-instarting dir.
+ */
+static struct vnode *
+namei_getstartdir_for_nfsd(struct namei_state *state, struct vnode *startdir)
+{
+ /* always use the real root, and never set an emulation root */
+ state->ndp->ni_rootdir = rootvnode;
+ state->ndp->ni_erootdir = NULL;
+
+ vref(startdir);
+ return startdir;
+}
+
+
+/*
+ * Ktrace the namei operation.
*/
static void
-namei_start1(struct namei_state *state)
+namei_ktrace(struct namei_state *state)
{
+ struct nameidata *ndp = state->ndp;
+ struct componentname *cnp = state->cnp;
+ struct lwp *self = curlwp; /* thread doing namei() */
+ const char *emul_path;
-#ifdef DIAGNOSTIC
- if (!state->cnp->cn_cred)
- panic("namei: bad cred/proc");
- if (state->cnp->cn_nameiop & (~OPMASK))
- panic("namei: nameiop contaminated with flags");
- if (state->cnp->cn_flags & OPMASK)
- panic("namei: flags contaminated with nameiops");
-#endif
-
- /*
- * The buffer for name translation shall be the one inside the
- * pathbuf.
- */
- state->ndp->ni_pnbuf = state->ndp->ni_pathbuf->pb_path;
+ if (ktrpoint(KTR_NAMEI)) {
+ if (ndp->ni_erootdir != NULL) {
+ /*
+ * To make any sense, the trace entry need to have the
+ * text of the emulation path prepended.
+ * Usually we can get this from the current process,
+ * but when called from emul_find_interp() it is only
+ * in the exec_package - so we get it passed in ni_next
+ * (this is a hack).
+ */
+ if (cnp->cn_flags & EMULROOTSET)
+ emul_path = ndp->ni_next;
+ else
+ emul_path = self->l_proc->p_emul->e_path;
+ ktrnamei2(emul_path, strlen(emul_path),
+ ndp->ni_pnbuf, ndp->ni_pathlen);
+ } else
+ ktrnamei(ndp->ni_pnbuf, ndp->ni_pathlen);
+ }
}
/*
* Start up namei. Copy the path, find the root dir and cwd, establish
- * the starting directory for lookup, and lock it.
+ * the starting directory for lookup, and lock it. Also calls ktrace when
+ * appropriate.
*/
static int
-namei_start2(struct namei_state *state)
+namei_start(struct namei_state *state, int isnfsd, struct vnode *forcecwd)
{
struct nameidata *ndp = state->ndp;
- struct componentname *cnp = state->cnp;
-
- struct cwdinfo *cwdi; /* pointer to cwd state */
- struct lwp *self = curlwp; /* thread doing namei() */
/* length includes null terminator (was originally from copyinstr) */
ndp->ni_pathlen = strlen(ndp->ni_pnbuf) + 1;
@@ -507,69 +608,14 @@
ndp->ni_loopcnt = 0;
- /*
- * Get root directory for the translation.
- */
- cwdi = self->l_proc->p_cwdi;
- rw_enter(&cwdi->cwdi_lock, RW_READER);
- state->namei_startdir = cwdi->cwdi_rdir;
- if (state->namei_startdir == NULL)
- state->namei_startdir = rootvnode;
- ndp->ni_rootdir = state->namei_startdir;
-
- /*
- * Check if starting from root directory or current directory.
- */
- if (ndp->ni_pnbuf[0] == '/') {
- if (cnp->cn_flags & TRYEMULROOT) {
- if (cnp->cn_flags & EMULROOTSET) {
- /* Called from (eg) emul_find_interp() */
- state->namei_startdir = ndp->ni_erootdir;
- } else {
- if (cwdi->cwdi_edir == NULL
- || (ndp->ni_pnbuf[1] == '.'
- && ndp->ni_pnbuf[2] == '.'
- && ndp->ni_pnbuf[3] == '/')) {
- ndp->ni_erootdir = NULL;
- } else {
- state->namei_startdir = cwdi->cwdi_edir;
- ndp->ni_erootdir = state->namei_startdir;
- }
- }
- } else {
- ndp->ni_erootdir = NULL;
- if (cnp->cn_flags & NOCHROOT)
- state->namei_startdir = ndp->ni_rootdir = rootvnode;
- }
+ /* Get starting directory, set up root, and ktrace. */
+ if (isnfsd) {
+ state->namei_startdir = namei_getstartdir_for_nfsd(state,
+ forcecwd);
+ /* no ktrace */
} else {
- state->namei_startdir = cwdi->cwdi_cdir;
- ndp->ni_erootdir = NULL;
- }
- vref(state->namei_startdir);
- rw_exit(&cwdi->cwdi_lock);
-
- /*
- * Ktrace it.
- */
- if (ktrpoint(KTR_NAMEI)) {
- if (ndp->ni_erootdir != NULL) {
- /*
- * To make any sense, the trace entry need to have the
- * text of the emulation path prepended.
- * Usually we can get this from the current process,
- * but when called from emul_find_interp() it is only
- * in the exec_package - so we get it passed in ni_next
- * (this is a hack).
- */
- const char *emul_path;
- if (cnp->cn_flags & EMULROOTSET)
- emul_path = ndp->ni_next;
- else
- emul_path = self->l_proc->p_emul->e_path;
- ktrnamei2(emul_path, strlen(emul_path),
- ndp->ni_pnbuf, ndp->ni_pathlen);
- } else
- ktrnamei(ndp->ni_pnbuf, ndp->ni_pathlen);
+ state->namei_startdir = namei_getstartdir(state);
+ namei_ktrace(state);
}
vn_lock(state->namei_startdir, LK_EXCLUSIVE | LK_RETRY);
@@ -578,8 +624,7 @@
}
/*
- * Undo namei_start: unlock and release the current lookup directory,
- * and discard the path buffer.
+ * Undo namei_start: unlock and release the current lookup directory.
*/
static void
namei_end(struct namei_state *state)
@@ -1053,6 +1098,8 @@
KASSERT(cnp == &ndp->ni_cnd);
+ cnp->cn_nameptr = ndp->ni_pnbuf;
+
error = lookup_start(state, startdir);
Home |
Main Index |
Thread Index |
Old Index