diff options
Diffstat (limited to 'fs/ceph/messenger.c')
-rw-r--r-- | fs/ceph/messenger.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 8f1715ffbe4..509f57d9ccb 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -30,6 +30,10 @@ static char tag_msg = CEPH_MSGR_TAG_MSG; | |||
30 | static char tag_ack = CEPH_MSGR_TAG_ACK; | 30 | static char tag_ack = CEPH_MSGR_TAG_ACK; |
31 | static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; | 31 | static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; |
32 | 32 | ||
33 | #ifdef CONFIG_LOCKDEP | ||
34 | static struct lock_class_key socket_class; | ||
35 | #endif | ||
36 | |||
33 | 37 | ||
34 | static void queue_con(struct ceph_connection *con); | 38 | static void queue_con(struct ceph_connection *con); |
35 | static void con_work(struct work_struct *); | 39 | static void con_work(struct work_struct *); |
@@ -228,6 +232,10 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con) | |||
228 | con->sock = sock; | 232 | con->sock = sock; |
229 | sock->sk->sk_allocation = GFP_NOFS; | 233 | sock->sk->sk_allocation = GFP_NOFS; |
230 | 234 | ||
235 | #ifdef CONFIG_LOCKDEP | ||
236 | lockdep_set_class(&sock->sk->sk_lock, &socket_class); | ||
237 | #endif | ||
238 | |||
231 | set_sock_callbacks(sock, con); | 239 | set_sock_callbacks(sock, con); |
232 | 240 | ||
233 | dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); | 241 | dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); |
@@ -333,6 +341,7 @@ static void reset_connection(struct ceph_connection *con) | |||
333 | con->out_msg = NULL; | 341 | con->out_msg = NULL; |
334 | } | 342 | } |
335 | con->in_seq = 0; | 343 | con->in_seq = 0; |
344 | con->in_seq_acked = 0; | ||
336 | } | 345 | } |
337 | 346 | ||
338 | /* | 347 | /* |
@@ -1325,6 +1334,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1325 | unsigned front_len, middle_len, data_len, data_off; | 1334 | unsigned front_len, middle_len, data_len, data_off; |
1326 | int datacrc = con->msgr->nocrc; | 1335 | int datacrc = con->msgr->nocrc; |
1327 | int skip; | 1336 | int skip; |
1337 | u64 seq; | ||
1328 | 1338 | ||
1329 | dout("read_partial_message con %p msg %p\n", con, m); | 1339 | dout("read_partial_message con %p msg %p\n", con, m); |
1330 | 1340 | ||
@@ -1359,6 +1369,25 @@ static int read_partial_message(struct ceph_connection *con) | |||
1359 | return -EIO; | 1369 | return -EIO; |
1360 | data_off = le16_to_cpu(con->in_hdr.data_off); | 1370 | data_off = le16_to_cpu(con->in_hdr.data_off); |
1361 | 1371 | ||
1372 | /* verify seq# */ | ||
1373 | seq = le64_to_cpu(con->in_hdr.seq); | ||
1374 | if ((s64)seq - (s64)con->in_seq < 1) { | ||
1375 | pr_info("skipping %s%lld %s seq %lld, expected %lld\n", | ||
1376 | ENTITY_NAME(con->peer_name), | ||
1377 | pr_addr(&con->peer_addr.in_addr), | ||
1378 | seq, con->in_seq + 1); | ||
1379 | con->in_base_pos = -front_len - middle_len - data_len - | ||
1380 | sizeof(m->footer); | ||
1381 | con->in_tag = CEPH_MSGR_TAG_READY; | ||
1382 | con->in_seq++; | ||
1383 | return 0; | ||
1384 | } else if ((s64)seq - (s64)con->in_seq > 1) { | ||
1385 | pr_err("read_partial_message bad seq %lld expected %lld\n", | ||
1386 | seq, con->in_seq + 1); | ||
1387 | con->error_msg = "bad message sequence # for incoming message"; | ||
1388 | return -EBADMSG; | ||
1389 | } | ||
1390 | |||
1362 | /* allocate message? */ | 1391 | /* allocate message? */ |
1363 | if (!con->in_msg) { | 1392 | if (!con->in_msg) { |
1364 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, | 1393 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, |
@@ -1370,6 +1399,7 @@ static int read_partial_message(struct ceph_connection *con) | |||
1370 | con->in_base_pos = -front_len - middle_len - data_len - | 1399 | con->in_base_pos = -front_len - middle_len - data_len - |
1371 | sizeof(m->footer); | 1400 | sizeof(m->footer); |
1372 | con->in_tag = CEPH_MSGR_TAG_READY; | 1401 | con->in_tag = CEPH_MSGR_TAG_READY; |
1402 | con->in_seq++; | ||
1373 | return 0; | 1403 | return 0; |
1374 | } | 1404 | } |
1375 | if (IS_ERR(con->in_msg)) { | 1405 | if (IS_ERR(con->in_msg)) { |
@@ -2021,6 +2051,7 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg) | |||
2021 | ceph_msg_put(con->in_msg); | 2051 | ceph_msg_put(con->in_msg); |
2022 | con->in_msg = NULL; | 2052 | con->in_msg = NULL; |
2023 | con->in_tag = CEPH_MSGR_TAG_READY; | 2053 | con->in_tag = CEPH_MSGR_TAG_READY; |
2054 | con->in_seq++; | ||
2024 | } else { | 2055 | } else { |
2025 | dout("con_revoke_pages %p msg %p pages %p no-op\n", | 2056 | dout("con_revoke_pages %p msg %p pages %p no-op\n", |
2026 | con, con->in_msg, msg); | 2057 | con, con->in_msg, msg); |