Commit aca420bc authored by Sage Weil's avatar Sage Weil

libceph: fix leak of osd structs during shutdown

We want to remove all OSDs, not just those on the idle LRU.
Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 259a187a
...@@ -685,6 +685,18 @@ static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) ...@@ -685,6 +685,18 @@ static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
put_osd(osd); put_osd(osd);
} }
static void remove_all_osds(struct ceph_osd_client *osdc)
{
dout("__remove_old_osds %p\n", osdc);
mutex_lock(&osdc->request_mutex);
while (!RB_EMPTY_ROOT(&osdc->osds)) {
struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds),
struct ceph_osd, o_node);
__remove_osd(osdc, osd);
}
mutex_unlock(&osdc->request_mutex);
}
static void __move_osd_to_lru(struct ceph_osd_client *osdc, static void __move_osd_to_lru(struct ceph_osd_client *osdc,
struct ceph_osd *osd) struct ceph_osd *osd)
{ {
...@@ -701,14 +713,14 @@ static void __remove_osd_from_lru(struct ceph_osd *osd) ...@@ -701,14 +713,14 @@ static void __remove_osd_from_lru(struct ceph_osd *osd)
list_del_init(&osd->o_osd_lru); list_del_init(&osd->o_osd_lru);
} }
static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) static void remove_old_osds(struct ceph_osd_client *osdc)
{ {
struct ceph_osd *osd, *nosd; struct ceph_osd *osd, *nosd;
dout("__remove_old_osds %p\n", osdc); dout("__remove_old_osds %p\n", osdc);
mutex_lock(&osdc->request_mutex); mutex_lock(&osdc->request_mutex);
list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
if (!remove_all && time_before(jiffies, osd->lru_ttl)) if (time_before(jiffies, osd->lru_ttl))
break; break;
__remove_osd(osdc, osd); __remove_osd(osdc, osd);
} }
...@@ -751,6 +763,7 @@ static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new) ...@@ -751,6 +763,7 @@ static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new)
struct rb_node *parent = NULL; struct rb_node *parent = NULL;
struct ceph_osd *osd = NULL; struct ceph_osd *osd = NULL;
dout("__insert_osd %p osd%d\n", new, new->o_osd);
while (*p) { while (*p) {
parent = *p; parent = *p;
osd = rb_entry(parent, struct ceph_osd, o_node); osd = rb_entry(parent, struct ceph_osd, o_node);
...@@ -1144,7 +1157,7 @@ static void handle_osds_timeout(struct work_struct *work) ...@@ -1144,7 +1157,7 @@ static void handle_osds_timeout(struct work_struct *work)
dout("osds timeout\n"); dout("osds timeout\n");
down_read(&osdc->map_sem); down_read(&osdc->map_sem);
remove_old_osds(osdc, 0); remove_old_osds(osdc);
up_read(&osdc->map_sem); up_read(&osdc->map_sem);
schedule_delayed_work(&osdc->osds_timeout_work, schedule_delayed_work(&osdc->osds_timeout_work,
...@@ -1862,8 +1875,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc) ...@@ -1862,8 +1875,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc)
ceph_osdmap_destroy(osdc->osdmap); ceph_osdmap_destroy(osdc->osdmap);
osdc->osdmap = NULL; osdc->osdmap = NULL;
} }
remove_old_osds(osdc, 1); remove_all_osds(osdc);
WARN_ON(!RB_EMPTY_ROOT(&osdc->osds));
mempool_destroy(osdc->req_mempool); mempool_destroy(osdc->req_mempool);
ceph_msgpool_destroy(&osdc->msgpool_op); ceph_msgpool_destroy(&osdc->msgpool_op);
ceph_msgpool_destroy(&osdc->msgpool_op_reply); ceph_msgpool_destroy(&osdc->msgpool_op_reply);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment