aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-08-31 17:45:53 -0400
committerSage Weil <sage@newdream.net>2011-08-31 18:22:46 -0400
commitaca420bc51f48b0701963ba3a6234442a0cabebd (patch)
tree7c9f19bd0f91d012253bed3579ec1fbdfb5ec6b1
parent259a187ade45056fd44856654f78aa9e9f0f7c75 (diff)
libceph: fix leak of osd structs during shutdown
We want to remove all OSDs, not just those on the idle LRU. Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--net/ceph/osd_client.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index ce310eee708d..16836a7df7a6 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -685,6 +685,18 @@ static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
685 put_osd(osd); 685 put_osd(osd);
686} 686}
687 687
688static void remove_all_osds(struct ceph_osd_client *osdc)
689{
690 dout("__remove_old_osds %p\n", osdc);
691 mutex_lock(&osdc->request_mutex);
692 while (!RB_EMPTY_ROOT(&osdc->osds)) {
693 struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds),
694 struct ceph_osd, o_node);
695 __remove_osd(osdc, osd);
696 }
697 mutex_unlock(&osdc->request_mutex);
698}
699
688static void __move_osd_to_lru(struct ceph_osd_client *osdc, 700static void __move_osd_to_lru(struct ceph_osd_client *osdc,
689 struct ceph_osd *osd) 701 struct ceph_osd *osd)
690{ 702{
@@ -701,14 +713,14 @@ static void __remove_osd_from_lru(struct ceph_osd *osd)
701 list_del_init(&osd->o_osd_lru); 713 list_del_init(&osd->o_osd_lru);
702} 714}
703 715
704static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) 716static void remove_old_osds(struct ceph_osd_client *osdc)
705{ 717{
706 struct ceph_osd *osd, *nosd; 718 struct ceph_osd *osd, *nosd;
707 719
708 dout("__remove_old_osds %p\n", osdc); 720 dout("__remove_old_osds %p\n", osdc);
709 mutex_lock(&osdc->request_mutex); 721 mutex_lock(&osdc->request_mutex);
710 list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { 722 list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
711 if (!remove_all && time_before(jiffies, osd->lru_ttl)) 723 if (time_before(jiffies, osd->lru_ttl))
712 break; 724 break;
713 __remove_osd(osdc, osd); 725 __remove_osd(osdc, osd);
714 } 726 }
@@ -751,6 +763,7 @@ static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new)
751 struct rb_node *parent = NULL; 763 struct rb_node *parent = NULL;
752 struct ceph_osd *osd = NULL; 764 struct ceph_osd *osd = NULL;
753 765
766 dout("__insert_osd %p osd%d\n", new, new->o_osd);
754 while (*p) { 767 while (*p) {
755 parent = *p; 768 parent = *p;
756 osd = rb_entry(parent, struct ceph_osd, o_node); 769 osd = rb_entry(parent, struct ceph_osd, o_node);
@@ -1144,7 +1157,7 @@ static void handle_osds_timeout(struct work_struct *work)
1144 1157
1145 dout("osds timeout\n"); 1158 dout("osds timeout\n");
1146 down_read(&osdc->map_sem); 1159 down_read(&osdc->map_sem);
1147 remove_old_osds(osdc, 0); 1160 remove_old_osds(osdc);
1148 up_read(&osdc->map_sem); 1161 up_read(&osdc->map_sem);
1149 1162
1150 schedule_delayed_work(&osdc->osds_timeout_work, 1163 schedule_delayed_work(&osdc->osds_timeout_work,
@@ -1862,8 +1875,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc)
1862 ceph_osdmap_destroy(osdc->osdmap); 1875 ceph_osdmap_destroy(osdc->osdmap);
1863 osdc->osdmap = NULL; 1876 osdc->osdmap = NULL;
1864 } 1877 }
1865 remove_old_osds(osdc, 1); 1878 remove_all_osds(osdc);
1866 WARN_ON(!RB_EMPTY_ROOT(&osdc->osds));
1867 mempool_destroy(osdc->req_mempool); 1879 mempool_destroy(osdc->req_mempool);
1868 ceph_msgpool_destroy(&osdc->msgpool_op); 1880 ceph_msgpool_destroy(&osdc->msgpool_op);
1869 ceph_msgpool_destroy(&osdc->msgpool_op_reply); 1881 ceph_msgpool_destroy(&osdc->msgpool_op_reply);