diff options
Diffstat (limited to 'fs/ceph/osd_client.c')
| -rw-r--r-- | fs/ceph/osd_client.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index c7b4dedaace6..3514f71ff85f 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
| @@ -565,7 +565,8 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 565 | { | 565 | { |
| 566 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; | 566 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; |
| 567 | struct ceph_pg pgid; | 567 | struct ceph_pg pgid; |
| 568 | int o = -1; | 568 | int acting[CEPH_PG_MAX_SIZE]; |
| 569 | int o = -1, num = 0; | ||
| 569 | int err; | 570 | int err; |
| 570 | 571 | ||
| 571 | dout("map_osds %p tid %lld\n", req, req->r_tid); | 572 | dout("map_osds %p tid %lld\n", req, req->r_tid); |
| @@ -576,10 +577,16 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 576 | pgid = reqhead->layout.ol_pgid; | 577 | pgid = reqhead->layout.ol_pgid; |
| 577 | req->r_pgid = pgid; | 578 | req->r_pgid = pgid; |
| 578 | 579 | ||
| 579 | o = ceph_calc_pg_primary(osdc->osdmap, pgid); | 580 | err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting); |
| 581 | if (err > 0) { | ||
| 582 | o = acting[0]; | ||
| 583 | num = err; | ||
| 584 | } | ||
| 580 | 585 | ||
| 581 | if ((req->r_osd && req->r_osd->o_osd == o && | 586 | if ((req->r_osd && req->r_osd->o_osd == o && |
| 582 | req->r_sent >= req->r_osd->o_incarnation) || | 587 | req->r_sent >= req->r_osd->o_incarnation && |
| 588 | req->r_num_pg_osds == num && | ||
| 589 | memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) || | ||
| 583 | (req->r_osd == NULL && o == -1)) | 590 | (req->r_osd == NULL && o == -1)) |
| 584 | return 0; /* no change */ | 591 | return 0; /* no change */ |
| 585 | 592 | ||
| @@ -587,6 +594,10 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 587 | req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o, | 594 | req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o, |
| 588 | req->r_osd ? req->r_osd->o_osd : -1); | 595 | req->r_osd ? req->r_osd->o_osd : -1); |
| 589 | 596 | ||
| 597 | /* record full pg acting set */ | ||
| 598 | memcpy(req->r_pg_osds, acting, sizeof(acting[0]) * num); | ||
| 599 | req->r_num_pg_osds = num; | ||
| 600 | |||
| 590 | if (req->r_osd) { | 601 | if (req->r_osd) { |
| 591 | __cancel_request(req); | 602 | __cancel_request(req); |
| 592 | list_del_init(&req->r_osd_item); | 603 | list_del_init(&req->r_osd_item); |
| @@ -612,7 +623,7 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 612 | __remove_osd_from_lru(req->r_osd); | 623 | __remove_osd_from_lru(req->r_osd); |
| 613 | list_add(&req->r_osd_item, &req->r_osd->o_requests); | 624 | list_add(&req->r_osd_item, &req->r_osd->o_requests); |
| 614 | } | 625 | } |
| 615 | err = 1; /* osd changed */ | 626 | err = 1; /* osd or pg changed */ |
| 616 | 627 | ||
| 617 | out: | 628 | out: |
| 618 | return err; | 629 | return err; |
| @@ -779,16 +790,18 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 779 | struct ceph_osd_request *req; | 790 | struct ceph_osd_request *req; |
| 780 | u64 tid; | 791 | u64 tid; |
| 781 | int numops, object_len, flags; | 792 | int numops, object_len, flags; |
| 793 | s32 result; | ||
| 782 | 794 | ||
| 783 | tid = le64_to_cpu(msg->hdr.tid); | 795 | tid = le64_to_cpu(msg->hdr.tid); |
| 784 | if (msg->front.iov_len < sizeof(*rhead)) | 796 | if (msg->front.iov_len < sizeof(*rhead)) |
| 785 | goto bad; | 797 | goto bad; |
| 786 | numops = le32_to_cpu(rhead->num_ops); | 798 | numops = le32_to_cpu(rhead->num_ops); |
| 787 | object_len = le32_to_cpu(rhead->object_len); | 799 | object_len = le32_to_cpu(rhead->object_len); |
| 800 | result = le32_to_cpu(rhead->result); | ||
| 788 | if (msg->front.iov_len != sizeof(*rhead) + object_len + | 801 | if (msg->front.iov_len != sizeof(*rhead) + object_len + |
| 789 | numops * sizeof(struct ceph_osd_op)) | 802 | numops * sizeof(struct ceph_osd_op)) |
| 790 | goto bad; | 803 | goto bad; |
| 791 | dout("handle_reply %p tid %llu\n", msg, tid); | 804 | dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result); |
| 792 | 805 | ||
| 793 | /* lookup */ | 806 | /* lookup */ |
| 794 | mutex_lock(&osdc->request_mutex); | 807 | mutex_lock(&osdc->request_mutex); |
| @@ -834,7 +847,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 834 | dout("handle_reply tid %llu flags %d\n", tid, flags); | 847 | dout("handle_reply tid %llu flags %d\n", tid, flags); |
| 835 | 848 | ||
| 836 | /* either this is a read, or we got the safe response */ | 849 | /* either this is a read, or we got the safe response */ |
| 837 | if ((flags & CEPH_OSD_FLAG_ONDISK) || | 850 | if (result < 0 || |
| 851 | (flags & CEPH_OSD_FLAG_ONDISK) || | ||
| 838 | ((flags & CEPH_OSD_FLAG_WRITE) == 0)) | 852 | ((flags & CEPH_OSD_FLAG_WRITE) == 0)) |
| 839 | __unregister_request(osdc, req); | 853 | __unregister_request(osdc, req); |
| 840 | 854 | ||
