aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osd_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ceph/osd_client.c')
-rw-r--r--net/ceph/osd_client.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 7330c2757c0..88ad8a2501b 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -217,6 +217,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
217 INIT_LIST_HEAD(&req->r_unsafe_item); 217 INIT_LIST_HEAD(&req->r_unsafe_item);
218 INIT_LIST_HEAD(&req->r_linger_item); 218 INIT_LIST_HEAD(&req->r_linger_item);
219 INIT_LIST_HEAD(&req->r_linger_osd); 219 INIT_LIST_HEAD(&req->r_linger_osd);
220 INIT_LIST_HEAD(&req->r_req_lru_item);
220 req->r_flags = flags; 221 req->r_flags = flags;
221 222
222 WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0); 223 WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0);
@@ -685,6 +686,18 @@ static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
685 put_osd(osd); 686 put_osd(osd);
686} 687}
687 688
689static void remove_all_osds(struct ceph_osd_client *osdc)
690{
691 dout("__remove_old_osds %p\n", osdc);
692 mutex_lock(&osdc->request_mutex);
693 while (!RB_EMPTY_ROOT(&osdc->osds)) {
694 struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds),
695 struct ceph_osd, o_node);
696 __remove_osd(osdc, osd);
697 }
698 mutex_unlock(&osdc->request_mutex);
699}
700
688static void __move_osd_to_lru(struct ceph_osd_client *osdc, 701static void __move_osd_to_lru(struct ceph_osd_client *osdc,
689 struct ceph_osd *osd) 702 struct ceph_osd *osd)
690{ 703{
@@ -701,14 +714,14 @@ static void __remove_osd_from_lru(struct ceph_osd *osd)
701 list_del_init(&osd->o_osd_lru); 714 list_del_init(&osd->o_osd_lru);
702} 715}
703 716
704static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) 717static void remove_old_osds(struct ceph_osd_client *osdc)
705{ 718{
706 struct ceph_osd *osd, *nosd; 719 struct ceph_osd *osd, *nosd;
707 720
708 dout("__remove_old_osds %p\n", osdc); 721 dout("__remove_old_osds %p\n", osdc);
709 mutex_lock(&osdc->request_mutex); 722 mutex_lock(&osdc->request_mutex);
710 list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { 723 list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
711 if (!remove_all && time_before(jiffies, osd->lru_ttl)) 724 if (time_before(jiffies, osd->lru_ttl))
712 break; 725 break;
713 __remove_osd(osdc, osd); 726 __remove_osd(osdc, osd);
714 } 727 }
@@ -751,6 +764,7 @@ static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new)
751 struct rb_node *parent = NULL; 764 struct rb_node *parent = NULL;
752 struct ceph_osd *osd = NULL; 765 struct ceph_osd *osd = NULL;
753 766
767 dout("__insert_osd %p osd%d\n", new, new->o_osd);
754 while (*p) { 768 while (*p) {
755 parent = *p; 769 parent = *p;
756 osd = rb_entry(parent, struct ceph_osd, o_node); 770 osd = rb_entry(parent, struct ceph_osd, o_node);
@@ -803,13 +817,10 @@ static void __register_request(struct ceph_osd_client *osdc,
803{ 817{
804 req->r_tid = ++osdc->last_tid; 818 req->r_tid = ++osdc->last_tid;
805 req->r_request->hdr.tid = cpu_to_le64(req->r_tid); 819 req->r_request->hdr.tid = cpu_to_le64(req->r_tid);
806 INIT_LIST_HEAD(&req->r_req_lru_item);
807
808 dout("__register_request %p tid %lld\n", req, req->r_tid); 820 dout("__register_request %p tid %lld\n", req, req->r_tid);
809 __insert_request(osdc, req); 821 __insert_request(osdc, req);
810 ceph_osdc_get_request(req); 822 ceph_osdc_get_request(req);
811 osdc->num_requests++; 823 osdc->num_requests++;
812
813 if (osdc->num_requests == 1) { 824 if (osdc->num_requests == 1) {
814 dout(" first request, scheduling timeout\n"); 825 dout(" first request, scheduling timeout\n");
815 __schedule_osd_timeout(osdc); 826 __schedule_osd_timeout(osdc);
@@ -1085,9 +1096,15 @@ static void handle_timeout(struct work_struct *work)
1085 req = list_entry(osdc->req_lru.next, struct ceph_osd_request, 1096 req = list_entry(osdc->req_lru.next, struct ceph_osd_request,
1086 r_req_lru_item); 1097 r_req_lru_item);
1087 1098
1099 /* hasn't been long enough since we sent it? */
1088 if (time_before(jiffies, req->r_stamp + timeout)) 1100 if (time_before(jiffies, req->r_stamp + timeout))
1089 break; 1101 break;
1090 1102
1103 /* hasn't been long enough since it was acked? */
1104 if (req->r_request->ack_stamp == 0 ||
1105 time_before(jiffies, req->r_request->ack_stamp + timeout))
1106 break;
1107
1091 BUG_ON(req == last_req && req->r_stamp == last_stamp); 1108 BUG_ON(req == last_req && req->r_stamp == last_stamp);
1092 last_req = req; 1109 last_req = req;
1093 last_stamp = req->r_stamp; 1110 last_stamp = req->r_stamp;
@@ -1138,7 +1155,7 @@ static void handle_osds_timeout(struct work_struct *work)
1138 1155
1139 dout("osds timeout\n"); 1156 dout("osds timeout\n");
1140 down_read(&osdc->map_sem); 1157 down_read(&osdc->map_sem);
1141 remove_old_osds(osdc, 0); 1158 remove_old_osds(osdc);
1142 up_read(&osdc->map_sem); 1159 up_read(&osdc->map_sem);
1143 1160
1144 schedule_delayed_work(&osdc->osds_timeout_work, 1161 schedule_delayed_work(&osdc->osds_timeout_work,
@@ -1856,8 +1873,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc)
1856 ceph_osdmap_destroy(osdc->osdmap); 1873 ceph_osdmap_destroy(osdc->osdmap);
1857 osdc->osdmap = NULL; 1874 osdc->osdmap = NULL;
1858 } 1875 }
1859 remove_old_osds(osdc, 1); 1876 remove_all_osds(osdc);
1860 WARN_ON(!RB_EMPTY_ROOT(&osdc->osds));
1861 mempool_destroy(osdc->req_mempool); 1877 mempool_destroy(osdc->req_mempool);
1862 ceph_msgpool_destroy(&osdc->msgpool_op); 1878 ceph_msgpool_destroy(&osdc->msgpool_op);
1863 ceph_msgpool_destroy(&osdc->msgpool_op_reply); 1879 ceph_msgpool_destroy(&osdc->msgpool_op_reply);