|
@@ -565,7 +565,8 @@ static int __map_osds(struct ceph_osd_client *osdc,
|
|
|
{
|
|
|
struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
|
|
|
struct ceph_pg pgid;
|
|
|
- int o = -1;
|
|
|
+ int acting[CEPH_PG_MAX_SIZE];
|
|
|
+ int o = -1, num = 0;
|
|
|
int err;
|
|
|
|
|
|
dout("map_osds %p tid %lld\n", req, req->r_tid);
|
|
@@ -576,10 +577,16 @@ static int __map_osds(struct ceph_osd_client *osdc,
|
|
|
pgid = reqhead->layout.ol_pgid;
|
|
|
req->r_pgid = pgid;
|
|
|
|
|
|
- o = ceph_calc_pg_primary(osdc->osdmap, pgid);
|
|
|
+ err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting);
|
|
|
+ if (err > 0) {
|
|
|
+ o = acting[0];
|
|
|
+ num = err;
|
|
|
+ }
|
|
|
|
|
|
if ((req->r_osd && req->r_osd->o_osd == o &&
|
|
|
- req->r_sent >= req->r_osd->o_incarnation) ||
|
|
|
+ req->r_sent >= req->r_osd->o_incarnation &&
|
|
|
+ req->r_num_pg_osds == num &&
|
|
|
+ memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
|
|
|
(req->r_osd == NULL && o == -1))
|
|
|
return 0; /* no change */
|
|
|
|
|
@@ -587,6 +594,10 @@ static int __map_osds(struct ceph_osd_client *osdc,
|
|
|
req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o,
|
|
|
req->r_osd ? req->r_osd->o_osd : -1);
|
|
|
|
|
|
+ /* record full pg acting set */
|
|
|
+ memcpy(req->r_pg_osds, acting, sizeof(acting[0]) * num);
|
|
|
+ req->r_num_pg_osds = num;
|
|
|
+
|
|
|
if (req->r_osd) {
|
|
|
__cancel_request(req);
|
|
|
list_del_init(&req->r_osd_item);
|
|
@@ -612,7 +623,7 @@ static int __map_osds(struct ceph_osd_client *osdc,
|
|
|
__remove_osd_from_lru(req->r_osd);
|
|
|
list_add(&req->r_osd_item, &req->r_osd->o_requests);
|
|
|
}
|
|
|
- err = 1; /* osd changed */
|
|
|
+ err = 1; /* osd or pg changed */
|
|
|
|
|
|
out:
|
|
|
return err;
|
|
@@ -779,16 +790,18 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
|
|
|
struct ceph_osd_request *req;
|
|
|
u64 tid;
|
|
|
int numops, object_len, flags;
|
|
|
+ s32 result;
|
|
|
|
|
|
tid = le64_to_cpu(msg->hdr.tid);
|
|
|
if (msg->front.iov_len < sizeof(*rhead))
|
|
|
goto bad;
|
|
|
numops = le32_to_cpu(rhead->num_ops);
|
|
|
object_len = le32_to_cpu(rhead->object_len);
|
|
|
+ result = le32_to_cpu(rhead->result);
|
|
|
if (msg->front.iov_len != sizeof(*rhead) + object_len +
|
|
|
numops * sizeof(struct ceph_osd_op))
|
|
|
goto bad;
|
|
|
- dout("handle_reply %p tid %llu\n", msg, tid);
|
|
|
+ dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result);
|
|
|
|
|
|
/* lookup */
|
|
|
mutex_lock(&osdc->request_mutex);
|
|
@@ -834,7 +847,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
|
|
|
dout("handle_reply tid %llu flags %d\n", tid, flags);
|
|
|
|
|
|
/* either this is a read, or we got the safe response */
|
|
|
- if ((flags & CEPH_OSD_FLAG_ONDISK) ||
|
|
|
+ if (result < 0 ||
|
|
|
+ (flags & CEPH_OSD_FLAG_ONDISK) ||
|
|
|
((flags & CEPH_OSD_FLAG_WRITE) == 0))
|
|
|
__unregister_request(osdc, req);
|
|
|
|