aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 19:42:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 19:42:18 -0400
commit97d2eb13a019ec09cc1a7ea2d3705c0b117b3c0d (patch)
tree86f6382941f8cfc41647d33d87bec7bc1407c18c /net
parent68d99b2c8efcb6ed3807a55569300c53b5f88be5 (diff)
parent339573406737461cfb17bebabf7ba536a302d841 (diff)
Merge branch 'for-linus' of git://ceph.newdream.net/git/ceph-client
* 'for-linus' of git://ceph.newdream.net/git/ceph-client: libceph: fix double-free of page vector ceph: fix 32-bit ino numbers libceph: force resend of osd requests if we skip an osdmap ceph: use kernel DNS resolver ceph: fix ceph_monc_init memory leak ceph: let the set_layout ioctl set single traits Revert "ceph: don't truncate dirty pages in invalidate work thread" ceph: replace leading spaces with tabs libceph: warn on msg allocation failures libceph: don't complain on msgpool alloc failures libceph: always preallocate mon connection libceph: create messenger with client ceph: document ioctls ceph: implement (optional) max read size ceph: rename rsize -> rasize ceph: make readpages fully async
Diffstat (limited to 'net')
-rw-r--r--net/ceph/Kconfig14
-rw-r--r--net/ceph/ceph_common.c47
-rw-r--r--net/ceph/messenger.c130
-rw-r--r--net/ceph/mon_client.c79
-rw-r--r--net/ceph/msgpool.c4
-rw-r--r--net/ceph/osd_client.c34
6 files changed, 217 insertions, 91 deletions
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
index be683f2d401f..cc04dd667a10 100644
--- a/net/ceph/Kconfig
+++ b/net/ceph/Kconfig
@@ -27,3 +27,17 @@ config CEPH_LIB_PRETTYDEBUG
27 27
28 If unsure, say N. 28 If unsure, say N.
29 29
30config CEPH_LIB_USE_DNS_RESOLVER
31 bool "Use in-kernel support for DNS lookup"
32 depends on CEPH_LIB
33 select DNS_RESOLVER
34 default n
35 help
36 If you say Y here, hostnames (e.g. monitor addresses) will
37 be resolved using the CONFIG_DNS_RESOLVER facility.
38
39 For information on how to use CONFIG_DNS_RESOLVER consult
40 Documentation/networking/dns_resolver.txt
41
42 If unsure, say N.
43
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 2883ea01e680..97f70e50ad3b 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -432,9 +432,12 @@ EXPORT_SYMBOL(ceph_client_id);
432/* 432/*
433 * create a fresh client instance 433 * create a fresh client instance
434 */ 434 */
435struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private) 435struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
436 unsigned supported_features,
437 unsigned required_features)
436{ 438{
437 struct ceph_client *client; 439 struct ceph_client *client;
440 struct ceph_entity_addr *myaddr = NULL;
438 int err = -ENOMEM; 441 int err = -ENOMEM;
439 442
440 client = kzalloc(sizeof(*client), GFP_KERNEL); 443 client = kzalloc(sizeof(*client), GFP_KERNEL);
@@ -449,15 +452,27 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
449 client->auth_err = 0; 452 client->auth_err = 0;
450 453
451 client->extra_mon_dispatch = NULL; 454 client->extra_mon_dispatch = NULL;
452 client->supported_features = CEPH_FEATURE_SUPPORTED_DEFAULT; 455 client->supported_features = CEPH_FEATURE_SUPPORTED_DEFAULT |
453 client->required_features = CEPH_FEATURE_REQUIRED_DEFAULT; 456 supported_features;
454 457 client->required_features = CEPH_FEATURE_REQUIRED_DEFAULT |
455 client->msgr = NULL; 458 required_features;
459
460 /* msgr */
461 if (ceph_test_opt(client, MYIP))
462 myaddr = &client->options->my_addr;
463 client->msgr = ceph_messenger_create(myaddr,
464 client->supported_features,
465 client->required_features);
466 if (IS_ERR(client->msgr)) {
467 err = PTR_ERR(client->msgr);
468 goto fail;
469 }
470 client->msgr->nocrc = ceph_test_opt(client, NOCRC);
456 471
457 /* subsystems */ 472 /* subsystems */
458 err = ceph_monc_init(&client->monc, client); 473 err = ceph_monc_init(&client->monc, client);
459 if (err < 0) 474 if (err < 0)
460 goto fail; 475 goto fail_msgr;
461 err = ceph_osdc_init(&client->osdc, client); 476 err = ceph_osdc_init(&client->osdc, client);
462 if (err < 0) 477 if (err < 0)
463 goto fail_monc; 478 goto fail_monc;
@@ -466,6 +481,8 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
466 481
467fail_monc: 482fail_monc:
468 ceph_monc_stop(&client->monc); 483 ceph_monc_stop(&client->monc);
484fail_msgr:
485 ceph_messenger_destroy(client->msgr);
469fail: 486fail:
470 kfree(client); 487 kfree(client);
471 return ERR_PTR(err); 488 return ERR_PTR(err);
@@ -490,8 +507,7 @@ void ceph_destroy_client(struct ceph_client *client)
490 507
491 ceph_debugfs_client_cleanup(client); 508 ceph_debugfs_client_cleanup(client);
492 509
493 if (client->msgr) 510 ceph_messenger_destroy(client->msgr);
494 ceph_messenger_destroy(client->msgr);
495 511
496 ceph_destroy_options(client->options); 512 ceph_destroy_options(client->options);
497 513
@@ -514,24 +530,9 @@ static int have_mon_and_osd_map(struct ceph_client *client)
514 */ 530 */
515int __ceph_open_session(struct ceph_client *client, unsigned long started) 531int __ceph_open_session(struct ceph_client *client, unsigned long started)
516{ 532{
517 struct ceph_entity_addr *myaddr = NULL;
518 int err; 533 int err;
519 unsigned long timeout = client->options->mount_timeout * HZ; 534 unsigned long timeout = client->options->mount_timeout * HZ;
520 535
521 /* initialize the messenger */
522 if (client->msgr == NULL) {
523 if (ceph_test_opt(client, MYIP))
524 myaddr = &client->options->my_addr;
525 client->msgr = ceph_messenger_create(myaddr,
526 client->supported_features,
527 client->required_features);
528 if (IS_ERR(client->msgr)) {
529 client->msgr = NULL;
530 return PTR_ERR(client->msgr);
531 }
532 client->msgr->nocrc = ceph_test_opt(client, NOCRC);
533 }
534
535 /* open session, and wait for mon and osd maps */ 536 /* open session, and wait for mon and osd maps */
536 err = ceph_monc_open_session(&client->monc); 537 err = ceph_monc_open_session(&client->monc);
537 if (err < 0) 538 if (err < 0)
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 9918e9eb276e..f466930e26fa 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -11,6 +11,7 @@
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/bio.h> 12#include <linux/bio.h>
13#include <linux/blkdev.h> 13#include <linux/blkdev.h>
14#include <linux/dns_resolver.h>
14#include <net/tcp.h> 15#include <net/tcp.h>
15 16
16#include <linux/ceph/libceph.h> 17#include <linux/ceph/libceph.h>
@@ -1078,6 +1079,101 @@ static void addr_set_port(struct sockaddr_storage *ss, int p)
1078} 1079}
1079 1080
1080/* 1081/*
1082 * Unlike other *_pton function semantics, zero indicates success.
1083 */
1084static int ceph_pton(const char *str, size_t len, struct sockaddr_storage *ss,
1085 char delim, const char **ipend)
1086{
1087 struct sockaddr_in *in4 = (void *)ss;
1088 struct sockaddr_in6 *in6 = (void *)ss;
1089
1090 memset(ss, 0, sizeof(*ss));
1091
1092 if (in4_pton(str, len, (u8 *)&in4->sin_addr.s_addr, delim, ipend)) {
1093 ss->ss_family = AF_INET;
1094 return 0;
1095 }
1096
1097 if (in6_pton(str, len, (u8 *)&in6->sin6_addr.s6_addr, delim, ipend)) {
1098 ss->ss_family = AF_INET6;
1099 return 0;
1100 }
1101
1102 return -EINVAL;
1103}
1104
1105/*
1106 * Extract hostname string and resolve using kernel DNS facility.
1107 */
1108#ifdef CONFIG_CEPH_LIB_USE_DNS_RESOLVER
1109static int ceph_dns_resolve_name(const char *name, size_t namelen,
1110 struct sockaddr_storage *ss, char delim, const char **ipend)
1111{
1112 const char *end, *delim_p;
1113 char *colon_p, *ip_addr = NULL;
1114 int ip_len, ret;
1115
1116 /*
1117 * The end of the hostname occurs immediately preceding the delimiter or
1118 * the port marker (':') where the delimiter takes precedence.
1119 */
1120 delim_p = memchr(name, delim, namelen);
1121 colon_p = memchr(name, ':', namelen);
1122
1123 if (delim_p && colon_p)
1124 end = delim_p < colon_p ? delim_p : colon_p;
1125 else if (!delim_p && colon_p)
1126 end = colon_p;
1127 else {
1128 end = delim_p;
1129 if (!end) /* case: hostname:/ */
1130 end = name + namelen;
1131 }
1132
1133 if (end <= name)
1134 return -EINVAL;
1135
1136 /* do dns_resolve upcall */
1137 ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL);
1138 if (ip_len > 0)
1139 ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL);
1140 else
1141 ret = -ESRCH;
1142
1143 kfree(ip_addr);
1144
1145 *ipend = end;
1146
1147 pr_info("resolve '%.*s' (ret=%d): %s\n", (int)(end - name), name,
1148 ret, ret ? "failed" : ceph_pr_addr(ss));
1149
1150 return ret;
1151}
1152#else
1153static inline int ceph_dns_resolve_name(const char *name, size_t namelen,
1154 struct sockaddr_storage *ss, char delim, const char **ipend)
1155{
1156 return -EINVAL;
1157}
1158#endif
1159
1160/*
1161 * Parse a server name (IP or hostname). If a valid IP address is not found
1162 * then try to extract a hostname to resolve using userspace DNS upcall.
1163 */
1164static int ceph_parse_server_name(const char *name, size_t namelen,
1165 struct sockaddr_storage *ss, char delim, const char **ipend)
1166{
1167 int ret;
1168
1169 ret = ceph_pton(name, namelen, ss, delim, ipend);
1170 if (ret)
1171 ret = ceph_dns_resolve_name(name, namelen, ss, delim, ipend);
1172
1173 return ret;
1174}
1175
1176/*
1081 * Parse an ip[:port] list into an addr array. Use the default 1177 * Parse an ip[:port] list into an addr array. Use the default
1082 * monitor port if a port isn't specified. 1178 * monitor port if a port isn't specified.
1083 */ 1179 */
@@ -1085,15 +1181,13 @@ int ceph_parse_ips(const char *c, const char *end,
1085 struct ceph_entity_addr *addr, 1181 struct ceph_entity_addr *addr,
1086 int max_count, int *count) 1182 int max_count, int *count)
1087{ 1183{
1088 int i; 1184 int i, ret = -EINVAL;
1089 const char *p = c; 1185 const char *p = c;
1090 1186
1091 dout("parse_ips on '%.*s'\n", (int)(end-c), c); 1187 dout("parse_ips on '%.*s'\n", (int)(end-c), c);
1092 for (i = 0; i < max_count; i++) { 1188 for (i = 0; i < max_count; i++) {
1093 const char *ipend; 1189 const char *ipend;
1094 struct sockaddr_storage *ss = &addr[i].in_addr; 1190 struct sockaddr_storage *ss = &addr[i].in_addr;
1095 struct sockaddr_in *in4 = (void *)ss;
1096 struct sockaddr_in6 *in6 = (void *)ss;
1097 int port; 1191 int port;
1098 char delim = ','; 1192 char delim = ',';
1099 1193
@@ -1102,15 +1196,11 @@ int ceph_parse_ips(const char *c, const char *end,
1102 p++; 1196 p++;
1103 } 1197 }
1104 1198
1105 memset(ss, 0, sizeof(*ss)); 1199 ret = ceph_parse_server_name(p, end - p, ss, delim, &ipend);
1106 if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr, 1200 if (ret)
1107 delim, &ipend))
1108 ss->ss_family = AF_INET;
1109 else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
1110 delim, &ipend))
1111 ss->ss_family = AF_INET6;
1112 else
1113 goto bad; 1201 goto bad;
1202 ret = -EINVAL;
1203
1114 p = ipend; 1204 p = ipend;
1115 1205
1116 if (delim == ']') { 1206 if (delim == ']') {
@@ -1155,7 +1245,7 @@ int ceph_parse_ips(const char *c, const char *end,
1155 1245
1156bad: 1246bad:
1157 pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c); 1247 pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c);
1158 return -EINVAL; 1248 return ret;
1159} 1249}
1160EXPORT_SYMBOL(ceph_parse_ips); 1250EXPORT_SYMBOL(ceph_parse_ips);
1161 1251
@@ -2281,7 +2371,8 @@ EXPORT_SYMBOL(ceph_con_keepalive);
2281 * construct a new message with given type, size 2371 * construct a new message with given type, size
2282 * the new msg has a ref count of 1. 2372 * the new msg has a ref count of 1.
2283 */ 2373 */
2284struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags) 2374struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
2375 bool can_fail)
2285{ 2376{
2286 struct ceph_msg *m; 2377 struct ceph_msg *m;
2287 2378
@@ -2333,7 +2424,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
2333 m->front.iov_base = kmalloc(front_len, flags); 2424 m->front.iov_base = kmalloc(front_len, flags);
2334 } 2425 }
2335 if (m->front.iov_base == NULL) { 2426 if (m->front.iov_base == NULL) {
2336 pr_err("msg_new can't allocate %d bytes\n", 2427 dout("ceph_msg_new can't allocate %d bytes\n",
2337 front_len); 2428 front_len);
2338 goto out2; 2429 goto out2;
2339 } 2430 }
@@ -2348,7 +2439,14 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
2348out2: 2439out2:
2349 ceph_msg_put(m); 2440 ceph_msg_put(m);
2350out: 2441out:
2351 pr_err("msg_new can't create type %d front %d\n", type, front_len); 2442 if (!can_fail) {
2443 pr_err("msg_new can't create type %d front %d\n", type,
2444 front_len);
2445 WARN_ON(1);
2446 } else {
2447 dout("msg_new can't create type %d front %d\n", type,
2448 front_len);
2449 }
2352 return NULL; 2450 return NULL;
2353} 2451}
2354EXPORT_SYMBOL(ceph_msg_new); 2452EXPORT_SYMBOL(ceph_msg_new);
@@ -2398,7 +2496,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
2398 } 2496 }
2399 if (!msg) { 2497 if (!msg) {
2400 *skip = 0; 2498 *skip = 0;
2401 msg = ceph_msg_new(type, front_len, GFP_NOFS); 2499 msg = ceph_msg_new(type, front_len, GFP_NOFS, false);
2402 if (!msg) { 2500 if (!msg) {
2403 pr_err("unable to allocate msg type %d len %d\n", 2501 pr_err("unable to allocate msg type %d len %d\n",
2404 type, front_len); 2502 type, front_len);
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index cbe31fa45508..0b62deae42bd 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -116,14 +116,12 @@ static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
116 */ 116 */
117static void __close_session(struct ceph_mon_client *monc) 117static void __close_session(struct ceph_mon_client *monc)
118{ 118{
119 if (monc->con) { 119 dout("__close_session closing mon%d\n", monc->cur_mon);
120 dout("__close_session closing mon%d\n", monc->cur_mon); 120 ceph_con_revoke(monc->con, monc->m_auth);
121 ceph_con_revoke(monc->con, monc->m_auth); 121 ceph_con_close(monc->con);
122 ceph_con_close(monc->con); 122 monc->cur_mon = -1;
123 monc->cur_mon = -1; 123 monc->pending_auth = 0;
124 monc->pending_auth = 0; 124 ceph_auth_reset(monc->auth);
125 ceph_auth_reset(monc->auth);
126 }
127} 125}
128 126
129/* 127/*
@@ -302,15 +300,6 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
302 */ 300 */
303int ceph_monc_open_session(struct ceph_mon_client *monc) 301int ceph_monc_open_session(struct ceph_mon_client *monc)
304{ 302{
305 if (!monc->con) {
306 monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
307 if (!monc->con)
308 return -ENOMEM;
309 ceph_con_init(monc->client->msgr, monc->con);
310 monc->con->private = monc;
311 monc->con->ops = &mon_con_ops;
312 }
313
314 mutex_lock(&monc->mutex); 303 mutex_lock(&monc->mutex);
315 __open_session(monc); 304 __open_session(monc);
316 __schedule_delayed(monc); 305 __schedule_delayed(monc);
@@ -528,10 +517,12 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
528 init_completion(&req->completion); 517 init_completion(&req->completion);
529 518
530 err = -ENOMEM; 519 err = -ENOMEM;
531 req->request = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), GFP_NOFS); 520 req->request = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), GFP_NOFS,
521 true);
532 if (!req->request) 522 if (!req->request)
533 goto out; 523 goto out;
534 req->reply = ceph_msg_new(CEPH_MSG_STATFS_REPLY, 1024, GFP_NOFS); 524 req->reply = ceph_msg_new(CEPH_MSG_STATFS_REPLY, 1024, GFP_NOFS,
525 true);
535 if (!req->reply) 526 if (!req->reply)
536 goto out; 527 goto out;
537 528
@@ -626,10 +617,12 @@ int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op,
626 init_completion(&req->completion); 617 init_completion(&req->completion);
627 618
628 err = -ENOMEM; 619 err = -ENOMEM;
629 req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS); 620 req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS,
621 true);
630 if (!req->request) 622 if (!req->request)
631 goto out; 623 goto out;
632 req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS); 624 req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS,
625 true);
633 if (!req->reply) 626 if (!req->reply)
634 goto out; 627 goto out;
635 628
@@ -755,13 +748,21 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
755 if (err) 748 if (err)
756 goto out; 749 goto out;
757 750
758 monc->con = NULL; 751 /* connection */
752 monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
753 if (!monc->con)
754 goto out_monmap;
755 ceph_con_init(monc->client->msgr, monc->con);
756 monc->con->private = monc;
757 monc->con->ops = &mon_con_ops;
759 758
760 /* authentication */ 759 /* authentication */
761 monc->auth = ceph_auth_init(cl->options->name, 760 monc->auth = ceph_auth_init(cl->options->name,
762 cl->options->key); 761 cl->options->key);
763 if (IS_ERR(monc->auth)) 762 if (IS_ERR(monc->auth)) {
764 return PTR_ERR(monc->auth); 763 err = PTR_ERR(monc->auth);
764 goto out_con;
765 }
765 monc->auth->want_keys = 766 monc->auth->want_keys =
766 CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON | 767 CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON |
767 CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS; 768 CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS;
@@ -770,19 +771,21 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
770 err = -ENOMEM; 771 err = -ENOMEM;
771 monc->m_subscribe_ack = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE_ACK, 772 monc->m_subscribe_ack = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE_ACK,
772 sizeof(struct ceph_mon_subscribe_ack), 773 sizeof(struct ceph_mon_subscribe_ack),
773 GFP_NOFS); 774 GFP_NOFS, true);
774 if (!monc->m_subscribe_ack) 775 if (!monc->m_subscribe_ack)
775 goto out_monmap; 776 goto out_auth;
776 777
777 monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, GFP_NOFS); 778 monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, GFP_NOFS,
779 true);
778 if (!monc->m_subscribe) 780 if (!monc->m_subscribe)
779 goto out_subscribe_ack; 781 goto out_subscribe_ack;
780 782
781 monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096, GFP_NOFS); 783 monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096, GFP_NOFS,
784 true);
782 if (!monc->m_auth_reply) 785 if (!monc->m_auth_reply)
783 goto out_subscribe; 786 goto out_subscribe;
784 787
785 monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_NOFS); 788 monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_NOFS, true);
786 monc->pending_auth = 0; 789 monc->pending_auth = 0;
787 if (!monc->m_auth) 790 if (!monc->m_auth)
788 goto out_auth_reply; 791 goto out_auth_reply;
@@ -808,6 +811,10 @@ out_subscribe:
808 ceph_msg_put(monc->m_subscribe); 811 ceph_msg_put(monc->m_subscribe);
809out_subscribe_ack: 812out_subscribe_ack:
810 ceph_msg_put(monc->m_subscribe_ack); 813 ceph_msg_put(monc->m_subscribe_ack);
814out_auth:
815 ceph_auth_destroy(monc->auth);
816out_con:
817 monc->con->ops->put(monc->con);
811out_monmap: 818out_monmap:
812 kfree(monc->monmap); 819 kfree(monc->monmap);
813out: 820out:
@@ -822,11 +829,11 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
822 829
823 mutex_lock(&monc->mutex); 830 mutex_lock(&monc->mutex);
824 __close_session(monc); 831 __close_session(monc);
825 if (monc->con) { 832
826 monc->con->private = NULL; 833 monc->con->private = NULL;
827 monc->con->ops->put(monc->con); 834 monc->con->ops->put(monc->con);
828 monc->con = NULL; 835 monc->con = NULL;
829 } 836
830 mutex_unlock(&monc->mutex); 837 mutex_unlock(&monc->mutex);
831 838
832 ceph_auth_destroy(monc->auth); 839 ceph_auth_destroy(monc->auth);
@@ -973,7 +980,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
973 case CEPH_MSG_MON_MAP: 980 case CEPH_MSG_MON_MAP:
974 case CEPH_MSG_MDS_MAP: 981 case CEPH_MSG_MDS_MAP:
975 case CEPH_MSG_OSD_MAP: 982 case CEPH_MSG_OSD_MAP:
976 m = ceph_msg_new(type, front_len, GFP_NOFS); 983 m = ceph_msg_new(type, front_len, GFP_NOFS, false);
977 break; 984 break;
978 } 985 }
979 986
@@ -1000,7 +1007,7 @@ static void mon_fault(struct ceph_connection *con)
1000 if (!con->private) 1007 if (!con->private)
1001 goto out; 1008 goto out;
1002 1009
1003 if (monc->con && !monc->hunting) 1010 if (!monc->hunting)
1004 pr_info("mon%d %s session lost, " 1011 pr_info("mon%d %s session lost, "
1005 "hunting for new mon\n", monc->cur_mon, 1012 "hunting for new mon\n", monc->cur_mon,
1006 ceph_pr_addr(&monc->con->peer_addr.in_addr)); 1013 ceph_pr_addr(&monc->con->peer_addr.in_addr));
diff --git a/net/ceph/msgpool.c b/net/ceph/msgpool.c
index 1f4cb30a42c5..11d5f4196a73 100644
--- a/net/ceph/msgpool.c
+++ b/net/ceph/msgpool.c
@@ -12,7 +12,7 @@ static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
12 struct ceph_msgpool *pool = arg; 12 struct ceph_msgpool *pool = arg;
13 struct ceph_msg *msg; 13 struct ceph_msg *msg;
14 14
15 msg = ceph_msg_new(0, pool->front_len, gfp_mask); 15 msg = ceph_msg_new(0, pool->front_len, gfp_mask, true);
16 if (!msg) { 16 if (!msg) {
17 dout("msgpool_alloc %s failed\n", pool->name); 17 dout("msgpool_alloc %s failed\n", pool->name);
18 } else { 18 } else {
@@ -61,7 +61,7 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool,
61 WARN_ON(1); 61 WARN_ON(1);
62 62
63 /* try to alloc a fresh message */ 63 /* try to alloc a fresh message */
64 return ceph_msg_new(0, front_len, GFP_NOFS); 64 return ceph_msg_new(0, front_len, GFP_NOFS, false);
65 } 65 }
66 66
67 msg = mempool_alloc(pool->pool, GFP_NOFS); 67 msg = mempool_alloc(pool->pool, GFP_NOFS);
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 88ad8a2501b5..733e46008b89 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -227,7 +227,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
227 msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0); 227 msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
228 else 228 else
229 msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, 229 msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY,
230 OSD_OPREPLY_FRONT_LEN, gfp_flags); 230 OSD_OPREPLY_FRONT_LEN, gfp_flags, true);
231 if (!msg) { 231 if (!msg) {
232 ceph_osdc_put_request(req); 232 ceph_osdc_put_request(req);
233 return NULL; 233 return NULL;
@@ -250,7 +250,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
250 if (use_mempool) 250 if (use_mempool)
251 msg = ceph_msgpool_get(&osdc->msgpool_op, 0); 251 msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
252 else 252 else
253 msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp_flags); 253 msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp_flags, true);
254 if (!msg) { 254 if (!msg) {
255 ceph_osdc_put_request(req); 255 ceph_osdc_put_request(req);
256 return NULL; 256 return NULL;
@@ -943,7 +943,7 @@ EXPORT_SYMBOL(ceph_osdc_set_request_linger);
943 * Caller should hold map_sem for read and request_mutex. 943 * Caller should hold map_sem for read and request_mutex.
944 */ 944 */
945static int __map_request(struct ceph_osd_client *osdc, 945static int __map_request(struct ceph_osd_client *osdc,
946 struct ceph_osd_request *req) 946 struct ceph_osd_request *req, int force_resend)
947{ 947{
948 struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; 948 struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
949 struct ceph_pg pgid; 949 struct ceph_pg pgid;
@@ -967,7 +967,8 @@ static int __map_request(struct ceph_osd_client *osdc,
967 num = err; 967 num = err;
968 } 968 }
969 969
970 if ((req->r_osd && req->r_osd->o_osd == o && 970 if ((!force_resend &&
971 req->r_osd && req->r_osd->o_osd == o &&
971 req->r_sent >= req->r_osd->o_incarnation && 972 req->r_sent >= req->r_osd->o_incarnation &&
972 req->r_num_pg_osds == num && 973 req->r_num_pg_osds == num &&
973 memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) || 974 memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
@@ -1289,18 +1290,18 @@ static void reset_changed_osds(struct ceph_osd_client *osdc)
1289 * 1290 *
1290 * Caller should hold map_sem for read and request_mutex. 1291 * Caller should hold map_sem for read and request_mutex.
1291 */ 1292 */
1292static void kick_requests(struct ceph_osd_client *osdc) 1293static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
1293{ 1294{
1294 struct ceph_osd_request *req, *nreq; 1295 struct ceph_osd_request *req, *nreq;
1295 struct rb_node *p; 1296 struct rb_node *p;
1296 int needmap = 0; 1297 int needmap = 0;
1297 int err; 1298 int err;
1298 1299
1299 dout("kick_requests\n"); 1300 dout("kick_requests %s\n", force_resend ? " (force resend)" : "");
1300 mutex_lock(&osdc->request_mutex); 1301 mutex_lock(&osdc->request_mutex);
1301 for (p = rb_first(&osdc->requests); p; p = rb_next(p)) { 1302 for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
1302 req = rb_entry(p, struct ceph_osd_request, r_node); 1303 req = rb_entry(p, struct ceph_osd_request, r_node);
1303 err = __map_request(osdc, req); 1304 err = __map_request(osdc, req, force_resend);
1304 if (err < 0) 1305 if (err < 0)
1305 continue; /* error */ 1306 continue; /* error */
1306 if (req->r_osd == NULL) { 1307 if (req->r_osd == NULL) {
@@ -1318,7 +1319,7 @@ static void kick_requests(struct ceph_osd_client *osdc)
1318 r_linger_item) { 1319 r_linger_item) {
1319 dout("linger req=%p req->r_osd=%p\n", req, req->r_osd); 1320 dout("linger req=%p req->r_osd=%p\n", req, req->r_osd);
1320 1321
1321 err = __map_request(osdc, req); 1322 err = __map_request(osdc, req, force_resend);
1322 if (err == 0) 1323 if (err == 0)
1323 continue; /* no change and no osd was specified */ 1324 continue; /* no change and no osd was specified */
1324 if (err < 0) 1325 if (err < 0)
@@ -1395,7 +1396,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1395 ceph_osdmap_destroy(osdc->osdmap); 1396 ceph_osdmap_destroy(osdc->osdmap);
1396 osdc->osdmap = newmap; 1397 osdc->osdmap = newmap;
1397 } 1398 }
1398 kick_requests(osdc); 1399 kick_requests(osdc, 0);
1399 reset_changed_osds(osdc); 1400 reset_changed_osds(osdc);
1400 } else { 1401 } else {
1401 dout("ignoring incremental map %u len %d\n", 1402 dout("ignoring incremental map %u len %d\n",
@@ -1423,6 +1424,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1423 "older than our %u\n", epoch, maplen, 1424 "older than our %u\n", epoch, maplen,
1424 osdc->osdmap->epoch); 1425 osdc->osdmap->epoch);
1425 } else { 1426 } else {
1427 int skipped_map = 0;
1428
1426 dout("taking full map %u len %d\n", epoch, maplen); 1429 dout("taking full map %u len %d\n", epoch, maplen);
1427 newmap = osdmap_decode(&p, p+maplen); 1430 newmap = osdmap_decode(&p, p+maplen);
1428 if (IS_ERR(newmap)) { 1431 if (IS_ERR(newmap)) {
@@ -1432,9 +1435,12 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1432 BUG_ON(!newmap); 1435 BUG_ON(!newmap);
1433 oldmap = osdc->osdmap; 1436 oldmap = osdc->osdmap;
1434 osdc->osdmap = newmap; 1437 osdc->osdmap = newmap;
1435 if (oldmap) 1438 if (oldmap) {
1439 if (oldmap->epoch + 1 < newmap->epoch)
1440 skipped_map = 1;
1436 ceph_osdmap_destroy(oldmap); 1441 ceph_osdmap_destroy(oldmap);
1437 kick_requests(osdc); 1442 }
1443 kick_requests(osdc, skipped_map);
1438 } 1444 }
1439 p += maplen; 1445 p += maplen;
1440 nr_maps--; 1446 nr_maps--;
@@ -1707,7 +1713,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1707 * the request still han't been touched yet. 1713 * the request still han't been touched yet.
1708 */ 1714 */
1709 if (req->r_sent == 0) { 1715 if (req->r_sent == 0) {
1710 rc = __map_request(osdc, req); 1716 rc = __map_request(osdc, req, 0);
1711 if (rc < 0) { 1717 if (rc < 0) {
1712 if (nofail) { 1718 if (nofail) {
1713 dout("osdc_start_request failed map, " 1719 dout("osdc_start_request failed map, "
@@ -2032,7 +2038,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
2032 if (front > req->r_reply->front.iov_len) { 2038 if (front > req->r_reply->front.iov_len) {
2033 pr_warning("get_reply front %d > preallocated %d\n", 2039 pr_warning("get_reply front %d > preallocated %d\n",
2034 front, (int)req->r_reply->front.iov_len); 2040 front, (int)req->r_reply->front.iov_len);
2035 m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, GFP_NOFS); 2041 m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, GFP_NOFS, false);
2036 if (!m) 2042 if (!m)
2037 goto out; 2043 goto out;
2038 ceph_msg_put(req->r_reply); 2044 ceph_msg_put(req->r_reply);
@@ -2080,7 +2086,7 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con,
2080 switch (type) { 2086 switch (type) {
2081 case CEPH_MSG_OSD_MAP: 2087 case CEPH_MSG_OSD_MAP:
2082 case CEPH_MSG_WATCH_NOTIFY: 2088 case CEPH_MSG_WATCH_NOTIFY:
2083 return ceph_msg_new(type, front, GFP_NOFS); 2089 return ceph_msg_new(type, front, GFP_NOFS, false);
2084 case CEPH_MSG_OSD_OPREPLY: 2090 case CEPH_MSG_OSD_OPREPLY:
2085 return get_reply(con, hdr, skip); 2091 return get_reply(con, hdr, skip);
2086 default: 2092 default: