NFS: Don't use GFP_KERNEL in rpcsec_gss downcalls
[safe/jmp/linux-2.6] / net / sunrpc / cache.c
index ade8a7e..39bddba 100644 (file)
@@ -105,18 +105,16 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
 
 static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
 
-static int cache_fresh_locked(struct cache_head *head, time_t expiry)
+static void cache_fresh_locked(struct cache_head *head, time_t expiry)
 {
        head->expiry_time = expiry;
        head->last_refresh = get_seconds();
-       return !test_and_set_bit(CACHE_VALID, &head->flags);
+       set_bit(CACHE_VALID, &head->flags);
 }
 
 static void cache_fresh_unlocked(struct cache_head *head,
-                       struct cache_detail *detail, int new)
+                                struct cache_detail *detail)
 {
-       if (new)
-               cache_revisit_request(head);
        if (test_and_clear_bit(CACHE_PENDING, &head->flags)) {
                cache_revisit_request(head);
                cache_dequeue(detail, head);
@@ -132,7 +130,6 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
         */
        struct cache_head **head;
        struct cache_head *tmp;
-       int is_new;
 
        if (!test_bit(CACHE_VALID, &old->flags)) {
                write_lock(&detail->hash_lock);
@@ -141,9 +138,9 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
                                set_bit(CACHE_NEGATIVE, &old->flags);
                        else
                                detail->update(old, new);
-                       is_new = cache_fresh_locked(old, new->expiry_time);
+                       cache_fresh_locked(old, new->expiry_time);
                        write_unlock(&detail->hash_lock);
-                       cache_fresh_unlocked(old, detail, is_new);
+                       cache_fresh_unlocked(old, detail);
                        return old;
                }
                write_unlock(&detail->hash_lock);
@@ -167,11 +164,11 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
        *head = tmp;
        detail->entries++;
        cache_get(tmp);
-       is_new = cache_fresh_locked(tmp, new->expiry_time);
+       cache_fresh_locked(tmp, new->expiry_time);
        cache_fresh_locked(old, 0);
        write_unlock(&detail->hash_lock);
-       cache_fresh_unlocked(tmp, detail, is_new);
-       cache_fresh_unlocked(old, detail, 0);
+       cache_fresh_unlocked(tmp, detail);
+       cache_fresh_unlocked(old, detail);
        cache_put(old, detail);
        return tmp;
 }
@@ -240,8 +237,8 @@ int cache_check(struct cache_detail *detail,
                                cache_revisit_request(h);
                                if (rv == -EAGAIN) {
                                        set_bit(CACHE_NEGATIVE, &h->flags);
-                                       cache_fresh_unlocked(h, detail,
-                                            cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY));
+                                       cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY);
+                                       cache_fresh_unlocked(h, detail);
                                        rv = -ENOENT;
                                }
                                break;
@@ -255,7 +252,7 @@ int cache_check(struct cache_detail *detail,
        }
 
        if (rv == -EAGAIN) {
-               if (cache_defer_req(rqstp, h) == 0) {
+               if (cache_defer_req(rqstp, h) < 0) {
                        /* Request is not deferred */
                        rv = cache_is_valid(detail, h);
                        if (rv == -EAGAIN)
@@ -404,9 +401,8 @@ static int cache_clean(void)
                for (; ch; cp= & ch->next, ch= *cp) {
                        if (current_detail->nextcheck > ch->expiry_time)
                                current_detail->nextcheck = ch->expiry_time+1;
-                       if (ch->expiry_time >= get_seconds()
-                           && ch->last_refresh >= current_detail->flush_time
-                               )
+                       if (ch->expiry_time >= get_seconds() &&
+                           ch->last_refresh >= current_detail->flush_time)
                                continue;
                        if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
                                cache_dequeue(current_detail, ch);
@@ -503,7 +499,7 @@ static int cache_defer_cnt;
 
 static int cache_defer_req(struct cache_req *req, struct cache_head *item)
 {
-       struct cache_deferred_req *dreq;
+       struct cache_deferred_req *dreq, *discard;
        int hash = DFR_HASH(item);
 
        if (cache_defer_cnt >= DFR_MAX) {
@@ -511,11 +507,11 @@ static int cache_defer_req(struct cache_req *req, struct cache_head *item)
                 * or continue and drop the oldest below
                 */
                if (net_random()&1)
-                       return 0;
+                       return -ENOMEM;
        }
        dreq = req->defer(req);
        if (dreq == NULL)
-               return 0;
+               return -ENOMEM;
 
        dreq->item = item;
 
@@ -528,26 +524,26 @@ static int cache_defer_req(struct cache_req *req, struct cache_head *item)
        list_add(&dreq->hash, &cache_defer_hash[hash]);
 
        /* it is in, now maybe clean up */
-       dreq = NULL;
+       discard = NULL;
        if (++cache_defer_cnt > DFR_MAX) {
-               dreq = list_entry(cache_defer_list.prev,
-                                 struct cache_deferred_req, recent);
-               list_del(&dreq->recent);
-               list_del(&dreq->hash);
+               discard = list_entry(cache_defer_list.prev,
+                                    struct cache_deferred_req, recent);
+               list_del_init(&discard->recent);
+               list_del_init(&discard->hash);
                cache_defer_cnt--;
        }
        spin_unlock(&cache_defer_lock);
 
-       if (dreq) {
+       if (discard)
                /* there was one too many */
-               dreq->revisit(dreq, 1);
-       }
+               discard->revisit(discard, 1);
+
        if (!test_bit(CACHE_PENDING, &item->flags)) {
                /* must have just been validated... */
                cache_revisit_request(item);
-               return 0;
+               return -EAGAIN;
        }
-       return 1;
+       return 0;
 }
 
 static void cache_revisit_request(struct cache_head *item)
@@ -567,7 +563,7 @@ static void cache_revisit_request(struct cache_head *item)
                        dreq = list_entry(lp, struct cache_deferred_req, hash);
                        lp = lp->next;
                        if (dreq->item == item) {
-                               list_del(&dreq->hash);
+                               list_del_init(&dreq->hash);
                                list_move(&dreq->recent, &pending);
                                cache_defer_cnt--;
                        }
@@ -593,7 +589,7 @@ void cache_clean_deferred(void *owner)
 
        list_for_each_entry_safe(dreq, tmp, &cache_defer_list, recent) {
                if (dreq->owner == owner) {
-                       list_del(&dreq->hash);
+                       list_del_init(&dreq->hash);
                        list_move(&dreq->recent, &pending);
                        cache_defer_cnt--;
                }