Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern lookup_fastforward(): handle dotdot lookups and giv...



details:   https://anonhg.NetBSD.org/src/rev/61720949f200
branches:  trunk
changeset: 971364:61720949f200
user:      ad <ad%NetBSD.org@localhost>
date:      Wed Apr 22 21:35:52 2020 +0000

description:
lookup_fastforward(): handle dotdot lookups and give up less often in
the union mount case.

diffstat:

 sys/kern/vfs_cache.c  |  15 +++++++++++----
 sys/kern/vfs_lookup.c |  43 +++++++++++++++++++++++++------------------
 2 files changed, 36 insertions(+), 22 deletions(-)

diffs (118 lines):

diff -r 57d61bd0affe -r 61720949f200 sys/kern/vfs_cache.c
--- a/sys/kern/vfs_cache.c      Wed Apr 22 21:28:02 2020 +0000
+++ b/sys/kern/vfs_cache.c      Wed Apr 22 21:35:52 2020 +0000
@@ -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 @@
         * 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);
                }
diff -r 57d61bd0affe -r 61720949f200 sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c     Wed Apr 22 21:28:02 2020 +0000
+++ b/sys/kern/vfs_lookup.c     Wed Apr 22 21:35:52 2020 +0000
@@ -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 @@
                }
 
                /*
-                * 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 @@
                        }
                }
 
-               /* 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 @@
                }
                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;
                }
 



Home | Main Index | Thread Index | Old Index