Skip to content

Commit

Permalink
libceph: DEFINE_RB_FUNCS macro
Browse files Browse the repository at this point in the history
Given

    struct foo {
        u64 id;
        struct rb_node bar_node;
    };

generate insert_bar(), erase_bar() and lookup_bar() functions with

    DEFINE_RB_FUNCS(bar, struct foo, id, bar_node)

The key is assumed to be an integer (u64, int, etc), compared with
< and >.  nodefld has to be initialized with RB_CLEAR_NODE().

Start using it for MDS, MON and OSD requests and OSD sessions.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
  • Loading branch information
Ilya Dryomov committed May 25, 2016
1 parent 42a2c09 commit fcd00b6
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 172 deletions.
54 changes: 13 additions & 41 deletions fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,51 +567,23 @@ void ceph_mdsc_release_request(struct kref *kref)
kfree(req);
}

DEFINE_RB_FUNCS(request, struct ceph_mds_request, r_tid, r_node)

/*
* lookup session, bump ref if found.
*
* called under mdsc->mutex.
*/
static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc,
u64 tid)
static struct ceph_mds_request *
lookup_get_request(struct ceph_mds_client *mdsc, u64 tid)
{
struct ceph_mds_request *req;
struct rb_node *n = mdsc->request_tree.rb_node;

while (n) {
req = rb_entry(n, struct ceph_mds_request, r_node);
if (tid < req->r_tid)
n = n->rb_left;
else if (tid > req->r_tid)
n = n->rb_right;
else {
ceph_mdsc_get_request(req);
return req;
}
}
return NULL;
}

static void __insert_request(struct ceph_mds_client *mdsc,
struct ceph_mds_request *new)
{
struct rb_node **p = &mdsc->request_tree.rb_node;
struct rb_node *parent = NULL;
struct ceph_mds_request *req = NULL;
req = lookup_request(&mdsc->request_tree, tid);
if (req)
ceph_mdsc_get_request(req);

while (*p) {
parent = *p;
req = rb_entry(parent, struct ceph_mds_request, r_node);
if (new->r_tid < req->r_tid)
p = &(*p)->rb_left;
else if (new->r_tid > req->r_tid)
p = &(*p)->rb_right;
else
BUG();
}

rb_link_node(&new->r_node, parent, p);
rb_insert_color(&new->r_node, &mdsc->request_tree);
return req;
}

/*
Expand All @@ -630,7 +602,7 @@ static void __register_request(struct ceph_mds_client *mdsc,
req->r_num_caps);
dout("__register_request %p tid %lld\n", req, req->r_tid);
ceph_mdsc_get_request(req);
__insert_request(mdsc, req);
insert_request(&mdsc->request_tree, req);

req->r_uid = current_fsuid();
req->r_gid = current_fsgid();
Expand Down Expand Up @@ -663,8 +635,7 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
}
}

rb_erase(&req->r_node, &mdsc->request_tree);
RB_CLEAR_NODE(&req->r_node);
erase_request(&mdsc->request_tree, req);

if (req->r_unsafe_dir && req->r_got_unsafe) {
struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
Expand Down Expand Up @@ -1722,6 +1693,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
INIT_LIST_HEAD(&req->r_unsafe_target_item);
req->r_fmode = -1;
kref_init(&req->r_kref);
RB_CLEAR_NODE(&req->r_node);
INIT_LIST_HEAD(&req->r_wait);
init_completion(&req->r_completion);
init_completion(&req->r_safe_completion);
Expand Down Expand Up @@ -2414,7 +2386,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
/* get request, session */
tid = le64_to_cpu(msg->hdr.tid);
mutex_lock(&mdsc->mutex);
req = __lookup_request(mdsc, tid);
req = lookup_get_request(mdsc, tid);
if (!req) {
dout("handle_reply on unknown tid %llu\n", tid);
mutex_unlock(&mdsc->mutex);
Expand Down Expand Up @@ -2604,7 +2576,7 @@ static void handle_forward(struct ceph_mds_client *mdsc,
fwd_seq = ceph_decode_32(&p);

mutex_lock(&mdsc->mutex);
req = __lookup_request(mdsc, tid);
req = lookup_get_request(mdsc, tid);
if (!req) {
dout("forward tid %llu to mds%d - req dne\n", tid, next_mds);
goto out; /* dup reply? */
Expand Down
57 changes: 57 additions & 0 deletions include/linux/ceph/libceph.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,63 @@ static inline int calc_pages_for(u64 off, u64 len)
(off >> PAGE_SHIFT);
}

/*
* These are not meant to be generic - an integer key is assumed.
*/
#define DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \
static void insert_##name(struct rb_root *root, type *t) \
{ \
struct rb_node **n = &root->rb_node; \
struct rb_node *parent = NULL; \
\
BUG_ON(!RB_EMPTY_NODE(&t->nodefld)); \
\
while (*n) { \
type *cur = rb_entry(*n, type, nodefld); \
\
parent = *n; \
if (t->keyfld < cur->keyfld) \
n = &(*n)->rb_left; \
else if (t->keyfld > cur->keyfld) \
n = &(*n)->rb_right; \
else \
BUG(); \
} \
\
rb_link_node(&t->nodefld, parent, n); \
rb_insert_color(&t->nodefld, root); \
} \
static void erase_##name(struct rb_root *root, type *t) \
{ \
BUG_ON(RB_EMPTY_NODE(&t->nodefld)); \
rb_erase(&t->nodefld, root); \
RB_CLEAR_NODE(&t->nodefld); \
}

#define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) \
static type *lookup_##name(struct rb_root *root, \
typeof(((type *)0)->keyfld) key) \
{ \
struct rb_node *n = root->rb_node; \
\
while (n) { \
type *cur = rb_entry(n, type, nodefld); \
\
if (key < cur->keyfld) \
n = n->rb_left; \
else if (key > cur->keyfld) \
n = n->rb_right; \
else \
return cur; \
} \
\
return NULL; \
}

#define DEFINE_RB_FUNCS(name, type, keyfld, nodefld) \
DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \
DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld)

