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. |