diff options
author | Sage Weil <sage@newdream.net> | 2009-10-08 19:57:16 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2009-10-09 14:58:07 -0400 |
commit | 0ba6478df7c6bef0f4b2625554545f941f89fb97 (patch) | |
tree | 2b99864e80174ab56cb0d0b42669e45e2c9d86cd /fs/ceph/osd_client.c | |
parent | c1ea8823be69ebebaface912142190e910711984 (diff) |
ceph: revoke osd request message on request completion
If an osd has failed or returned and a request has been sent twice, it's
possible to get a reply and unregister the request while the request
message is queued for delivery. Since the message references the caller's
page vector, we need to revoke it before completing.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/osd_client.c')
-rw-r--r-- | fs/ceph/osd_client.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d14019dd6868..0aea8afaa072 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
@@ -469,10 +469,15 @@ static void __unregister_request(struct ceph_osd_client *osdc, | |||
469 | rb_erase(&req->r_node, &osdc->requests); | 469 | rb_erase(&req->r_node, &osdc->requests); |
470 | osdc->num_requests--; | 470 | osdc->num_requests--; |
471 | 471 | ||
472 | list_del_init(&req->r_osd_item); | 472 | if (req->r_osd) { |
473 | if (list_empty(&req->r_osd->o_requests)) | 473 | /* make sure the original request isn't in flight. */ |
474 | remove_osd(osdc, req->r_osd); | 474 | ceph_con_revoke(&req->r_osd->o_con, req->r_request); |
475 | req->r_osd = NULL; | 475 | |
476 | list_del_init(&req->r_osd_item); | ||
477 | if (list_empty(&req->r_osd->o_requests)) | ||
478 | remove_osd(osdc, req->r_osd); | ||
479 | req->r_osd = NULL; | ||
480 | } | ||
476 | 481 | ||
477 | ceph_osdc_put_request(req); | 482 | ceph_osdc_put_request(req); |
478 | 483 | ||