Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/ad-namecache]: src/sys/kern - Change style of new code slightly to match...
details: https://anonhg.NetBSD.org/src/rev/00c92399898c
branches: ad-namecache
changeset: 983005:00c92399898c
user: ad <ad%NetBSD.org@localhost>
date: Thu Jan 23 12:21:01 2020 +0000
description:
- Change style of new code slightly to match rest of file.
- NFS lookup needs to cross mountpoint too.
- Update comments.
diffstat:
sys/kern/vfs_lookup.c | 143 ++++++++++++++++++++++++++++---------------------
1 files changed, 81 insertions(+), 62 deletions(-)
diffs (298 lines):
diff -r abb7818a2fbb -r 00c92399898c sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c Thu Jan 23 12:17:08 2020 +0000
+++ b/sys/kern/vfs_lookup.c Thu Jan 23 12:21:01 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_lookup.c,v 1.212.4.5 2020/01/22 12:10:46 ad Exp $ */
+/* $NetBSD: vfs_lookup.c,v 1.212.4.6 2020/01/23 12:21:01 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.212.4.5 2020/01/22 12:10:46 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.212.4.6 2020/01/23 12:21:01 ad Exp $");
#ifdef _KERNEL_OPT
#include "opt_magiclinks.h"
@@ -1113,9 +1113,9 @@
/*
* If the file system supports VOP_LOOKUP() with a shared lock, and
* we are not making any modifications (nameiop LOOKUP) or this is
- * not the last component then get a shared lock LK_SHARED. Where
- * we can't do fast-forwarded lookups (for example with layered file
- * systems) then this is the fallback for reducing lock contention.
+ * not the last component then get a shared lock. Where we can't do
+ * fast-forwarded lookups (for example with layered file systems)
+ * then this is the fallback for reducing lock contention.
*/
if ((searchdir->v_mount->mnt_iflag & IMNT_SHRLOOKUP) != 0 &&
(cnp->cn_nameiop == LOOKUP || (cnp->cn_flags & ISLASTCN) == 0)) {
@@ -1251,13 +1251,13 @@
* final vnode will have its reference count adjusted and lock taken.
*/
static int
-lookup_fastforward(struct namei_state *state, struct vnode **searchdir,
- struct vnode **foundobj)
+lookup_fastforward(struct namei_state *state, struct vnode **searchdir_ret,
+ struct vnode **foundobj_ret)
{
struct componentname *cnp = state->cnp;
struct nameidata *ndp = state->ndp;
krwlock_t *plock;
- struct vnode *vp, *origsearchdir;
+ struct vnode *foundobj, *searchdir;
int error, error2;
size_t oldpathlen;
const char *oldnameptr;
@@ -1268,10 +1268,12 @@
* case we can't get vnode references and need to roll back.
*/
plock = NULL;
- origsearchdir = *searchdir;
+ searchdir = *searchdir_ret;
oldnameptr = cnp->cn_nameptr;
oldpathlen = ndp->ni_pathlen;
for (;;) {
+ foundobj = NULL;
+
/*
* Get the next component name. There should be no slashes
* here, and we shouldn't have looped around if we were
@@ -1289,15 +1291,15 @@
* that need to be made. Also check for missing mountpoints.
*/
if ((cnp->cn_flags & ISDOTDOT) != 0 ||
- (*searchdir)->v_mount == NULL) {
+ searchdir->v_mount == NULL) {
error = EOPNOTSUPP;
break;
}
/*
* Can't deal with last component when modifying; this needs
- * the directory vnode locked and VOP_LOOKUP() called (which
- * can and does modify state, despite the name).
+ * searchdir locked and VOP_LOOKUP() called (which can and
+ * does modify state, despite the name).
*/
if ((cnp->cn_flags & ISLASTCN) != 0) {
if (cnp->cn_nameiop != LOOKUP ||
@@ -1313,16 +1315,15 @@
* ownership info for the directory, or if the user doesn't
* have permission to look up files in this directory.
*/
- if (!cache_lookup_linked(*searchdir, cnp->cn_nameptr,
- cnp->cn_namelen, &vp, &plock, cnp->cn_cred)) {
+ if (!cache_lookup_linked(searchdir, cnp->cn_nameptr,
+ cnp->cn_namelen, &foundobj, &plock, cnp->cn_cred)) {
error = EOPNOTSUPP;
break;
}
KASSERT(plock != NULL && rw_lock_held(plock));
/* Scored a hit. Negative is good too (ENOENT). */
- if (vp == NULL) {
- *foundobj = vp;
+ if (foundobj == NULL) {
error = ENOENT;
break;
}
@@ -1335,15 +1336,16 @@
* - or encountered a mount point that needs to be crossed.
* - or encountered something other than a directory.
*/
- if ((cnp->cn_flags & ISLASTCN) != 0 || vp->v_type != VDIR ||
- (vp->v_type == VDIR && vp->v_mountedhere != NULL)) {
- mutex_enter(vp->v_interlock);
- error = vcache_tryvget(vp);
+ if ((cnp->cn_flags & ISLASTCN) != 0 ||
+ foundobj->v_type != VDIR ||
+ (foundobj->v_type == VDIR &&
+ foundobj->v_mountedhere != NULL)) {
+ mutex_enter(foundobj->v_interlock);
+ error = vcache_tryvget(foundobj);
/* v_interlock now released */
- if (error == 0) {
- *foundobj = vp;
+ if (error != 0) {
+ foundobj = NULL;
}
- vp = NULL;
break;
}
@@ -1353,7 +1355,7 @@
* continue on to it.
*/
cnp->cn_nameptr = ndp->ni_next;
- *searchdir = vp;
+ searchdir = foundobj;
}
/*
@@ -1363,20 +1365,22 @@
* bit of a problem. Roll back the fastforward to the beginning and
* let lookup_once() take care of it.
*/
- if (*searchdir != origsearchdir) {
- mutex_enter((*searchdir)->v_interlock);
- error2 = vcache_tryvget(*searchdir);
+ if (searchdir != *searchdir_ret) {
+ mutex_enter(searchdir->v_interlock);
+ error2 = vcache_tryvget(searchdir);
/* v_interlock now unheld */
KASSERT(plock != NULL);
rw_exit(plock);
if (__predict_true(error2 == 0)) {
- vrele(origsearchdir);
+ /* Returning new searchdir, and maybe new foundobj. */
+ vrele(*searchdir_ret);
+ *searchdir_ret = searchdir;
} else {
- if (error == 0) {
- vrele_async(*foundobj);
- *foundobj = NULL;
+ /* Returning nothing. */
+ if (foundobj != NULL) {
+ vrele(foundobj);
+ foundobj = NULL;
}
- *searchdir = origsearchdir;
cnp->cn_nameptr = oldnameptr;
ndp->ni_pathlen = oldpathlen;
error = lookup_parsepath(state);
@@ -1386,6 +1390,8 @@
rw_exit(plock);
}
+ KASSERT(foundobj == NULL || error == 0);
+ *foundobj_ret = foundobj;
return error;
}
@@ -1657,10 +1663,12 @@
* forever. So convert it to the real root.
*/
if (searchdir != NULL) {
- if ((cnp->cn_flags & LOCKPARENT) != 0) {
- VOP_UNLOCK(searchdir);
+ if (searchdir_locked) {
+ vput(searchdir);
+ searchdir_locked = false;
+ } else {
+ vrele(searchdir);
}
- vrele(searchdir);
searchdir = NULL;
}
vrele(foundobj);
@@ -1678,10 +1686,13 @@
(searchdir == NULL ||
searchdir->v_mount != foundobj->v_mount)) {
if (searchdir) {
- if ((cnp->cn_flags & LOCKPARENT) != 0) {
- VOP_UNLOCK(searchdir);
+ if (searchdir_locked) {
+ vput(searchdir);
+ searchdir_locked = false;
+ } else {
+ vrele(searchdir);
}
- vrele(searchdir);
+ searchdir = NULL;
}
vrele(foundobj);
foundobj = NULL;
@@ -1708,10 +1719,12 @@
if (state->rdonly &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
if (searchdir) {
- if ((cnp->cn_flags & LOCKPARENT) != 0) {
- VOP_UNLOCK(searchdir);
+ if (searchdir_locked) {
+ vput(searchdir);
+ searchdir_locked = false;
+ } else {
+ vrele(searchdir);
}
- vrele(searchdir);
searchdir = NULL;
}
vrele(foundobj);
@@ -1736,7 +1749,9 @@
* that uses this combination "knows" this, so
* it can't be safely changed. Feh. XXX
*/
+ KASSERT(searchdir_locked);
VOP_UNLOCK(searchdir);
+ searchdir_locked = false;
} else if ((cnp->cn_flags & LOCKLEAF) != 0 &&
(searchdir != foundobj ||
(cnp->cn_flags & LOCKPARENT) == 0)) {
@@ -1891,6 +1906,7 @@
do_lookup_for_nfsd_index(struct namei_state *state)
{
int error = 0;
+
struct componentname *cnp = state->cnp;
struct nameidata *ndp = state->ndp;
struct vnode *startdir;
@@ -1930,32 +1946,35 @@
vref(startdir);
error = lookup_once(state, startdir, &startdir, &foundobj,
&startdir_locked);
- KASSERT(!startdir_locked);
- if (error == 0 && startdir == foundobj) {
- vrele(startdir);
- } else if (startdir != NULL) {
- if (startdir_locked) {
- vput(startdir);
- } else {
- vrele(startdir);
- }
- }
- if (error) {
- goto bad;
- }
- ndp->ni_vp = foundobj;
- if (foundobj == NULL) {
- return 0;
+ KASSERT((cnp->cn_flags & LOCKPARENT) == 0);
+ if (startdir_locked) {
+ VOP_UNLOCK(startdir);
+ startdir_locked = false;
}
- if ((cnp->cn_flags & LOCKLEAF) != 0) {
- vn_lock(foundobj, LK_EXCLUSIVE | LK_RETRY);
+ /*
+ * If the vnode we found is mounted on, then cross the mount and get
+ * the root vnode in foundobj. If this encounters an error, it will
+ * dispose of foundobj, but searchdir is untouched.
+ */
+ if (error == 0 && foundobj != NULL &&
+ foundobj->v_type == VDIR &&
+ foundobj->v_mountedhere != NULL &&
+ (cnp->cn_flags & NOCROSSMOUNT) == 0) {
+ error = lookup_crossmount(state, &startdir, &foundobj,
+ &startdir_locked);
}
- return (0);
-bad:
- ndp->ni_vp = NULL;
+ /* Now toss startdir and see if we have an error. */
+ if (startdir != NULL)
+ vrele(startdir);
+ if (error)
+ foundobj = NULL;
+ else if (foundobj != NULL && (cnp->cn_flags & LOCKLEAF) != 0)
+ vn_lock(foundobj, LK_EXCLUSIVE | LK_RETRY);
+
+ ndp->ni_vp = foundobj;
return (error);
}
Home |
Main Index |
Thread Index |
Old Index