Module Name: src Committed By: ad Date: Mon Mar 23 20:02:14 UTC 2020
Modified Files: src/sys/kern: vfs_cache.c Log Message: cache_remove(): remove from the vnode list first, so cache_revlookup() doesn't try to re-activate an entry no longer on the LRU list. To generate a diff of this commit: cvs rdiff -u -r1.133 -r1.134 src/sys/kern/vfs_cache.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.133 src/sys/kern/vfs_cache.c:1.134 --- src/sys/kern/vfs_cache.c:1.133 Mon Mar 23 19:45:11 2020 +++ src/sys/kern/vfs_cache.c Mon Mar 23 20:02:13 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_cache.c,v 1.133 2020/03/23 19:45:11 ad Exp $ */ +/* $NetBSD: vfs_cache.c,v 1.134 2020/03/23 20:02:13 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.133 2020/03/23 19:45:11 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.134 2020/03/23 20:02:13 ad Exp $"); #define __NAMECACHE_PRIVATE #ifdef _KERNEL_OPT @@ -357,16 +357,10 @@ cache_remove(struct namecache *ncp, cons SDT_PROBE(vfs, namecache, invalidate, done, ncp, 0, 0, 0, 0); - /* First remove from the directory's rbtree. */ - rb_tree_remove_node(&dvi->vi_nc_tree, ncp); - - /* Then remove from the LRU lists. */ - mutex_enter(&cache_lru_lock); - TAILQ_REMOVE(&cache_lru.list[ncp->nc_lrulist], ncp, nc_lru); - cache_lru.count[ncp->nc_lrulist]--; - mutex_exit(&cache_lru_lock); - - /* Then remove from the node's list. */ + /* + * Remove from the vnode's list. This excludes cache_revlookup(), + * and then it's safe to remove from the LRU lists. + */ if ((vp = ncp->nc_vp) != NULL) { vnode_impl_t *vi = VNODE_TO_VIMPL(vp); if (__predict_true(dir2node)) { @@ -378,6 +372,15 @@ cache_remove(struct namecache *ncp, cons } } + /* Remove from the directory's rbtree. */ + rb_tree_remove_node(&dvi->vi_nc_tree, ncp); + + /* Remove from the LRU lists. */ + mutex_enter(&cache_lru_lock); + TAILQ_REMOVE(&cache_lru.list[ncp->nc_lrulist], ncp, nc_lru); + cache_lru.count[ncp->nc_lrulist]--; + mutex_exit(&cache_lru_lock); + /* Finally, free it. */ if (ncp->nc_nlen > NCHNAMLEN) { size_t sz = offsetof(struct namecache, nc_name[ncp->nc_nlen]);