aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ceph/auth_x.c76
-rw-r--r--net/ceph/auth_x.h1
-rw-r--r--net/ceph/buffer.c4
-rw-r--r--net/ceph/ceph_common.c21
-rw-r--r--net/ceph/messenger.c34
-rw-r--r--net/ceph/osd_client.c118
6 files changed, 203 insertions, 51 deletions
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 7e38b729696a..15845814a0f2 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/ceph/decode.h> 9#include <linux/ceph/decode.h>
10#include <linux/ceph/auth.h> 10#include <linux/ceph/auth.h>
11#include <linux/ceph/messenger.h>
11 12
12#include "crypto.h" 13#include "crypto.h"
13#include "auth_x.h" 14#include "auth_x.h"
@@ -293,6 +294,11 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
293 dout("build_authorizer for %s %p\n", 294 dout("build_authorizer for %s %p\n",
294 ceph_entity_type_name(th->service), au); 295 ceph_entity_type_name(th->service), au);
295 296
297 ceph_crypto_key_destroy(&au->session_key);
298 ret = ceph_crypto_key_clone(&au->session_key, &th->session_key);
299 if (ret)
300 return ret;
301
296 maxlen = sizeof(*msg_a) + sizeof(msg_b) + 302 maxlen = sizeof(*msg_a) + sizeof(msg_b) +
297 ceph_x_encrypt_buflen(ticket_blob_len); 303 ceph_x_encrypt_buflen(ticket_blob_len);
298 dout(" need len %d\n", maxlen); 304 dout(" need len %d\n", maxlen);
@@ -302,8 +308,10 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
302 } 308 }
303 if (!au->buf) { 309 if (!au->buf) {
304 au->buf = ceph_buffer_new(maxlen, GFP_NOFS); 310 au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
305 if (!au->buf) 311 if (!au->buf) {
312 ceph_crypto_key_destroy(&au->session_key);
306 return -ENOMEM; 313 return -ENOMEM;
314 }
307 } 315 }
308 au->service = th->service; 316 au->service = th->service;
309 au->secret_id = th->secret_id; 317 au->secret_id = th->secret_id;
@@ -329,7 +337,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
329 get_random_bytes(&au->nonce, sizeof(au->nonce)); 337 get_random_bytes(&au->nonce, sizeof(au->nonce));
330 msg_b.struct_v = 1; 338 msg_b.struct_v = 1;
331 msg_b.nonce = cpu_to_le64(au->nonce); 339 msg_b.nonce = cpu_to_le64(au->nonce);
332 ret = ceph_x_encrypt(&th->session_key, &msg_b, sizeof(msg_b), 340 ret = ceph_x_encrypt(&au->session_key, &msg_b, sizeof(msg_b),
333 p, end - p); 341 p, end - p);
334 if (ret < 0) 342 if (ret < 0)
335 goto out_buf; 343 goto out_buf;
@@ -560,6 +568,8 @@ static int ceph_x_create_authorizer(
560 auth->authorizer_buf_len = au->buf->vec.iov_len; 568 auth->authorizer_buf_len = au->buf->vec.iov_len;
561 auth->authorizer_reply_buf = au->reply_buf; 569 auth->authorizer_reply_buf = au->reply_buf;
562 auth->authorizer_reply_buf_len = sizeof (au->reply_buf); 570 auth->authorizer_reply_buf_len = sizeof (au->reply_buf);
571 auth->sign_message = ac->ops->sign_message;
572 auth->check_message_signature = ac->ops->check_message_signature;
563 573
564 return 0; 574 return 0;
565} 575}
@@ -588,17 +598,13 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
588 struct ceph_authorizer *a, size_t len) 598 struct ceph_authorizer *a, size_t len)
589{ 599{
590 struct ceph_x_authorizer *au = (void *)a; 600 struct ceph_x_authorizer *au = (void *)a;
591 struct ceph_x_ticket_handler *th;
592 int ret = 0; 601 int ret = 0;
593 struct ceph_x_authorize_reply reply; 602 struct ceph_x_authorize_reply reply;
594 void *preply = &reply; 603 void *preply = &reply;
595 void *p = au->reply_buf; 604 void *p = au->reply_buf;
596 void *end = p + sizeof(au->reply_buf); 605 void *end = p + sizeof(au->reply_buf);
597 606
598 th = get_ticket_handler(ac, au->service); 607 ret = ceph_x_decrypt(&au->session_key, &p, end, &preply, sizeof(reply));
599 if (IS_ERR(th))
600 return PTR_ERR(th);
601 ret = ceph_x_decrypt(&th->session_key, &p, end, &preply, sizeof(reply));
602 if (ret < 0) 608 if (ret < 0)
603 return ret; 609 return ret;
604 if (ret != sizeof(reply)) 610 if (ret != sizeof(reply))
@@ -618,6 +624,7 @@ static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac,
618{ 624{
619 struct ceph_x_authorizer *au = (void *)a; 625 struct ceph_x_authorizer *au = (void *)a;
620 626
627 ceph_crypto_key_destroy(&au->session_key);
621 ceph_buffer_put(au->buf); 628 ceph_buffer_put(au->buf);
622 kfree(au); 629 kfree(au);
623} 630}
@@ -663,6 +670,59 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
663 memset(&th->validity, 0, sizeof(th->validity)); 670 memset(&th->validity, 0, sizeof(th->validity));
664} 671}
665 672
673static int calcu_signature(struct ceph_x_authorizer *au,
674 struct ceph_msg *msg, __le64 *sig)
675{
676 int ret;
677 char tmp_enc[40];
678 __le32 tmp[5] = {
679 16u, msg->hdr.crc, msg->footer.front_crc,
680 msg->footer.middle_crc, msg->footer.data_crc,
681 };
682 ret = ceph_x_encrypt(&au->session_key, &tmp, sizeof(tmp),
683 tmp_enc, sizeof(tmp_enc));
684 if (ret < 0)
685 return ret;
686 *sig = *(__le64*)(tmp_enc + 4);
687 return 0;
688}
689
690static int ceph_x_sign_message(struct ceph_auth_handshake *auth,
691 struct ceph_msg *msg)
692{
693 int ret;
694 if (!auth->authorizer)
695 return 0;
696 ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer,
697 msg, &msg->footer.sig);
698 if (ret < 0)
699 return ret;
700 msg->footer.flags |= CEPH_MSG_FOOTER_SIGNED;
701 return 0;
702}
703
704static int ceph_x_check_message_signature(struct ceph_auth_handshake *auth,
705 struct ceph_msg *msg)
706{
707 __le64 sig_check;
708 int ret;
709
710 if (!auth->authorizer)
711 return 0;
712 ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer,
713 msg, &sig_check);
714 if (ret < 0)
715 return ret;
716 if (sig_check == msg->footer.sig)
717 return 0;
718 if (msg->footer.flags & CEPH_MSG_FOOTER_SIGNED)
719 dout("ceph_x_check_message_signature %p has signature %llx "
720 "expect %llx\n", msg, msg->footer.sig, sig_check);
721 else
722 dout("ceph_x_check_message_signature %p sender did not set "
723 "CEPH_MSG_FOOTER_SIGNED\n", msg);
724 return -EBADMSG;
725}
666 726
667static const struct ceph_auth_client_ops ceph_x_ops = { 727static const struct ceph_auth_client_ops ceph_x_ops = {
668 .name = "x", 728 .name = "x",
@@ -677,6 +737,8 @@ static const struct ceph_auth_client_ops ceph_x_ops = {
677 .invalidate_authorizer = ceph_x_invalidate_authorizer, 737 .invalidate_authorizer = ceph_x_invalidate_authorizer,
678 .reset = ceph_x_reset, 738 .reset = ceph_x_reset,
679 .destroy = ceph_x_destroy, 739 .destroy = ceph_x_destroy,
740 .sign_message = ceph_x_sign_message,
741 .check_message_signature = ceph_x_check_message_signature,
680}; 742};
681 743
682 744
diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h
index 65ee72082d99..e8b7c6917d47 100644
--- a/net/ceph/auth_x.h
+++ b/net/ceph/auth_x.h
@@ -26,6 +26,7 @@ struct ceph_x_ticket_handler {
26 26
27 27
28struct ceph_x_authorizer { 28struct ceph_x_authorizer {
29 struct ceph_crypto_key session_key;
29 struct ceph_buffer *buf; 30 struct ceph_buffer *buf;
30 unsigned int service; 31 unsigned int service;
31 u64 nonce; 32 u64 nonce;
diff --git a/net/ceph/buffer.c b/net/ceph/buffer.c
index 621b5f65407f..add5f921a0ff 100644
--- a/net/ceph/buffer.c
+++ b/net/ceph/buffer.c
@@ -6,7 +6,7 @@
6 6
7#include <linux/ceph/buffer.h> 7#include <linux/ceph/buffer.h>
8#include <linux/ceph/decode.h> 8#include <linux/ceph/decode.h>
9#include <linux/ceph/libceph.h> /* for ceph_kv{malloc,free} */ 9#include <linux/ceph/libceph.h> /* for ceph_kvmalloc */
10 10
11struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) 11struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
12{ 12{
@@ -35,7 +35,7 @@ void ceph_buffer_release(struct kref *kref)
35 struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref); 35 struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref);
36 36
37 dout("buffer_release %p\n", b); 37 dout("buffer_release %p\n", b);
38 ceph_kvfree(b->vec.iov_base); 38 kvfree(b->vec.iov_base);
39 kfree(b); 39 kfree(b);
40} 40}
41EXPORT_SYMBOL(ceph_buffer_release); 41EXPORT_SYMBOL(ceph_buffer_release);
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 58fbfe134f93..5d5ab67f516d 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -184,14 +184,6 @@ void *ceph_kvmalloc(size_t size, gfp_t flags)
184 return __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL); 184 return __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL);
185} 185}
186 186
187void ceph_kvfree(const void *ptr)
188{
189 if (is_vmalloc_addr(ptr))
190 vfree(ptr);
191 else
192 kfree(ptr);
193}
194
195 187
196static int parse_fsid(const char *str, struct ceph_fsid *fsid) 188static int parse_fsid(const char *str, struct ceph_fsid *fsid)
197{ 189{
@@ -245,6 +237,8 @@ enum {
245 Opt_noshare, 237 Opt_noshare,
246 Opt_crc, 238 Opt_crc,
247 Opt_nocrc, 239 Opt_nocrc,
240 Opt_cephx_require_signatures,
241 Opt_nocephx_require_signatures,
248}; 242};
249 243
250static match_table_t opt_tokens = { 244static match_table_t opt_tokens = {
@@ -263,6 +257,8 @@ static match_table_t opt_tokens = {
263 {Opt_noshare, "noshare"}, 257 {Opt_noshare, "noshare"},
264 {Opt_crc, "crc"}, 258 {Opt_crc, "crc"},
265 {Opt_nocrc, "nocrc"}, 259 {Opt_nocrc, "nocrc"},
260 {Opt_cephx_require_signatures, "cephx_require_signatures"},
261 {Opt_nocephx_require_signatures, "nocephx_require_signatures"},
266 {-1, NULL} 262 {-1, NULL}
267}; 263};
268 264
@@ -461,6 +457,12 @@ ceph_parse_options(char *options, const char *dev_name,
461 case Opt_nocrc: 457 case Opt_nocrc:
462 opt->flags |= CEPH_OPT_NOCRC; 458 opt->flags |= CEPH_OPT_NOCRC;
463 break; 459 break;
460 case Opt_cephx_require_signatures:
461 opt->flags &= ~CEPH_OPT_NOMSGAUTH;
462 break;
463 case Opt_nocephx_require_signatures:
464 opt->flags |= CEPH_OPT_NOMSGAUTH;
465 break;
464 466
465 default: 467 default:
466 BUG_ON(token); 468 BUG_ON(token);
@@ -504,6 +506,9 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
504 init_waitqueue_head(&client->auth_wq); 506 init_waitqueue_head(&client->auth_wq);
505 client->auth_err = 0; 507 client->auth_err = 0;
506 508
509 if (!ceph_test_opt(client, NOMSGAUTH))
510 required_features |= CEPH_FEATURE_MSG_AUTH;
511
507 client->extra_mon_dispatch = NULL; 512 client->extra_mon_dispatch = NULL;
508 client->supported_features = CEPH_FEATURES_SUPPORTED_DEFAULT | 513 client->supported_features = CEPH_FEATURES_SUPPORTED_DEFAULT |
509 supported_features; 514 supported_features;
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 8d1653caffdb..33a2f201e460 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1196,8 +1196,18 @@ static void prepare_write_message_footer(struct ceph_connection *con)
1196 dout("prepare_write_message_footer %p\n", con); 1196 dout("prepare_write_message_footer %p\n", con);
1197 con->out_kvec_is_msg = true; 1197 con->out_kvec_is_msg = true;
1198 con->out_kvec[v].iov_base = &m->footer; 1198 con->out_kvec[v].iov_base = &m->footer;
1199 con->out_kvec[v].iov_len = sizeof(m->footer); 1199 if (con->peer_features & CEPH_FEATURE_MSG_AUTH) {
1200 con->out_kvec_bytes += sizeof(m->footer); 1200 if (con->ops->sign_message)
1201 con->ops->sign_message(con, m);
1202 else
1203 m->footer.sig = 0;
1204 con->out_kvec[v].iov_len = sizeof(m->footer);
1205 con->out_kvec_bytes += sizeof(m->footer);
1206 } else {
1207 m->old_footer.flags = m->footer.flags;
1208 con->out_kvec[v].iov_len = sizeof(m->old_footer);
1209 con->out_kvec_bytes += sizeof(m->old_footer);
1210 }
1201 con->out_kvec_left++; 1211 con->out_kvec_left++;
1202 con->out_more = m->more_to_follow; 1212 con->out_more = m->more_to_follow;
1203 con->out_msg_done = true; 1213 con->out_msg_done = true;
@@ -2249,6 +2259,7 @@ static int read_partial_message(struct ceph_connection *con)
2249 int ret; 2259 int ret;
2250 unsigned int front_len, middle_len, data_len; 2260 unsigned int front_len, middle_len, data_len;
2251 bool do_datacrc = !con->msgr->nocrc; 2261 bool do_datacrc = !con->msgr->nocrc;
2262 bool need_sign = (con->peer_features & CEPH_FEATURE_MSG_AUTH);
2252 u64 seq; 2263 u64 seq;
2253 u32 crc; 2264 u32 crc;
2254 2265
@@ -2361,12 +2372,21 @@ static int read_partial_message(struct ceph_connection *con)
2361 } 2372 }
2362 2373
2363 /* footer */ 2374 /* footer */
2364 size = sizeof (m->footer); 2375 if (need_sign)
2376 size = sizeof(m->footer);
2377 else
2378 size = sizeof(m->old_footer);
2379
2365 end += size; 2380 end += size;
2366 ret = read_partial(con, end, size, &m->footer); 2381 ret = read_partial(con, end, size, &m->footer);
2367 if (ret <= 0) 2382 if (ret <= 0)
2368 return ret; 2383 return ret;
2369 2384
2385 if (!need_sign) {
2386 m->footer.flags = m->old_footer.flags;
2387 m->footer.sig = 0;
2388 }
2389
2370 dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n", 2390 dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n",
2371 m, front_len, m->footer.front_crc, middle_len, 2391 m, front_len, m->footer.front_crc, middle_len,
2372 m->footer.middle_crc, data_len, m->footer.data_crc); 2392 m->footer.middle_crc, data_len, m->footer.data_crc);
@@ -2390,6 +2410,12 @@ static int read_partial_message(struct ceph_connection *con)
2390 return -EBADMSG; 2410 return -EBADMSG;
2391 } 2411 }
2392 2412
2413 if (need_sign && con->ops->check_message_signature &&
2414 con->ops->check_message_signature(con, m)) {
2415 pr_err("read_partial_message %p signature check failed\n", m);
2416 return -EBADMSG;
2417 }
2418
2393 return 1; /* done! */ 2419 return 1; /* done! */
2394} 2420}
2395 2421
@@ -3288,7 +3314,7 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip)
3288static void ceph_msg_free(struct ceph_msg *m) 3314static void ceph_msg_free(struct ceph_msg *m)
3289{ 3315{
3290 dout("%s %p\n", __func__, m); 3316 dout("%s %p\n", __func__, m);
3291 ceph_kvfree(m->front.iov_base); 3317 kvfree(m->front.iov_base);
3292 kmem_cache_free(ceph_msg_cache, m); 3318 kmem_cache_free(ceph_msg_cache, m);
3293} 3319}
3294 3320
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 6f164289bde8..53299c7b0ca4 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -292,6 +292,10 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
292 ceph_osd_data_release(&op->cls.request_data); 292 ceph_osd_data_release(&op->cls.request_data);
293 ceph_osd_data_release(&op->cls.response_data); 293 ceph_osd_data_release(&op->cls.response_data);
294 break; 294 break;
295 case CEPH_OSD_OP_SETXATTR:
296 case CEPH_OSD_OP_CMPXATTR:
297 ceph_osd_data_release(&op->xattr.osd_data);
298 break;
295 default: 299 default:
296 break; 300 break;
297 } 301 }
@@ -476,8 +480,7 @@ void osd_req_op_extent_init(struct ceph_osd_request *osd_req,
476 size_t payload_len = 0; 480 size_t payload_len = 0;
477 481
478 BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE && 482 BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
479 opcode != CEPH_OSD_OP_DELETE && opcode != CEPH_OSD_OP_ZERO && 483 opcode != CEPH_OSD_OP_ZERO && opcode != CEPH_OSD_OP_TRUNCATE);
480 opcode != CEPH_OSD_OP_TRUNCATE);
481 484
482 op->extent.offset = offset; 485 op->extent.offset = offset;
483 op->extent.length = length; 486 op->extent.length = length;
@@ -545,6 +548,39 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
545} 548}
546EXPORT_SYMBOL(osd_req_op_cls_init); 549EXPORT_SYMBOL(osd_req_op_cls_init);
547 550
551int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
552 u16 opcode, const char *name, const void *value,
553 size_t size, u8 cmp_op, u8 cmp_mode)
554{
555 struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which, opcode);
556 struct ceph_pagelist *pagelist;
557 size_t payload_len;
558
559 BUG_ON(opcode != CEPH_OSD_OP_SETXATTR && opcode != CEPH_OSD_OP_CMPXATTR);
560
561 pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
562 if (!pagelist)
563 return -ENOMEM;
564
565 ceph_pagelist_init(pagelist);
566
567 payload_len = strlen(name);
568 op->xattr.name_len = payload_len;
569 ceph_pagelist_append(pagelist, name, payload_len);
570
571 op->xattr.value_len = size;
572 ceph_pagelist_append(pagelist, value, size);
573 payload_len += size;
574
575 op->xattr.cmp_op = cmp_op;
576 op->xattr.cmp_mode = cmp_mode;
577
578 ceph_osd_data_pagelist_init(&op->xattr.osd_data, pagelist);
579 op->payload_len = payload_len;
580 return 0;
581}
582EXPORT_SYMBOL(osd_req_op_xattr_init);
583
548void osd_req_op_watch_init(struct ceph_osd_request *osd_req, 584void osd_req_op_watch_init(struct ceph_osd_request *osd_req,
549 unsigned int which, u16 opcode, 585 unsigned int which, u16 opcode,
550 u64 cookie, u64 version, int flag) 586 u64 cookie, u64 version, int flag)
@@ -626,7 +662,6 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
626 case CEPH_OSD_OP_READ: 662 case CEPH_OSD_OP_READ:
627 case CEPH_OSD_OP_WRITE: 663 case CEPH_OSD_OP_WRITE:
628 case CEPH_OSD_OP_ZERO: 664 case CEPH_OSD_OP_ZERO:
629 case CEPH_OSD_OP_DELETE:
630 case CEPH_OSD_OP_TRUNCATE: 665 case CEPH_OSD_OP_TRUNCATE:
631 if (src->op == CEPH_OSD_OP_WRITE) 666 if (src->op == CEPH_OSD_OP_WRITE)
632 request_data_len = src->extent.length; 667 request_data_len = src->extent.length;
@@ -676,6 +711,19 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
676 dst->alloc_hint.expected_write_size = 711 dst->alloc_hint.expected_write_size =
677 cpu_to_le64(src->alloc_hint.expected_write_size); 712 cpu_to_le64(src->alloc_hint.expected_write_size);
678 break; 713 break;
714 case CEPH_OSD_OP_SETXATTR:
715 case CEPH_OSD_OP_CMPXATTR:
716 dst->xattr.name_len = cpu_to_le32(src->xattr.name_len);
717 dst->xattr.value_len = cpu_to_le32(src->xattr.value_len);
718 dst->xattr.cmp_op = src->xattr.cmp_op;
719 dst->xattr.cmp_mode = src->xattr.cmp_mode;
720 osd_data = &src->xattr.osd_data;
721 ceph_osdc_msg_data_add(req->r_request, osd_data);
722 request_data_len = osd_data->pagelist->length;
723 break;
724 case CEPH_OSD_OP_CREATE:
725 case CEPH_OSD_OP_DELETE:
726 break;
679 default: 727 default:
680 pr_err("unsupported osd opcode %s\n", 728 pr_err("unsupported osd opcode %s\n",
681 ceph_osd_op_name(src->op)); 729 ceph_osd_op_name(src->op));
@@ -705,7 +753,8 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
705struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, 753struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
706 struct ceph_file_layout *layout, 754 struct ceph_file_layout *layout,
707 struct ceph_vino vino, 755 struct ceph_vino vino,
708 u64 off, u64 *plen, int num_ops, 756 u64 off, u64 *plen,
757 unsigned int which, int num_ops,
709 int opcode, int flags, 758 int opcode, int flags,
710 struct ceph_snap_context *snapc, 759 struct ceph_snap_context *snapc,
711 u32 truncate_seq, 760 u32 truncate_seq,
@@ -716,13 +765,11 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
716 u64 objnum = 0; 765 u64 objnum = 0;
717 u64 objoff = 0; 766 u64 objoff = 0;
718 u64 objlen = 0; 767 u64 objlen = 0;
719 u32 object_size;
720 u64 object_base;
721 int r; 768 int r;
722 769
723 BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE && 770 BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
724 opcode != CEPH_OSD_OP_DELETE && opcode != CEPH_OSD_OP_ZERO && 771 opcode != CEPH_OSD_OP_ZERO && opcode != CEPH_OSD_OP_TRUNCATE &&
725 opcode != CEPH_OSD_OP_TRUNCATE); 772 opcode != CEPH_OSD_OP_CREATE && opcode != CEPH_OSD_OP_DELETE);
726 773
727 req = ceph_osdc_alloc_request(osdc, snapc, num_ops, use_mempool, 774 req = ceph_osdc_alloc_request(osdc, snapc, num_ops, use_mempool,
728 GFP_NOFS); 775 GFP_NOFS);
@@ -738,29 +785,24 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
738 return ERR_PTR(r); 785 return ERR_PTR(r);
739 } 786 }
740 787
741 object_size = le32_to_cpu(layout->fl_object_size); 788 if (opcode == CEPH_OSD_OP_CREATE || opcode == CEPH_OSD_OP_DELETE) {
742 object_base = off - objoff; 789 osd_req_op_init(req, which, opcode);
743 if (!(truncate_seq == 1 && truncate_size == -1ULL)) { 790 } else {
744 if (truncate_size <= object_base) { 791 u32 object_size = le32_to_cpu(layout->fl_object_size);
745 truncate_size = 0; 792 u32 object_base = off - objoff;
746 } else { 793 if (!(truncate_seq == 1 && truncate_size == -1ULL)) {
747 truncate_size -= object_base; 794 if (truncate_size <= object_base) {
748 if (truncate_size > object_size) 795 truncate_size = 0;
749 truncate_size = object_size; 796 } else {
797 truncate_size -= object_base;
798 if (truncate_size > object_size)
799 truncate_size = object_size;
800 }
750 } 801 }
802 osd_req_op_extent_init(req, which, opcode, objoff, objlen,
803 truncate_size, truncate_seq);
751 } 804 }
752 805
753 osd_req_op_extent_init(req, 0, opcode, objoff, objlen,
754 truncate_size, truncate_seq);
755
756 /*
757 * A second op in the ops array means the caller wants to
758 * also issue a include a 'startsync' command so that the
759 * osd will flush data quickly.
760 */
761 if (num_ops > 1)
762 osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC);
763
764 req->r_base_oloc.pool = ceph_file_layout_pg_pool(*layout); 806 req->r_base_oloc.pool = ceph_file_layout_pg_pool(*layout);
765 807
766 snprintf(req->r_base_oid.name, sizeof(req->r_base_oid.name), 808 snprintf(req->r_base_oid.name, sizeof(req->r_base_oid.name),
@@ -2626,7 +2668,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
2626 2668
2627 dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino, 2669 dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
2628 vino.snap, off, *plen); 2670 vino.snap, off, *plen);
2629 req = ceph_osdc_new_request(osdc, layout, vino, off, plen, 1, 2671 req = ceph_osdc_new_request(osdc, layout, vino, off, plen, 0, 1,
2630 CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, 2672 CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
2631 NULL, truncate_seq, truncate_size, 2673 NULL, truncate_seq, truncate_size,
2632 false); 2674 false);
@@ -2669,7 +2711,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
2669 int page_align = off & ~PAGE_MASK; 2711 int page_align = off & ~PAGE_MASK;
2670 2712
2671 BUG_ON(vino.snap != CEPH_NOSNAP); /* snapshots aren't writeable */ 2713 BUG_ON(vino.snap != CEPH_NOSNAP); /* snapshots aren't writeable */
2672 req = ceph_osdc_new_request(osdc, layout, vino, off, &len, 1, 2714 req = ceph_osdc_new_request(osdc, layout, vino, off, &len, 0, 1,
2673 CEPH_OSD_OP_WRITE, 2715 CEPH_OSD_OP_WRITE,
2674 CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_WRITE, 2716 CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_WRITE,
2675 snapc, truncate_seq, truncate_size, 2717 snapc, truncate_seq, truncate_size,
@@ -2920,6 +2962,20 @@ static int invalidate_authorizer(struct ceph_connection *con)
2920 return ceph_monc_validate_auth(&osdc->client->monc); 2962 return ceph_monc_validate_auth(&osdc->client->monc);
2921} 2963}
2922 2964
2965static int sign_message(struct ceph_connection *con, struct ceph_msg *msg)
2966{
2967 struct ceph_osd *o = con->private;
2968 struct ceph_auth_handshake *auth = &o->o_auth;
2969 return ceph_auth_sign_message(auth, msg);
2970}
2971
2972static int check_message_signature(struct ceph_connection *con, struct ceph_msg *msg)
2973{
2974 struct ceph_osd *o = con->private;
2975 struct ceph_auth_handshake *auth = &o->o_auth;
2976 return ceph_auth_check_message_signature(auth, msg);
2977}
2978
2923static const struct ceph_connection_operations osd_con_ops = { 2979static const struct ceph_connection_operations osd_con_ops = {
2924 .get = get_osd_con, 2980 .get = get_osd_con,
2925 .put = put_osd_con, 2981 .put = put_osd_con,
@@ -2928,5 +2984,7 @@ static const struct ceph_connection_operations osd_con_ops = {
2928 .verify_authorizer_reply = verify_authorizer_reply, 2984 .verify_authorizer_reply = verify_authorizer_reply,
2929 .invalidate_authorizer = invalidate_authorizer, 2985 .invalidate_authorizer = invalidate_authorizer,
2930 .alloc_msg = alloc_msg, 2986 .alloc_msg = alloc_msg,
2987 .sign_message = sign_message,
2988 .check_message_signature = check_message_signature,
2931 .fault = osd_reset, 2989 .fault = osd_reset,
2932}; 2990};