Merge branch 'reset-seq' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libat...
[powerpc.git] / include / linux / sunrpc / cache.h
index afc481d..3699dff 100644 (file)
@@ -50,7 +50,7 @@ struct cache_head {
        time_t          last_refresh;   /* If CACHE_PENDING, this is when upcall 
                                         * was sent, else this is when update was received
                                         */
-       atomic_t        refcnt;
+       struct kref     ref;
        unsigned long   flags;
 };
 #define        CACHE_VALID     0       /* Entry contains valid data */
@@ -68,8 +68,7 @@ struct cache_detail {
        atomic_t                inuse; /* active user-space update or lookup */
 
        char                    *name;
-       void                    (*cache_put)(struct cache_head *,
-                                            struct cache_detail*);
+       void                    (*cache_put)(struct kref *);
 
        void                    (*cache_request)(struct cache_detail *cd,
                                                 struct cache_head *h,
@@ -151,22 +150,30 @@ extern void cache_clean_deferred(void *owner);
 
 static inline struct cache_head  *cache_get(struct cache_head *h)
 {
-       atomic_inc(&h->refcnt);
+       kref_get(&h->ref);
        return h;
 }
 
 
-static inline int cache_put(struct cache_head *h, struct cache_detail *cd)
+static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
 {
-       if (atomic_read(&h->refcnt) <= 2 &&
+       if (atomic_read(&h->ref.refcount) <= 2 &&
            h->expiry_time < cd->nextcheck)
                cd->nextcheck = h->expiry_time;
-       return atomic_dec_and_test(&h->refcnt);
+       kref_put(&h->ref, cd->cache_put);
+}
+
+static inline int cache_valid(struct cache_head *h)
+{
+       /* If an item has been unhashed pending removal when
+        * the refcount drops to 0, the expiry_time will be
+        * set to 0.  We don't want to consider such items
+        * valid in this context even though CACHE_VALID is
+        * set.
+        */
+       return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags));
 }
 
-extern void cache_init(struct cache_head *h);
-extern void cache_fresh(struct cache_detail *detail,
-                       struct cache_head *head, time_t expiry);
 extern int cache_check(struct cache_detail *detail,
                       struct cache_head *h, struct cache_req *rqstp);
 extern void cache_flush(void);