diff options
| -rw-r--r-- | fs/ceph/osd_client.c | 19 | ||||
| -rw-r--r-- | fs/ceph/osd_client.h | 2 | ||||
| -rw-r--r-- | fs/ceph/osdmap.c | 29 | ||||
| -rw-r--r-- | fs/ceph/osdmap.h | 2 | ||||
| -rw-r--r-- | fs/ceph/rados.h | 1 |
5 files changed, 44 insertions, 9 deletions
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 8128082a028e..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; |
diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index c5191d62f243..ce776989ef6a 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h | |||
| @@ -48,6 +48,8 @@ struct ceph_osd_request { | |||
| 48 | struct list_head r_osd_item; | 48 | struct list_head r_osd_item; |
| 49 | struct ceph_osd *r_osd; | 49 | struct ceph_osd *r_osd; |
| 50 | struct ceph_pg r_pgid; | 50 | struct ceph_pg r_pgid; |
| 51 | int r_pg_osds[CEPH_PG_MAX_SIZE]; | ||
| 52 | int r_num_pg_osds; | ||
| 51 | 53 | ||
| 52 | struct ceph_connection *r_con_filling_msg; | 54 | struct ceph_connection *r_con_filling_msg; |
| 53 | 55 | ||
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 2e2c15eed82a..cfdd8f4388b7 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
| @@ -1041,12 +1041,33 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | |||
| 1041 | } | 1041 | } |
| 1042 | 1042 | ||
| 1043 | /* | 1043 | /* |
| 1044 | * Return acting set for given pgid. | ||
| 1045 | */ | ||
| 1046 | int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | ||
| 1047 | int *acting) | ||
| 1048 | { | ||
| 1049 | int rawosds[CEPH_PG_MAX_SIZE], *osds; | ||
| 1050 | int i, o, num = CEPH_PG_MAX_SIZE; | ||
| 1051 | |||
| 1052 | osds = calc_pg_raw(osdmap, pgid, rawosds, &num); | ||
| 1053 | if (!osds) | ||
| 1054 | return -1; | ||
| 1055 | |||
| 1056 | /* primary is first up osd */ | ||
| 1057 | o = 0; | ||
| 1058 | for (i = 0; i < num; i++) | ||
| 1059 | if (ceph_osd_is_up(osdmap, osds[i])) | ||
| 1060 | acting[o++] = osds[i]; | ||
| 1061 | return o; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | /* | ||
| 1044 | * Return primary osd for given pgid, or -1 if none. | 1065 | * Return primary osd for given pgid, or -1 if none. |
| 1045 | */ | 1066 | */ |
| 1046 | int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) | 1067 | int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) |
| 1047 | { | 1068 | { |
| 1048 | int rawosds[10], *osds; | 1069 | int rawosds[CEPH_PG_MAX_SIZE], *osds; |
| 1049 | int i, num = ARRAY_SIZE(rawosds); | 1070 | int i, num = CEPH_PG_MAX_SIZE; |
| 1050 | 1071 | ||
| 1051 | osds = calc_pg_raw(osdmap, pgid, rawosds, &num); | 1072 | osds = calc_pg_raw(osdmap, pgid, rawosds, &num); |
| 1052 | if (!osds) | 1073 | if (!osds) |
| @@ -1054,9 +1075,7 @@ int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) | |||
| 1054 | 1075 | ||
| 1055 | /* primary is first up osd */ | 1076 | /* primary is first up osd */ |
| 1056 | for (i = 0; i < num; i++) | 1077 | for (i = 0; i < num; i++) |
| 1057 | if (ceph_osd_is_up(osdmap, osds[i])) { | 1078 | if (ceph_osd_is_up(osdmap, osds[i])) |
| 1058 | return osds[i]; | 1079 | return osds[i]; |
| 1059 | break; | ||
| 1060 | } | ||
| 1061 | return -1; | 1080 | return -1; |
| 1062 | } | 1081 | } |
diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 8bc9f1e4f562..970b547e510d 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h | |||
| @@ -120,6 +120,8 @@ extern int ceph_calc_object_layout(struct ceph_object_layout *ol, | |||
| 120 | const char *oid, | 120 | const char *oid, |
| 121 | struct ceph_file_layout *fl, | 121 | struct ceph_file_layout *fl, |
| 122 | struct ceph_osdmap *osdmap); | 122 | struct ceph_osdmap *osdmap); |
| 123 | extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | ||
| 124 | int *acting); | ||
| 123 | extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, | 125 | extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, |
| 124 | struct ceph_pg pgid); | 126 | struct ceph_pg pgid); |
| 125 | 127 | ||
diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index a1fc1d017b58..fd56451a871f 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h | |||
| @@ -58,6 +58,7 @@ struct ceph_timespec { | |||
| 58 | #define CEPH_PG_LAYOUT_LINEAR 2 | 58 | #define CEPH_PG_LAYOUT_LINEAR 2 |
| 59 | #define CEPH_PG_LAYOUT_HYBRID 3 | 59 | #define CEPH_PG_LAYOUT_HYBRID 3 |
| 60 | 60 | ||
| 61 | #define CEPH_PG_MAX_SIZE 16 /* max # osds in a single pg */ | ||
| 61 | 62 | ||
| 62 | /* | 63 | /* |
| 63 | * placement group. | 64 | * placement group. |
