Date: Tue, 15 Nov 2016 03:38:05 +0000 (UTC) From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r308665 - head/sys/kern Message-ID: <201611150338.uAF3c50c039244@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611150338.uAF3c50c039244>