]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/sunrpc/cache.c
svcrpc: take lock on turning entry NEGATIVE in cache_check
[karo-tx-linux.git] / net / sunrpc / cache.c
index 0d6002f26d82313d25f142038a58e5fe926bb35b..a6c57334fa137749753ad5d3397c011bdae37ec3 100644 (file)
@@ -213,6 +213,23 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head
        }
 }
 
+static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h)
+{
+       int rv;
+
+       write_lock(&detail->hash_lock);
+       rv = cache_is_valid(detail, h);
+       if (rv != -EAGAIN) {
+               write_unlock(&detail->hash_lock);
+               return rv;
+       }
+       set_bit(CACHE_NEGATIVE, &h->flags);
+       cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
+       write_unlock(&detail->hash_lock);
+       cache_fresh_unlocked(h, detail);
+       return -ENOENT;
+}
+
 /*
  * This is the generic cache management routine for all
  * the authentication caches.
@@ -251,14 +268,8 @@ int cache_check(struct cache_detail *detail,
                        case -EINVAL:
                                clear_bit(CACHE_PENDING, &h->flags);
                                cache_revisit_request(h);
-                               if (rv == -EAGAIN) {
-                                       set_bit(CACHE_NEGATIVE, &h->flags);
-                                       cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
-                                       cache_fresh_unlocked(h, detail);
-                                       rv = -ENOENT;
-                               }
+                               rv = try_to_negate_entry(detail, h);
                                break;
-
                        case -EAGAIN:
                                clear_bit(CACHE_PENDING, &h->flags);
                                cache_revisit_request(h);