extern struct kmem_cache *ceph_inode_cachep;
extern struct kmem_cache *ceph_cap_cachep;
extern struct kmem_cache *ceph_cap_flush_cachep;
Expand Down
52 changes: 8 additions & 44 deletions net/ceph/mon_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,45 +478,7 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
/*
* generic requests (currently statfs, mon_get_version)
*/
static struct ceph_mon_generic_request *__lookup_generic_req(
struct ceph_mon_client *monc, u64 tid)
{
struct ceph_mon_generic_request *req;
struct rb_node *n = monc->generic_request_tree.rb_node;

while (n) {
req = rb_entry(n, struct ceph_mon_generic_request, node);
if (tid < req->tid)
n = n->rb_left;
else if (tid > req->tid)
n = n->rb_right;
else
return req;
}
return NULL;
}

static void __insert_generic_request(struct ceph_mon_client *monc,
struct ceph_mon_generic_request *new)
{
struct rb_node **p = &monc->generic_request_tree.rb_node;
struct rb_node *parent = NULL;
struct ceph_mon_generic_request *req = NULL;

while (*p) {
parent = *p;
req = rb_entry(parent, struct ceph_mon_generic_request, node);
if (new->tid < req->tid)
p = &(*p)->rb_left;
else if (new->tid > req->tid)
p = &(*p)->rb_right;
else
BUG();
}

rb_link_node(&new->node, parent, p);
rb_insert_color(&new->node, &monc->generic_request_tree);
}
DEFINE_RB_FUNCS(generic_request, struct ceph_mon_generic_request, tid, node)

static void release_generic_request(struct kref *kref)
{
Expand Down Expand Up @@ -551,7 +513,7 @@ static struct ceph_msg *get_generic_reply(struct ceph_connection *con,
struct ceph_msg *m;

mutex_lock(&monc->mutex);
req = __lookup_generic_req(monc, tid);
req = lookup_generic_request(&monc->generic_request_tree, tid);
if (!req) {
dout("get_generic_reply %lld dne\n", tid);
*skip = 1;
Expand All @@ -578,14 +540,14 @@ static int __do_generic_request(struct ceph_mon_client *monc, u64 tid,
/* register request */
req->tid = tid != 0 ? tid : ++monc->last_tid;
req->request->hdr.tid = cpu_to_le64(req->tid);
__insert_generic_request(monc, req);
insert_generic_request(&monc->generic_request_tree, req);
ceph_con_send(&monc->con, ceph_msg_get(req->request));
mutex_unlock(&monc->mutex);

err = wait_for_completion_interruptible(&req->completion);

mutex_lock(&monc->mutex);
rb_erase(&req->node, &monc->generic_request_tree);
erase_generic_request(&monc->generic_request_tree, req);

if (!err)
err = req->result;
Expand Down Expand Up @@ -619,7 +581,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc,
dout("handle_statfs_reply %p tid %llu\n", msg, tid);

mutex_lock(&monc->mutex);
req = __lookup_generic_req(monc, tid);
req = lookup_generic_request(&monc->generic_request_tree, tid);
if (req) {
*(struct ceph_statfs *)req->buf = reply->st;
req->result = 0;
Expand Down Expand Up @@ -651,6 +613,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
return -ENOMEM;

kref_init(&req->kref);
RB_CLEAR_NODE(&req->node);
req->buf = buf;
init_completion(&req->completion);

Expand Down Expand Up @@ -696,7 +659,7 @@ static void handle_get_version_reply(struct ceph_mon_client *monc,
goto bad;

mutex_lock(&monc->mutex);
req = __lookup_generic_req(monc, handle);
req = lookup_generic_request(&monc->generic_request_tree, handle);
if (req) {
*(u64 *)req->buf = ceph_decode_64(&p);
req->result = 0;
Expand Down Expand Up @@ -732,6 +695,7 @@ int ceph_monc_do_get_version(struct ceph_mon_client *monc, const char *what,
return -ENOMEM;

kref_init(&req->kref);
RB_CLEAR_NODE(&req->node);
req->buf = newest;
init_completion(&req->completion);

Expand Down
Loading

0 comments on commit fcd00b6

Please sign in to comment.