summaryrefslogtreecommitdiffstats
path: root/net/ceph/pagelist.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2014-09-16 17:50:45 +0800
committerSage Weil <sage@redhat.com>2014-10-14 12:56:48 -0700
commite4339d28f640a7c0d92903bcf389a2dfa281270d (patch)
tree428c172af1081d29613732cdcf7801f958be358f /net/ceph/pagelist.c
parent0abb43dcacb52145aa265f82c914375d59dfe2da (diff)
downloadlinux-e4339d28f640a7c0d92903bcf389a2dfa281270d.tar.bz2
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/ceph/pagelist.c')
-rw-r--r--net/ceph/pagelist.c7
1 files changed, 5 insertions, 2 deletions
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 @@
#include <linux/module.h>
#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/ceph/pagelist.h>
@@ -13,8 +14,10 @@ static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl)
}
}
-int ceph_pagelist_release(struct ceph_pagelist *pl)
+void ceph_pagelist_release(struct ceph_pagelist *pl)
{
+ if (!atomic_dec_and_test(&pl->refcnt))
+ return;
ceph_pagelist_unmap_tail(pl);
while (!list_empty(&pl->head)) {
struct page *page = list_first_entry(&pl->head, struct page,
@@ -23,7 +26,7 @@ int ceph_pagelist_release(struct ceph_pagelist *pl)
__free_page(page);
}
ceph_pagelist_free_reserve(pl);
- return 0;
+ kfree(pl);
}
EXPORT_SYMBOL(ceph_pagelist_release);