ceph: use kref for ceph_msg
authorSage Weil <sage@newdream.net>
Mon, 7 Dec 2009 23:55:05 +0000 (15:55 -0800)
committerSage Weil <sage@newdream.net>
Mon, 7 Dec 2009 23:55:05 +0000 (15:55 -0800)
Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/messenger.c
fs/ceph/messenger.h
fs/ceph/msgpool.c

index bf76210..b0571b0 100644 (file)
@@ -1958,7 +1958,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len,
        m = kmalloc(sizeof(*m), GFP_NOFS);
        if (m == NULL)
                goto out;
-       atomic_set(&m->nref, 1);
+       kref_init(&m->kref);
        INIT_LIST_HEAD(&m->list_head);
 
        m->hdr.type = cpu_to_le16(type);
@@ -2070,34 +2070,23 @@ void ceph_msg_kfree(struct ceph_msg *m)
 /*
  * Drop a msg ref.  Destroy as needed.
  */
-void ceph_msg_put(struct ceph_msg *m)
-{
-       dout("ceph_msg_put %p %d -> %d\n", m, atomic_read(&m->nref),
-            atomic_read(&m->nref)-1);
-       if (atomic_read(&m->nref) <= 0) {
-               pr_err("bad ceph_msg_put on %p %llu %d=%s %d+%d\n",
-                      m, le64_to_cpu(m->hdr.seq),
-                      le16_to_cpu(m->hdr.type),
-                      ceph_msg_type_name(le16_to_cpu(m->hdr.type)),
-                      le32_to_cpu(m->hdr.front_len),
-                      le32_to_cpu(m->hdr.data_len));
-               WARN_ON(1);
-       }
-       if (atomic_dec_and_test(&m->nref)) {
-               dout("ceph_msg_put last one on %p\n", m);
-               WARN_ON(!list_empty(&m->list_head));
-
-               /* drop middle, data, if any */
-               if (m->middle) {
-                       ceph_buffer_put(m->middle);
-                       m->middle = NULL;
-               }
-               m->nr_pages = 0;
-               m->pages = NULL;
+void ceph_msg_last_put(struct kref *kref)
+{
+       struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);
 
-               if (m->pool)
-                       ceph_msgpool_put(m->pool, m);
-               else
-                       ceph_msg_kfree(m);
+       dout("ceph_msg_put last one on %p\n", m);
+       WARN_ON(!list_empty(&m->list_head));
+
+       /* drop middle, data, if any */
+       if (m->middle) {
+               ceph_buffer_put(m->middle);
+               m->middle = NULL;
        }
+       m->nr_pages = 0;
+       m->pages = NULL;
+
+       if (m->pool)
+               ceph_msgpool_put(m->pool, m);
+       else
+               ceph_msg_kfree(m);
 }
index f9c9f64..981b7c0 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __FS_CEPH_MESSENGER_H
 #define __FS_CEPH_MESSENGER_H
 
+#include <linux/kref.h>
 #include <linux/mutex.h>
 #include <linux/net.h>
 #include <linux/radix-tree.h>
@@ -85,7 +86,7 @@ struct ceph_msg {
        struct page **pages;            /* data payload.  NOT OWNER. */
        unsigned nr_pages;              /* size of page array */
        struct list_head list_head;
-       atomic_t nref;
+       struct kref kref;
        bool front_is_vmalloc;
        bool more_to_follow;
        int front_max;
@@ -243,11 +244,13 @@ extern int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg);
 
 static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg)
 {
-       dout("ceph_msg_get %p %d -> %d\n", msg, atomic_read(&msg->nref),
-            atomic_read(&msg->nref)+1);
-       atomic_inc(&msg->nref);
+       kref_get(&msg->kref);
        return msg;
 }
-extern void ceph_msg_put(struct ceph_msg *msg);
+extern void ceph_msg_last_put(struct kref *kref);
+static inline void ceph_msg_put(struct ceph_msg *msg)
+{
+       kref_put(&msg->kref, ceph_msg_last_put);
+}
 
 #endif
index 7599b33..ad5482c 100644 (file)
@@ -165,7 +165,7 @@ void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
 {
        spin_lock(&pool->lock);
        if (pool->num < pool->min) {
-               ceph_msg_get(msg);   /* retake a single ref */
+               kref_set(&msg->kref, 1);  /* retake a single ref */
                list_add(&msg->list_head, &pool->msgs);
                pool->num++;
                dout("msgpool_put %p reclaim %p, now %d/%d\n", pool, msg,