aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osd_client.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-10-14 16:33:55 -0400
committerSage Weil <sage@newdream.net>2011-10-25 19:10:17 -0400
commit38d6453ca39ecce442628a93e1bb46d70d547512 (patch)
tree7113a921788a83987e2e561e28eefbecd3733d5a /net/ceph/osd_client.c
parentee3b56f265cafb28c9a1b58faed4f1dbdf51af86 (diff)
libceph: force resend of osd requests if we skip an osdmap
If we skip over one or more map epochs, we need to resend all osd requests because it is possible they remapped to other servers and then back. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'net/ceph/osd_client.c')
-rw-r--r--net/ceph/osd_client.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 01ceb59a8b4a..733e46008b89 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -943,7 +943,7 @@ EXPORT_SYMBOL(ceph_osdc_set_request_linger);
943 * Caller should hold map_sem for read and request_mutex. 943 * Caller should hold map_sem for read and request_mutex.
944 */ 944 */
945static int __map_request(struct ceph_osd_client *osdc, 945static int __map_request(struct ceph_osd_client *osdc,
946 struct ceph_osd_request *req) 946 struct ceph_osd_request *req, int force_resend)
947{ 947{
948 struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; 948 struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
949 struct ceph_pg pgid; 949 struct ceph_pg pgid;
@@ -967,7 +967,8 @@ static int __map_request(struct ceph_osd_client *osdc,
967 num = err; 967 num = err;
968 } 968 }
969 969
970 if ((req->r_osd && req->r_osd->o_osd == o && 970 if ((!force_resend &&
971 req->r_osd && req->r_osd->o_osd == o &&
971 req->r_sent >= req->r_osd->o_incarnation && 972 req->r_sent >= req->r_osd->o_incarnation &&
972 req->r_num_pg_osds == num && 973 req->r_num_pg_osds == num &&
973 memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) || 974 memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
@@ -1289,18 +1290,18 @@ static void reset_changed_osds(struct ceph_osd_client *osdc)
1289 * 1290 *
1290 * Caller should hold map_sem for read and request_mutex. 1291 * Caller should hold map_sem for read and request_mutex.
1291 */ 1292 */
1292static void kick_requests(struct ceph_osd_client *osdc) 1293static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
1293{ 1294{
1294 struct ceph_osd_request *req, *nreq; 1295 struct ceph_osd_request *req, *nreq;
1295 struct rb_node *p; 1296 struct rb_node *p;
1296 int needmap = 0; 1297 int needmap = 0;
1297 int err; 1298 int err;
1298 1299
1299 dout("kick_requests\n"); 1300 dout("kick_requests %s\n", force_resend ? " (force resend)" : "");
1300 mutex_lock(&osdc->request_mutex); 1301 mutex_lock(&osdc->request_mutex);
1301 for (p = rb_first(&osdc->requests); p; p = rb_next(p)) { 1302 for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
1302 req = rb_entry(p, struct ceph_osd_request, r_node); 1303 req = rb_entry(p, struct ceph_osd_request, r_node);
1303 err = __map_request(osdc, req); 1304 err = __map_request(osdc, req, force_resend);
1304 if (err < 0) 1305 if (err < 0)
1305 continue; /* error */ 1306 continue; /* error */
1306 if (req->r_osd == NULL) { 1307 if (req->r_osd == NULL) {
@@ -1318,7 +1319,7 @@ static void kick_requests(struct ceph_osd_client *osdc)
1318 r_linger_item) { 1319 r_linger_item) {
1319 dout("linger req=%p req->r_osd=%p\n", req, req->r_osd); 1320 dout("linger req=%p req->r_osd=%p\n", req, req->r_osd);
1320 1321
1321 err = __map_request(osdc, req); 1322 err = __map_request(osdc, req, force_resend);
1322 if (err == 0) 1323 if (err == 0)
1323 continue; /* no change and no osd was specified */ 1324 continue; /* no change and no osd was specified */
1324 if (err < 0) 1325 if (err < 0)
@@ -1395,7 +1396,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1395 ceph_osdmap_destroy(osdc->osdmap); 1396 ceph_osdmap_destroy(osdc->osdmap);
1396 osdc->osdmap = newmap; 1397 osdc->osdmap = newmap;
1397 } 1398 }
1398 kick_requests(osdc); 1399 kick_requests(osdc, 0);
1399 reset_changed_osds(osdc); 1400 reset_changed_osds(osdc);
1400 } else { 1401 } else {
1401 dout("ignoring incremental map %u len %d\n", 1402 dout("ignoring incremental map %u len %d\n",
@@ -1423,6 +1424,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1423 "older than our %u\n", epoch, maplen, 1424 "older than our %u\n", epoch, maplen,
1424 osdc->osdmap->epoch); 1425 osdc->osdmap->epoch);
1425 } else { 1426 } else {
1427 int skipped_map = 0;
1428
1426 dout("taking full map %u len %d\n", epoch, maplen); 1429 dout("taking full map %u len %d\n", epoch, maplen);
1427 newmap = osdmap_decode(&p, p+maplen); 1430 newmap = osdmap_decode(&p, p+maplen);
1428 if (IS_ERR(newmap)) { 1431 if (IS_ERR(newmap)) {
@@ -1432,9 +1435,12 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1432 BUG_ON(!newmap); 1435 BUG_ON(!newmap);
1433 oldmap = osdc->osdmap; 1436 oldmap = osdc->osdmap;
1434 osdc->osdmap = newmap; 1437 osdc->osdmap = newmap;
1435 if (oldmap) 1438 if (oldmap) {
1439 if (oldmap->epoch + 1 < newmap->epoch)
1440 skipped_map = 1;
1436 ceph_osdmap_destroy(oldmap); 1441 ceph_osdmap_destroy(oldmap);
1437 kick_requests(osdc); 1442 }
1443 kick_requests(osdc, skipped_map);
1438 } 1444 }
1439 p += maplen; 1445 p += maplen;
1440 nr_maps--; 1446 nr_maps--;
@@ -1707,7 +1713,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1707 * the request still han't been touched yet. 1713 * the request still han't been touched yet.
1708 */ 1714 */
1709 if (req->r_sent == 0) { 1715 if (req->r_sent == 0) {
1710 rc = __map_request(osdc, req); 1716 rc = __map_request(osdc, req, 0);
1711 if (rc < 0) { 1717 if (rc < 0) {
1712 if (nofail) { 1718 if (nofail) {
1713 dout("osdc_start_request failed map, " 1719 dout("osdc_start_request failed map, "