Skip to content

Commit cff7f22

Browse files
committed
Merge tag 'ceph-for-5.17-rc3' of git://github.com/ceph/ceph-client
Pull ceph fixes from Ilya Dryomov: "A patch to make it possible to disable zero copy path in the messenger to avoid checksum or authentication tag mismatches and ensuing session resets in case the destination buffer isn't guaranteed to be stable" * tag 'ceph-for-5.17-rc3' of git://github.com/ceph/ceph-client: libceph: optionally use bounce buffer on recv path in crc mode libceph: make recv path in secure mode work the same as send path
2 parents 1eb7de1 + 038b8d1 commit cff7f22

File tree

6 files changed

+251
-70
lines changed

6 files changed

+251
-70
lines changed

include/linux/ceph/libceph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define CEPH_OPT_TCP_NODELAY (1<<4) /* TCP_NODELAY on TCP sockets */
3636
#define CEPH_OPT_NOMSGSIGN (1<<5) /* don't sign msgs (msgr1) */
3737
#define CEPH_OPT_ABORT_ON_FULL (1<<6) /* abort w/ ENOSPC when full */
38+
#define CEPH_OPT_RXBOUNCE (1<<7) /* double-buffer read data */
3839

3940
#define CEPH_OPT_DEFAULT (CEPH_OPT_TCP_NODELAY)
4041

include/linux/ceph/messenger.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ struct ceph_connection_v2_info {
383383
struct ceph_gcm_nonce in_gcm_nonce;
384384
struct ceph_gcm_nonce out_gcm_nonce;
385385

386+
struct page **in_enc_pages;
387+
int in_enc_page_cnt;
388+
int in_enc_resid;
389+
int in_enc_i;
386390
struct page **out_enc_pages;
387391
int out_enc_page_cnt;
388392
int out_enc_resid;
@@ -457,6 +461,7 @@ struct ceph_connection {
457461
struct ceph_msg *out_msg; /* sending message (== tail of
458462
out_sent) */
459463

464+
struct page *bounce_page;
460465
u32 in_front_crc, in_middle_crc, in_data_crc; /* calculated crc */
461466

462467
struct timespec64 last_keepalive_ack; /* keepalive2 ack stamp */

net/ceph/ceph_common.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ enum {
246246
Opt_cephx_sign_messages,
247247
Opt_tcp_nodelay,
248248
Opt_abort_on_full,
249+
Opt_rxbounce,
249250
};
250251

251252
enum {
@@ -295,6 +296,7 @@ static const struct fs_parameter_spec ceph_parameters[] = {
295296
fsparam_u32 ("osdkeepalive", Opt_osdkeepalivetimeout),
296297
fsparam_enum ("read_from_replica", Opt_read_from_replica,
297298
ceph_param_read_from_replica),
299+
fsparam_flag ("rxbounce", Opt_rxbounce),
298300
fsparam_enum ("ms_mode", Opt_ms_mode,
299301
ceph_param_ms_mode),
300302
fsparam_string ("secret", Opt_secret),
@@ -584,6 +586,9 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
584586
case Opt_abort_on_full:
585587
opt->flags |= CEPH_OPT_ABORT_ON_FULL;
586588
break;
589+
case Opt_rxbounce:
590+
opt->flags |= CEPH_OPT_RXBOUNCE;
591+
break;
587592

588593
default:
589594
BUG();
@@ -660,6 +665,8 @@ int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
660665
seq_puts(m, "notcp_nodelay,");
661666
if (show_all && (opt->flags & CEPH_OPT_ABORT_ON_FULL))
662667
seq_puts(m, "abort_on_full,");
668+
if (opt->flags & CEPH_OPT_RXBOUNCE)
669+
seq_puts(m, "rxbounce,");
663670

664671
if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
665672
seq_printf(m, "mount_timeout=%d,",

net/ceph/messenger.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,10 @@ static void ceph_con_reset_protocol(struct ceph_connection *con)
515515
ceph_msg_put(con->out_msg);
516516
con->out_msg = NULL;
517517
}
518+
if (con->bounce_page) {
519+
__free_page(con->bounce_page);
520+
con->bounce_page = NULL;
521+
}
518522

519523
if (ceph_msgr2(from_msgr(con->msgr)))
520524
ceph_con_v2_reset_protocol(con);

net/ceph/messenger_v1.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -992,18 +992,14 @@ static int read_partial_message_section(struct ceph_connection *con,
992992

993993
static int read_partial_msg_data(struct ceph_connection *con)
994994
{
995-
struct ceph_msg *msg = con->in_msg;
996-
struct ceph_msg_data_cursor *cursor = &msg->cursor;
995+
struct ceph_msg_data_cursor *cursor = &con->in_msg->cursor;
997996
bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC);
998997
struct page *page;
999998
size_t page_offset;
1000999
size_t length;
10011000
u32 crc = 0;
10021001
int ret;
10031002

1004-
if (!msg->num_data_items)
1005-
return -EIO;
1006-
10071003
if (do_datacrc)
10081004
crc = con->in_data_crc;
10091005
while (cursor->total_resid) {
@@ -1031,6 +1027,46 @@ static int read_partial_msg_data(struct ceph_connection *con)
10311027
return 1; /* must return > 0 to indicate success */
10321028
}
10331029

1030+
static int read_partial_msg_data_bounce(struct ceph_connection *con)
1031+
{
1032+
struct ceph_msg_data_cursor *cursor = &con->in_msg->cursor;
1033+
struct page *page;
1034+
size_t off, len;
1035+
u32 crc;
1036+
int ret;
1037+
1038+
if (unlikely(!con->bounce_page)) {
1039+
con->bounce_page = alloc_page(GFP_NOIO);
1040+
if (!con->bounce_page) {
1041+
pr_err("failed to allocate bounce page\n");
1042+
return -ENOMEM;
1043+
}
1044+
}
1045+
1046+
crc = con->in_data_crc;
1047+
while (cursor->total_resid) {
1048+
if (!cursor->resid) {
1049+
ceph_msg_data_advance(cursor, 0);
1050+
continue;
1051+
}
1052+
1053+
page = ceph_msg_data_next(cursor, &off, &len, NULL);
1054+
ret = ceph_tcp_recvpage(con->sock, con->bounce_page, 0, len);
1055+
if (ret <= 0) {
1056+
con->in_data_crc = crc;
1057+
return ret;
1058+
}
1059+
1060+
crc = crc32c(crc, page_address(con->bounce_page), ret);
1061+
memcpy_to_page(page, off, page_address(con->bounce_page), ret);
1062+
1063+
ceph_msg_data_advance(cursor, ret);
1064+
}
1065+
con->in_data_crc = crc;
1066+
1067+
return 1; /* must return > 0 to indicate success */
1068+
}
1069+
10341070
/*
10351071
* read (part of) a message.
10361072
*/
@@ -1141,7 +1177,13 @@ static int read_partial_message(struct ceph_connection *con)
11411177

11421178
/* (page) data */
11431179
if (data_len) {
1144-
ret = read_partial_msg_data(con);
1180+
if (!m->num_data_items)
1181+
return -EIO;
1182+
1183+
if (ceph_test_opt(from_msgr(con->msgr), RXBOUNCE))
1184+
ret = read_partial_msg_data_bounce(con);
1185+
else
1186+
ret = read_partial_msg_data(con);
11451187
if (ret <= 0)
11461188
return ret;
11471189
}

0 commit comments

Comments
 (0)