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>
This commit is contained in:
parent
0abb43dcac
commit
e4339d28f6
4 changed files with 10 additions and 7 deletions
|
@ -2865,7 +2865,6 @@ fail:
|
|||
mutex_unlock(&session->s_mutex);
|
||||
fail_nomsg:
|
||||
ceph_pagelist_release(pagelist);
|
||||
kfree(pagelist);
|
||||
fail_nopagelist:
|
||||
pr_err("error %d preparing reconnect for mds%d\n", err, mds);
|
||||
return;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __FS_CEPH_PAGELIST_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
struct ceph_pagelist {
|
||||
struct list_head head;
|
||||
|
@ -10,6 +11,7 @@ struct ceph_pagelist {
|
|||
size_t room;
|
||||
struct list_head free_list;
|
||||
size_t num_pages_free;
|
||||
atomic_t refcnt;
|
||||
};
|
||||
|
||||
struct ceph_pagelist_cursor {
|
||||
|
@ -26,9 +28,10 @@ static inline void ceph_pagelist_init(struct ceph_pagelist *pl)
|
|||
pl->room = 0;
|
||||
INIT_LIST_HEAD(&pl->free_list);
|
||||
pl->num_pages_free = 0;
|
||||
atomic_set(&pl->refcnt, 1);
|
||||
}
|
||||
|
||||
extern int ceph_pagelist_release(struct ceph_pagelist *pl);
|
||||
extern void ceph_pagelist_release(struct ceph_pagelist *pl);
|
||||
|
||||
extern int ceph_pagelist_append(struct ceph_pagelist *pl, const void *d, size_t l);
|
||||
|
||||
|
|
|
@ -3071,10 +3071,8 @@ static void ceph_msg_data_destroy(struct ceph_msg_data *data)
|
|||
return;
|
||||
|
||||
WARN_ON(!list_empty(&data->links));
|
||||
if (data->type == CEPH_MSG_DATA_PAGELIST) {
|
||||
if (data->type == CEPH_MSG_DATA_PAGELIST)
|
||||
ceph_pagelist_release(data->pagelist);
|
||||
kfree(data->pagelist);
|
||||
}
|
||||
kmem_cache_free(ceph_msg_data_cache, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue