mirror of
https://github.com/ceph/ceph
synced 2025-02-14 14:28:36 +00:00
kclient: reuse osd struct when possible
This commit is contained in:
parent
88c788f9d6
commit
1ca917793f
@ -329,9 +329,10 @@ static void destroy_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
|
||||
dout("destroy_osd %p\n", osd);
|
||||
BUG_ON(!list_empty(&osd->o_requests));
|
||||
rb_erase(&osd->o_node, &osdc->osds);
|
||||
osd->o_con->private = NULL;
|
||||
ceph_con_close(osd->o_con);
|
||||
osd->o_con->ops->put(osd->o_con);
|
||||
kfree(osd);
|
||||
osd->o_con = NULL;
|
||||
}
|
||||
|
||||
static int reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
|
||||
@ -341,9 +342,11 @@ static int reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
|
||||
dout("reset_osd %p osd%d\n", osd, osd->o_osd);
|
||||
if (list_empty(&osd->o_requests)) {
|
||||
destroy_osd(osdc, osd);
|
||||
kfree(osd);
|
||||
} else {
|
||||
ceph_con_close(osd->o_con);
|
||||
osd->o_con->ops->put(osd->o_con);
|
||||
osd->o_con = NULL;
|
||||
ret = open_osd_session(osdc, osd);
|
||||
}
|
||||
return ret;
|
||||
@ -432,8 +435,10 @@ static void __unregister_request(struct ceph_osd_client *osdc,
|
||||
osdc->num_requests--;
|
||||
|
||||
list_del_init(&req->r_osd_item);
|
||||
if (list_empty(&req->r_osd->o_requests))
|
||||
if (list_empty(&req->r_osd->o_requests)) {
|
||||
destroy_osd(osdc, req->r_osd);
|
||||
kfree(req->r_osd);
|
||||
}
|
||||
req->r_osd = NULL;
|
||||
|
||||
ceph_osdc_put_request(req);
|
||||
@ -458,20 +463,22 @@ static void __unregister_request(struct ceph_osd_client *osdc,
|
||||
|
||||
|
||||
/*
|
||||
* Pick an osd (the first 'up' osd in the pg), and put result in
|
||||
* req->r_last_osd[_addr]. If none, set to -1.
|
||||
* Pick an osd (the first 'up' osd in the pg), allocate the osd struct
|
||||
* (as needed), and set the request r_osd appropriately. If there is
|
||||
* no up osd, set r_osd to NULL.
|
||||
*
|
||||
* Caller should hold map_sem for read.
|
||||
* Return 0 if unchanged, 1 if changed, or negative on error.
|
||||
*
|
||||
* return 0 if unchanged, 1 if changed.
|
||||
* Caller should hold map_sem for read and request_mutex.
|
||||
*/
|
||||
static int map_osds(struct ceph_osd_client *osdc,
|
||||
struct ceph_osd_request *req)
|
||||
static int __map_osds(struct ceph_osd_client *osdc,
|
||||
struct ceph_osd_request *req)
|
||||
{
|
||||
struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
|
||||
union ceph_pg pgid;
|
||||
int o = -1;
|
||||
int err;
|
||||
struct ceph_osd *newosd = NULL;
|
||||
|
||||
err = ceph_calc_object_layout(&reqhead->layout, req->r_oid,
|
||||
&req->r_file_layout, osdc->osdmap);
|
||||
@ -480,33 +487,45 @@ static int map_osds(struct ceph_osd_client *osdc,
|
||||
pgid.pg64 = le64_to_cpu(reqhead->layout.ol_pgid);
|
||||
o = ceph_calc_pg_primary(osdc->osdmap, pgid);
|
||||
|
||||
if (req->r_osd && req->r_osd->o_osd == o)
|
||||
return 0;
|
||||
if ((req->r_osd && req->r_osd->o_osd == o) ||
|
||||
(req->r_osd == NULL && o == -1))
|
||||
return 0; /* no change */
|
||||
|
||||
dout("map_osds tid %llu pgid %llx pool %d osd%d (was osd%d)\n",
|
||||
req->r_tid, pgid.pg64, pgid.pg.pool, o,
|
||||
req->r_osd ? req->r_osd->o_osd : -1);
|
||||
|
||||
/* XXX FIXME: try to reuse r_osd where possible */
|
||||
if (req->r_osd) {
|
||||
list_del_init(&req->r_osd_item);
|
||||
if (list_empty(&req->r_osd->o_requests))
|
||||
destroy_osd(osdc, req->r_osd);
|
||||
if (list_empty(&req->r_osd->o_requests)) {
|
||||
/* try to re-use r_osd if possible */
|
||||
newosd = req->r_osd;
|
||||
destroy_osd(osdc, newosd);
|
||||
}
|
||||
req->r_osd = NULL;
|
||||
}
|
||||
|
||||
req->r_osd = __lookup_osd(osdc, o);
|
||||
if (!req->r_osd) {
|
||||
req->r_osd = kmalloc(sizeof(*req->r_osd), GFP_NOFS);
|
||||
if (!req->r_osd)
|
||||
return -ENOMEM;
|
||||
if (!req->r_osd && o >= 0) {
|
||||
if (newosd) {
|
||||
req->r_osd = newosd;
|
||||
newosd = NULL;
|
||||
} else {
|
||||
err = -ENOMEM;
|
||||
req->r_osd = kmalloc(sizeof(*req->r_osd), GFP_NOFS);
|
||||
if (!req->r_osd)
|
||||
goto out;
|
||||
}
|
||||
init_osd(osdc, req->r_osd, o);
|
||||
#warning check return value
|
||||
open_osd_session(osdc, req->r_osd);
|
||||
__insert_osd(osdc, req->r_osd);
|
||||
}
|
||||
|
||||
list_add(&req->r_osd_item, &req->r_osd->o_requests);
|
||||
return 1;
|
||||
err = 1; /* osd changed */
|
||||
|
||||
out:
|
||||
kfree(newosd);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user