aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2014-09-16 05:50:45 -0400
committerSage Weil <sage@redhat.com>2014-10-14 15:56:48 -0400
commite4339d28f640a7c0d92903bcf389a2dfa281270d (patch)
tree428c172af1081d29613732cdcf7801f958be358f /net
parent0abb43dcacb52145aa265f82c914375d59dfe2da (diff)
libceph: reference counting pagelist
this allow pagelist to present data that may be sent multiple times. Signed-off-by: Yan, Zheng <zyan@redhat.com> Reviewed-by: Sage Weil <sage@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/messenger.c4
-rw-r--r--net/ceph/pagelist.c7
2 files changed, 6 insertions, 5 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index e7d94113f2d6..9764c771cfb1 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -3071,10 +3071,8 @@ static void ceph_msg_data_destroy(struct ceph_msg_data *data)
3071 return; 3071 return;
3072 3072
3073 WARN_ON(!list_empty(&data->links)); 3073 WARN_ON(!list_empty(&data->links));
3074 if (data->type == CEPH_MSG_DATA_PAGELIST) { 3074 if (data->type == CEPH_MSG_DATA_PAGELIST)
3075 ceph_pagelist_release(data->pagelist); 3075 ceph_pagelist_release(data->pagelist);
3076 kfree(data->pagelist);
3077 }
3078 kmem_cache_free(ceph_msg_data_cache, data); 3076 kmem_cache_free(ceph_msg_data_cache, data);
3079} 3077}
3080 3078
diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c
index 92866bebb65f..c7c220a736e5 100644
--- a/net/ceph/pagelist.c
+++ b/net/ceph/pagelist.c
@@ -1,5 +1,6 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/gfp.h> 2#include <linux/gfp.h>
3#include <linux/slab.h>
3#include <linux/pagemap.h> 4#include <linux/pagemap.h>
4#include <linux/highmem.h> 5#include <linux/highmem.h>
5#include <linux/ceph/pagelist.h> 6#include <linux/ceph/pagelist.h>
@@ -13,8 +14,10 @@ static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl)
13 } 14 }
14} 15}
15 16
16int ceph_pagelist_release(struct ceph_pagelist *pl) 17void ceph_pagelist_release(struct ceph_pagelist *pl)
17{ 18{
19 if (!atomic_dec_and_test(&pl->refcnt))
20 return;
18 ceph_pagelist_unmap_tail(pl); 21 ceph_pagelist_unmap_tail(pl);
19 while (!list_empty(&pl->head)) { 22 while (!list_empty(&pl->head)) {
20 struct page *page = list_first_entry(&pl->head, struct page, 23 struct page *page = list_first_entry(&pl->head, struct page,
@@ -23,7 +26,7 @@ int ceph_pagelist_release(struct ceph_pagelist *pl)
23 __free_page(page); 26 __free_page(page);
24 } 27 }
25 ceph_pagelist_free_reserve(pl); 28 ceph_pagelist_free_reserve(pl);
26 return 0; 29 kfree(pl);
27} 30}
28EXPORT_SYMBOL(ceph_pagelist_release); 31EXPORT_SYMBOL(ceph_pagelist_release);
29 32