kernel - Fix bug in recent defered-zap namecache code.
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 20 Jan 2010 16:00:07 +0000 (08:00 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 20 Jan 2010 16:00:07 +0000 (08:00 -0800)
* The NCF_DEFEREDZAP code could get into a degenerate situation
  where every name lookup ate tons of system cpu.  Reset the
  numdefered variable after cleaning defered-zap entries to fix.

sys/kern/vfs_cache.c

index c88c87c..6a0d3b6 100644 (file)
@@ -484,6 +484,7 @@ _cache_drop(struct namecache *ncp)
 
                if (refs == 1) {
                        if (_cache_lock_nonblock(ncp) == 0) {
+                               ncp->nc_flag &= ~NCF_DEFEREDZAP;
                                if ((ncp->nc_flag & NCF_UNRESOLVED) &&
                                    TAILQ_EMPTY(&ncp->nc_list)) {
                                        ncp = cache_zap(ncp, 1);
@@ -2624,6 +2625,7 @@ _cache_cleandefered(void)
        struct namecache dummy;
        int i;
 
+       numdefered = 0;
        bzero(&dummy, sizeof(dummy));
        dummy.nc_flag = NCF_DESTROYED;
 
@@ -2640,6 +2642,10 @@ _cache_cleandefered(void)
                        LIST_INSERT_AFTER(ncp, &dummy, nc_hash);
                        _cache_hold(ncp);
                        spin_unlock_wr(&nchpp->spin);
+                       if (_cache_lock_nonblock(ncp) == 0) {
+                               ncp->nc_flag &= ~NCF_DEFEREDZAP;
+                               _cache_unlock(ncp);
+                       }
                        _cache_drop(ncp);
                        spin_lock_wr(&nchpp->spin);
                        ncp = &dummy;