Module Name: src Committed By: ad Date: Wed Apr 22 21:35:52 UTC 2020
Modified Files: src/sys/kern: vfs_cache.c vfs_lookup.c Log Message: lookup_fastforward(): handle dotdot lookups and give up less often in the union mount case. To generate a diff of this commit: cvs rdiff -u -r1.139 -r1.140 src/sys/kern/vfs_cache.c cvs rdiff -u -r1.218 -r1.219 src/sys/kern/vfs_lookup.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_cache.c diff -u src/sys/kern/vfs_cache.c:1.139 src/sys/kern/vfs_cache.c:1.140 --- src/sys/kern/vfs_cache.c:1.139 Mon Apr 13 19:23:18 2020 +++ src/sys/kern/vfs_cache.c Wed Apr 22 21:35:52 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_cache.c,v 1.139 2020/04/13 19:23:18 ad Exp $ */ +/* $NetBSD: vfs_cache.c,v 1.140 2020/04/22 21:35:52 ad Exp $ */ /*- * Copyright (c) 2008, 2019, 2020 The NetBSD Foundation, Inc. @@ -172,7 +172,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.139 2020/04/13 19:23:18 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.140 2020/04/22 21:35:52 ad Exp $"); #define __NAMECACHE_PRIVATE #ifdef _KERNEL_OPT @@ -664,10 +664,17 @@ cache_lookup_linked(struct vnode *dvp, c * before we get its lock. * * Note that the two locks can be the same if looking up a dot, for - * example: /usr/bin/. + * example: /usr/bin/. If looking up the parent (..) we can't wait + * on the lock as child -> parent is the wrong direction. */ if (*plock != &dvi->vi_nc_lock) { - rw_enter(&dvi->vi_nc_lock, RW_READER); + if (namelen == 2 && name[0] == '.' && name[1] == '.') { + if (!rw_tryenter(&dvi->vi_nc_lock, RW_READER)) { + return false; + } + } else { + rw_enter(&dvi->vi_nc_lock, RW_READER); + } if (*plock != NULL) { rw_exit(*plock); } Index: src/sys/kern/vfs_lookup.c diff -u src/sys/kern/vfs_lookup.c:1.218 src/sys/kern/vfs_lookup.c:1.219 --- src/sys/kern/vfs_lookup.c:1.218 Tue Apr 21 21:42:47 2020 +++ src/sys/kern/vfs_lookup.c Wed Apr 22 21:35:52 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lookup.c,v 1.218 2020/04/21 21:42:47 ad Exp $ */ +/* $NetBSD: vfs_lookup.c,v 1.219 2020/04/22 21:35:52 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.218 2020/04/21 21:42:47 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.219 2020/04/22 21:35:52 ad Exp $"); #ifdef _KERNEL_OPT #include "opt_magiclinks.h" @@ -1286,14 +1286,19 @@ lookup_fastforward(struct namei_state *s } /* - * Can't deal with dotdot lookups, because it means lock - * order reversal, and there are checks in lookup_once() - * that need to be made. Also check for missing mountpoints. + * Can't deal with DOTDOT lookups if NOCROSSMOUNT or the + * lookup is chrooted. */ - if ((cnp->cn_flags & ISDOTDOT) != 0 || - searchdir->v_mount == NULL) { - error = EOPNOTSUPP; - break; + if ((cnp->cn_flags & ISDOTDOT) != 0) { + if ((searchdir->v_vflag & VV_ROOT) != 0 && + (cnp->cn_flags & NOCROSSMOUNT)) { + error = EOPNOTSUPP; + break; + } + if (ndp->ni_rootdir != rootvnode) { + error = EOPNOTSUPP; + break; + } } /* @@ -1309,13 +1314,6 @@ lookup_fastforward(struct namei_state *s } } - /* Can't deal with -o union lookups. */ - if ((searchdir->v_vflag & VV_ROOT) != 0 && - (searchdir->v_mount->mnt_flag & MNT_UNION) != 0) { - error = EOPNOTSUPP; - break; - } - /* * Good, now look for it in cache. cache_lookup_linked() * will fail if there's nothing there, or if there's no @@ -1329,9 +1327,18 @@ lookup_fastforward(struct namei_state *s } KASSERT(plock != NULL && rw_lock_held(plock)); - /* Scored a hit. Negative is good too (ENOENT). */ + /* + * Scored a hit. Negative is good too (ENOENT). If there's + * a '-o union' mount here, punt and let lookup_once() deal + * with it. + */ if (foundobj == NULL) { - error = ENOENT; + if ((searchdir->v_vflag & VV_ROOT) != 0 && + (searchdir->v_mount->mnt_flag & MNT_UNION) != 0) { + error = EOPNOTSUPP; + } else { + error = ENOENT; + } break; }