Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Move a big wodge of symlink-following code from nfsd to inside
details: https://anonhg.NetBSD.org/src/rev/c6d59022fb64
branches: trunk
changeset: 747693:c6d59022fb64
user: dholland <dholland%NetBSD.org@localhost>
date: Sun Sep 27 17:23:53 2009 +0000
description:
Move a big wodge of symlink-following code from nfsd to inside
lookup_for_nfsd(). This code is, or at least should be, the same as
the regular symlink-following code plus an extra flag nfsd needs.
The two lots of code can/will be merged in the future.
diffstat:
share/man/man9/namei.9 | 20 ++++--
sys/kern/vfs_lookup.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++-
sys/nfs/nfs_srvsubs.c | 109 ++------------------------------------
sys/sys/namei.src | 4 +-
4 files changed, 155 insertions(+), 114 deletions(-)
diffs (truncated from 379 to 300 lines):
diff -r efa4a6175d56 -r c6d59022fb64 share/man/man9/namei.9
--- a/share/man/man9/namei.9 Sun Sep 27 17:21:22 2009 +0000
+++ b/share/man/man9/namei.9 Sun Sep 27 17:23:53 2009 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: namei.9,v 1.22 2009/09/27 17:19:07 dholland Exp $
+.\" $NetBSD: namei.9,v 1.23 2009/09/27 17:23:53 dholland Exp $
.\"
.\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -46,7 +46,8 @@
.Ft int
.Fn namei "struct nameidata *ndp"
.Ft int
-.Fn lookup_for_nfsd "struct nameidata *ndp"
+.Fn lookup_for_nfsd "struct nameidata *ndp" "struct vnode *startdir" \
+"int neverfollow"
.Ft int
.Fn lookup_for_nfsd_index "struct nameidata *ndp"
.Ft int
@@ -288,11 +289,19 @@
is comparable to the historic
.Fn lookup
but this code is slated for refactoring.
-.It Fn lookup_for_nfsd "ndp"
+.It Fn lookup_for_nfsd "ndp" "startdir" "neverfollow"
This is a private entry point into
.Nm
used by the NFS server code.
-Its semantics are similar to the historic
+It looks up a path starting from
+.Fa startdir .
+If
+.Fa neverfollow
+is set,
+.Em any
+symbolic link (not just at the end of the path) will cause an error.
+Otherwise, it follows symlinks normally.
+Its semantics are similar to a symlink-following loop around the historic
.Fn lookup
function described above.
It should not be used by new code.
@@ -304,9 +313,6 @@
.Fn lookup
function described above.
It should not be used by new code.
-(For now it differs from the preceding private entry point in that it
-has a different call site with a different context and different
-custom initialization of what ought to be private namei state.)
.It Fn relookup "dvp" "vpp" "cnp"
Reacquire a path name component is a directory.
This is a quicker way to lookup a pathname component when the parent
diff -r efa4a6175d56 -r c6d59022fb64 sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c Sun Sep 27 17:21:22 2009 +0000
+++ b/sys/kern/vfs_lookup.c Sun Sep 27 17:23:53 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_lookup.c,v 1.119 2009/09/27 17:19:07 dholland Exp $ */
+/* $NetBSD: vfs_lookup.c,v 1.120 2009/09/27 17:23:54 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.119 2009/09/27 17:19:07 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.120 2009/09/27 17:23:54 dholland Exp $");
#include "opt_magiclinks.h"
@@ -1158,14 +1158,144 @@
*/
int
-lookup_for_nfsd(struct nameidata *ndp)
+lookup_for_nfsd(struct nameidata *ndp, struct vnode *dp, int neverfollow)
{
struct namei_state state;
int error;
+ struct iovec aiov;
+ struct uio auio;
+ int linklen;
+ char *cp;
+
/* For now at least we don't have to frob the state */
namei_init(&state, ndp);
+
+ /*
+ * BEGIN wodge of code from nfsd
+ */
+
+ VREF(dp);
+ vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
+
+ for (;;) {
+
+ state.cnp->cn_nameptr = state.cnp->cn_pnbuf;
+ state.ndp->ni_startdir = dp;
+
+ /*
+ * END wodge of code from nfsd
+ */
+
error = do_lookup(&state);
+ if (error) {
+ /* BEGIN from nfsd */
+ if (ndp->ni_dvp) {
+ vput(ndp->ni_dvp);
+ }
+ PNBUF_PUT(state.cnp->cn_pnbuf);
+ /* END from nfsd */
+ namei_cleanup(&state);
+ return error;
+ }
+
+ /*
+ * BEGIN wodge of code from nfsd
+ */
+
+ /*
+ * Check for encountering a symbolic link
+ */
+ if ((state.cnp->cn_flags & ISSYMLINK) == 0) {
+ if ((state.cnp->cn_flags & LOCKPARENT) == 0 && state.ndp->ni_dvp) {
+ if (state.ndp->ni_dvp == state.ndp->ni_vp) {
+ vrele(state.ndp->ni_dvp);
+ } else {
+ vput(state.ndp->ni_dvp);
+ }
+ }
+ if (state.cnp->cn_flags & (SAVENAME | SAVESTART)) {
+ state.cnp->cn_flags |= HASBUF;
+ } else {
+ PNBUF_PUT(state.cnp->cn_pnbuf);
+#if defined(DIAGNOSTIC)
+ state.cnp->cn_pnbuf = NULL;
+#endif /* defined(DIAGNOSTIC) */
+ }
+ return (0);
+ } else {
+ if (neverfollow) {
+ error = EINVAL;
+ goto out;
+ }
+ if (state.ndp->ni_loopcnt++ >= MAXSYMLINKS) {
+ error = ELOOP;
+ goto out;
+ }
+ if (state.ndp->ni_vp->v_mount->mnt_flag & MNT_SYMPERM) {
+ error = VOP_ACCESS(ndp->ni_vp, VEXEC, state.cnp->cn_cred);
+ if (error != 0)
+ goto out;
+ }
+ if (state.ndp->ni_pathlen > 1)
+ cp = PNBUF_GET();
+ else
+ cp = state.cnp->cn_pnbuf;
+ aiov.iov_base = cp;
+ aiov.iov_len = MAXPATHLEN;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ auio.uio_rw = UIO_READ;
+ auio.uio_resid = MAXPATHLEN;
+ UIO_SETUP_SYSSPACE(&auio);
+ error = VOP_READLINK(ndp->ni_vp, &auio, state.cnp->cn_cred);
+ if (error) {
+badlink:
+ if (ndp->ni_pathlen > 1)
+ PNBUF_PUT(cp);
+ goto out;
+ }
+ linklen = MAXPATHLEN - auio.uio_resid;
+ if (linklen == 0) {
+ error = ENOENT;
+ goto badlink;
+ }
+ if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
+ error = ENAMETOOLONG;
+ goto badlink;
+ }
+ if (ndp->ni_pathlen > 1) {
+ memcpy(cp + linklen, ndp->ni_next, ndp->ni_pathlen);
+ PNBUF_PUT(state.cnp->cn_pnbuf);
+ state.cnp->cn_pnbuf = cp;
+ } else
+ state.cnp->cn_pnbuf[linklen] = '\0';
+ state.ndp->ni_pathlen += linklen;
+ vput(state.ndp->ni_vp);
+ dp = state.ndp->ni_dvp;
+
+ /*
+ * Check if root directory should replace current directory.
+ */
+ if (state.cnp->cn_pnbuf[0] == '/') {
+ vput(dp);
+ dp = ndp->ni_rootdir;
+ VREF(dp);
+ vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
+ }
+ }
+
+ }
+ out:
+ vput(state.ndp->ni_vp);
+ vput(state.ndp->ni_dvp);
+ state.ndp->ni_vp = NULL;
+ PNBUF_PUT(state.cnp->cn_pnbuf);
+
+ /*
+ * END wodge of code from nfsd
+ */
namei_cleanup(&state);
return error;
diff -r efa4a6175d56 -r c6d59022fb64 sys/nfs/nfs_srvsubs.c
--- a/sys/nfs/nfs_srvsubs.c Sun Sep 27 17:21:22 2009 +0000
+++ b/sys/nfs/nfs_srvsubs.c Sun Sep 27 17:23:53 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_srvsubs.c,v 1.4 2009/09/27 17:19:07 dholland Exp $ */
+/* $NetBSD: nfs_srvsubs.c,v 1.5 2009/09/27 17:23:54 dholland Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_srvsubs.c,v 1.4 2009/09/27 17:19:07 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_srvsubs.c,v 1.5 2009/09/27 17:23:54 dholland Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -121,10 +121,9 @@
int i, rem;
struct mbuf *md;
char *fromcp, *tocp, *cp;
- struct iovec aiov;
- struct uio auio;
struct vnode *dp;
- int error, rdonly, linklen;
+ int error, rdonly;
+ int neverfollow;
struct componentname *cnp = &ndp->ni_cnd;
*retdirp = NULL;
@@ -254,111 +253,17 @@
cnp->cn_flags |= NOCROSSMOUNT;
}
- VREF(dp);
- vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
-
- for (;;) {
- cnp->cn_nameptr = cnp->cn_pnbuf;
- ndp->ni_startdir = dp;
+ neverfollow = !pubflag;
/*
* And call lookup() to do the real work
*/
- error = lookup_for_nfsd(ndp);
+ error = lookup_for_nfsd(ndp, dp, neverfollow);
if (error) {
- if (ndp->ni_dvp) {
- vput(ndp->ni_dvp);
- }
- PNBUF_PUT(cnp->cn_pnbuf);
return (error);
}
+ return 0;
- /*
- * Check for encountering a symbolic link
- */
- if ((cnp->cn_flags & ISSYMLINK) == 0) {
- if ((cnp->cn_flags & LOCKPARENT) == 0 && ndp->ni_dvp) {
- if (ndp->ni_dvp == ndp->ni_vp) {
- vrele(ndp->ni_dvp);
- } else {
- vput(ndp->ni_dvp);
- }
- }
- if (cnp->cn_flags & (SAVENAME | SAVESTART)) {
- cnp->cn_flags |= HASBUF;
- } else {
- PNBUF_PUT(cnp->cn_pnbuf);
-#if defined(DIAGNOSTIC)
- cnp->cn_pnbuf = NULL;
-#endif /* defined(DIAGNOSTIC) */
- }
- return (0);
- } else {
- if (!pubflag) {
- error = EINVAL;
- break;
- }
- if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
- error = ELOOP;
- break;
Home |
Main Index |
Thread Index |
Old Index