aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2017-06-15 10:30:55 -0400
committerIlya Dryomov <idryomov@gmail.com>2017-07-07 11:25:16 -0400
commit04c7d789e269c2b82bbd08106049a5a979cdb3fd (patch)
treedb72e960611bfbcffe75d0a5a0efff8642cc3eb6
parenta10bcb19ae02cea7d5e6650fbc2de3ced46b4e5d (diff)
libceph: make sure need_resend targets reflect latest map
Otherwise we may miss events like PG splits, pool deletions, etc when we get multiple incremental maps at once. Because check_pool_dne() can now be fed an unlinked request, finish_request() needed to be taught to handle unlinked requests. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--include/linux/ceph/osd_client.h1
-rw-r--r--net/ceph/debugfs.c2
-rw-r--r--net/ceph/osd_client.c33
3 files changed, 27 insertions, 9 deletions
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index bca2718ac253..62c672bcbb31 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -149,6 +149,7 @@ struct ceph_osd_request_target {
149 unsigned int flags; /* CEPH_OSD_FLAG_* */ 149 unsigned int flags; /* CEPH_OSD_FLAG_* */
150 bool paused; 150 bool paused;
151 151
152 u32 epoch;
152 u32 last_force_resend; 153 u32 last_force_resend;
153 154
154 int osd; 155 int osd;
diff --git a/net/ceph/debugfs.c b/net/ceph/debugfs.c
index 50ab1bdb16e2..c0089f8ccaeb 100644
--- a/net/ceph/debugfs.c
+++ b/net/ceph/debugfs.c
@@ -166,7 +166,7 @@ static void dump_target(struct seq_file *s, struct ceph_osd_request_target *t)
166 seq_printf(s, "]/%d\t[", t->up.primary); 166 seq_printf(s, "]/%d\t[", t->up.primary);
167 for (i = 0; i < t->acting.size; i++) 167 for (i = 0; i < t->acting.size; i++)
168 seq_printf(s, "%s%d", (!i ? "" : ","), t->acting.osds[i]); 168 seq_printf(s, "%s%d", (!i ? "" : ","), t->acting.osds[i]);
169 seq_printf(s, "]/%d\t", t->acting.primary); 169 seq_printf(s, "]/%d\te%u\t", t->acting.primary, t->epoch);
170 if (t->target_oloc.pool_ns) { 170 if (t->target_oloc.pool_ns) {
171 seq_printf(s, "%*pE/%*pE\t0x%x", 171 seq_printf(s, "%*pE/%*pE\t0x%x",
172 (int)t->target_oloc.pool_ns->len, 172 (int)t->target_oloc.pool_ns->len,
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 576101b635ef..173ab9c68eb6 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -386,6 +386,7 @@ static void target_copy(struct ceph_osd_request_target *dest,
386 dest->flags = src->flags; 386 dest->flags = src->flags;
387 dest->paused = src->paused; 387 dest->paused = src->paused;
388 388
389 dest->epoch = src->epoch;
389 dest->last_force_resend = src->last_force_resend; 390 dest->last_force_resend = src->last_force_resend;
390 391
391 dest->osd = src->osd; 392 dest->osd = src->osd;
@@ -1334,6 +1335,7 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc,
1334 enum calc_target_result ct_res; 1335 enum calc_target_result ct_res;
1335 int ret; 1336 int ret;
1336 1337
1338 t->epoch = osdc->osdmap->epoch;
1337 pi = ceph_pg_pool_by_id(osdc->osdmap, t->base_oloc.pool); 1339 pi = ceph_pg_pool_by_id(osdc->osdmap, t->base_oloc.pool);
1338 if (!pi) { 1340 if (!pi) {
1339 t->osd = CEPH_HOMELESS_OSD; 1341 t->osd = CEPH_HOMELESS_OSD;
@@ -1720,10 +1722,11 @@ static void send_request(struct ceph_osd_request *req)
1720 1722
1721 encode_request_partial(req, req->r_request); 1723 encode_request_partial(req, req->r_request);
1722 1724
1723 dout("%s req %p tid %llu to pgid %llu.%x spgid %llu.%xs%d osd%d flags 0x%x attempt %d\n", 1725 dout("%s req %p tid %llu to pgid %llu.%x spgid %llu.%xs%d osd%d e%u flags 0x%x attempt %d\n",
1724 __func__, req, req->r_tid, req->r_t.pgid.pool, req->r_t.pgid.seed, 1726 __func__, req, req->r_tid, req->r_t.pgid.pool, req->r_t.pgid.seed,
1725 req->r_t.spgid.pgid.pool, req->r_t.spgid.pgid.seed, 1727 req->r_t.spgid.pgid.pool, req->r_t.spgid.pgid.seed,
1726 req->r_t.spgid.shard, osd->o_osd, req->r_flags, req->r_attempts); 1728 req->r_t.spgid.shard, osd->o_osd, req->r_t.epoch, req->r_flags,
1729 req->r_attempts);
1727 1730
1728 req->r_t.paused = false; 1731 req->r_t.paused = false;
1729 req->r_stamp = jiffies; 1732 req->r_stamp = jiffies;
@@ -1863,13 +1866,12 @@ static void submit_request(struct ceph_osd_request *req, bool wrlocked)
1863static void finish_request(struct ceph_osd_request *req) 1866static void finish_request(struct ceph_osd_request *req)
1864{ 1867{
1865 struct ceph_osd_client *osdc = req->r_osdc; 1868 struct ceph_osd_client *osdc = req->r_osdc;
1866 struct ceph_osd *osd = req->r_osd;
1867 1869
1868 verify_osd_locked(osd); 1870 WARN_ON(lookup_request_mc(&osdc->map_checks, req->r_tid));
1869 dout("%s req %p tid %llu\n", __func__, req, req->r_tid); 1871 dout("%s req %p tid %llu\n", __func__, req, req->r_tid);
1870 1872
1871 WARN_ON(lookup_request_mc(&osdc->map_checks, req->r_tid)); 1873 if (req->r_osd)
1872 unlink_request(osd, req); 1874 unlink_request(req->r_osd, req);
1873 atomic_dec(&osdc->num_requests); 1875 atomic_dec(&osdc->num_requests);
1874 1876
1875 /* 1877 /*
@@ -3356,8 +3358,25 @@ static void kick_requests(struct ceph_osd_client *osdc,
3356 struct list_head *need_resend_linger) 3358 struct list_head *need_resend_linger)
3357{ 3359{
3358 struct ceph_osd_linger_request *lreq, *nlreq; 3360 struct ceph_osd_linger_request *lreq, *nlreq;
3361 enum calc_target_result ct_res;
3359 struct rb_node *n; 3362 struct rb_node *n;
3360 3363
3364 /* make sure need_resend targets reflect latest map */
3365 for (n = rb_first(need_resend); n; ) {
3366 struct ceph_osd_request *req =
3367 rb_entry(n, struct ceph_osd_request, r_node);
3368
3369 n = rb_next(n);
3370
3371 if (req->r_t.epoch < osdc->osdmap->epoch) {
3372 ct_res = calc_target(osdc, &req->r_t, NULL, false);
3373 if (ct_res == CALC_TARGET_POOL_DNE) {
3374 erase_request(need_resend, req);
3375 check_pool_dne(req);
3376 }
3377 }
3378 }
3379
3361 for (n = rb_first(need_resend); n; ) { 3380 for (n = rb_first(need_resend); n; ) {
3362 struct ceph_osd_request *req = 3381 struct ceph_osd_request *req =
3363 rb_entry(n, struct ceph_osd_request, r_node); 3382 rb_entry(n, struct ceph_osd_request, r_node);
@@ -3366,8 +3385,6 @@ static void kick_requests(struct ceph_osd_client *osdc,
3366 n = rb_next(n); 3385 n = rb_next(n);
3367 erase_request(need_resend, req); /* before link_request() */ 3386 erase_request(need_resend, req); /* before link_request() */
3368 3387
3369 WARN_ON(req->r_osd);
3370 calc_target(osdc, &req->r_t, NULL, false);
3371 osd = lookup_create_osd(osdc, req->r_t.osd, true); 3388 osd = lookup_create_osd(osdc, req->r_t.osd, true);
3372 link_request(osd, req); 3389 link_request(osd, req);
3373 if (!req->r_linger) { 3390 if (!req->r_linger) {