Skip to content

Commit

Permalink
libceph: reference counting pagelist
Browse files Browse the repository at this point in the history
this allow pagelist to present data that may be sent multiple times.

Signed-off-by: Yan, Zheng <[email protected]>
Reviewed-by: Sage Weil <[email protected]>
  • Loading branch information
ukernel authored and liewegas committed Oct 14, 2014
1 parent 0abb43d commit e4339d2
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 7 deletions.
1 change: 0 additions & 1 deletion fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -2865,7 +2865,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
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;
Expand Down
5 changes: 4 additions & 1 deletion include/linux/ceph/pagelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __FS_CEPH_PAGELIST_H

#include <linux/list.h>
#include <linux/atomic.h>

struct ceph_pagelist {
struct list_head head;
Expand All @@ -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 {
Expand All @@ -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);

Expand Down
4 changes: 1 addition & 3 deletions net/ceph/messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
7 changes: 5 additions & 2 deletions net/ceph/pagelist.c
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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,
Expand All @@ -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);

Expand Down

0 comments on commit e4339d2

Please sign in to comment.