svn commit: r308665 - head/sys/kern
Mateusz Guzik
mjg at FreeBSD.org
Tue Nov 15 03:38:06 UTC 2016
Author: mjg
Date: Tue Nov 15 03:38:05 2016
New Revision: 308665
URL: https://svnweb.freebsd.org/changeset/base/308665
Log:
cache: fix a race between entry removal and demotion
The negative list shrinker can demote an entry with only hotlist + neglist
locks held. On the other hand entry removal possibly sets the NCF_DVDROP
without aformentioned locks held prior to detaching it from the respective
netlist., which can lose the update made by the shrinker.
Reported and tested by: truckman
Modified:
head/sys/kern/vfs_cache.c
Modified: head/sys/kern/vfs_cache.c
==============================================================================
--- head/sys/kern/vfs_cache.c Tue Nov 15 02:36:12 2016 (r308664)
+++ head/sys/kern/vfs_cache.c Tue Nov 15 03:38:05 2016 (r308665)
@@ -868,6 +868,13 @@ cache_zap_locked(struct namecache *ncp,
nc_get_name(ncp), ncp->nc_neghits);
}
LIST_REMOVE(ncp, nc_hash);
+ if (!(ncp->nc_flag & NCF_NEGATIVE)) {
+ TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, ncp, nc_dst);
+ if (ncp == ncp->nc_vp->v_cache_dd)
+ ncp->nc_vp->v_cache_dd = NULL;
+ } else {
+ cache_negative_remove(ncp, neg_locked);
+ }
if (ncp->nc_flag & NCF_ISDOTDOT) {
if (ncp == ncp->nc_dvp->v_cache_dd)
ncp->nc_dvp->v_cache_dd = NULL;
@@ -878,13 +885,6 @@ cache_zap_locked(struct namecache *ncp,
atomic_subtract_rel_long(&numcachehv, 1);
}
}
- if (!(ncp->nc_flag & NCF_NEGATIVE)) {
- TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, ncp, nc_dst);
- if (ncp == ncp->nc_vp->v_cache_dd)
- ncp->nc_vp->v_cache_dd = NULL;
- } else {
- cache_negative_remove(ncp, neg_locked);
- }
atomic_subtract_rel_long(&numcache, 1);
}
More information about the svn-src-all
mailing list