History

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

Pull Ceph update from Sage Weil: "There are a few fixes for snapshot behavior with CephFS and support for the new keepalive protocol from Zheng, a libceph fix that affects both RBD and CephFS, a few bug fixes and cleanups for RBD from Ilya, and several small fixes and cleanups from Jianpeng and others" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: ceph: improve readahead for file holes ceph: get inode size for each append write libceph: check data_len in ->alloc_msg() libceph: use keepalive2 to verify the mon session is alive rbd: plug rbd_dev->header.object_prefix memory leak rbd: fix double free on rbd_dev->header_name libceph: set 'exists' flag for newly up osd ceph: cleanup use of ceph_msg_get ceph: no need to get parent inode in ceph_open ceph: remove the useless judgement ceph: remove redundant test of head->safe and silence static analysis warnings ceph: fix queuing inode to mdsdir's snaprealm libceph: rename con_work() to ceph_con_workfn() libceph: Avoid holding the zero page on ceph_msgr_slab_init errors libceph: remove the unused macro AES_KEY_SIZE ceph: invalidate dirty pages after forced umount ceph: EIO all operations after forced umount

Linus Torvalds committed 11 years ago

Commit e013f742 parents 01cab55 438386817 files · +191 −98Browse files

Unified · Split

17 files
  1. drivers/block/rbd.c +4 −2
  2. fs/ceph/addr.c +4 −2
  3. fs/ceph/caps.c +8 −0
  4. fs/ceph/file.c +8 −6
  5. fs/ceph/mds_client.c +45 −14
  6. fs/ceph/mds_client.h +1 −0
  7. fs/ceph/snap.c +0 −7
  8. fs/ceph/super.c +1 −0
  9. include/linux/ceph/libceph.h +2 −0
  10. include/linux/ceph/messenger.h +4 −0
  11. include/linux/ceph/msgr.h +3 −1
  12. net/ceph/ceph_common.c +1 −0
  13. net/ceph/crypto.c +0 −4
  14. net/ceph/messenger.c +62 −20
  15. net/ceph/mon_client.c +29 −8
  16. net/ceph/osd_client.c +18 −33
  17. net/ceph/osdmap.c +1 −1
drivers/block/rbd.c+4−2
@@ -4673,7 +4673,10 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) · 4672 unmodified lines
46734673 }
46744674
46754675 ret = rbd_dev_v2_snap_context(rbd_dev);
4676− dout("rbd_dev_v2_snap_context returned %d\n", ret);
4676+ if (ret && first_time) {
4677+ kfree(rbd_dev->header.object_prefix);
4678+ rbd_dev->header.object_prefix = NULL;
4679+ }
46774680
46784681 return ret;
46794682 }
@@ -5154,7 +5157,6 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev) · 474 unmodified lines
51545157 out_err:
51555158 if (parent) {
51565159 rbd_dev_unparent(rbd_dev);
5157− kfree(rbd_dev->header_name);
51585160 rbd_dev_destroy(parent);
51595161 } else {
51605162 rbd_put_client(rbdc);
fs/ceph/addr.c+4−2
@@ -276,7 +276,7 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg) · 275 unmodified lines
276276 for (i = 0; i < num_pages; i++) {
277277 struct page *page = osd_data->pages[i];
278278
279− if (rc < 0)
279+ if (rc < 0 && rc != ENOENT)
280280 goto unlock;
281281 if (bytes < (int)PAGE_CACHE_SIZE) {
282282 /* zero (remainder of) page */
@@ -717,8 +717,10 @@ static int ceph_writepages_start(struct address_space *mapping, · 434 unmodified lines
717717 wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
718718 (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
719719
720− if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) {
720+ if (ACCESS_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
721721 pr_warn("writepage_start %p on forced umount\n", inode);
722+ truncate_pagecache(inode, 0);
723+ mapping_set_error(mapping, -EIO);
722724 return -EIO; /* we're in a forced umount, don't write! */
723725 }
724726 if (fsc->mount_options->wsize && fsc->mount_options->wsize < wsize)
fs/ceph/caps.c+8−0
@@ -2413,6 +2413,14 @@ again: · 2412 unmodified lines
24132413 goto out_unlock;
24142414 }
24152415
2416+ if (!__ceph_is_any_caps(ci) &&
2417+ ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
2418+ dout("get_cap_refs %p forced umount\n", inode);
2419+ *err = -EIO;
2420+ ret = 1;
2421+ goto out_unlock;
2422+ }
2423+
24162424 dout("get_cap_refs %p have %s needed %s\n", inode,
24172425 ceph_cap_string(have), ceph_cap_string(need));
24182426 }
fs/ceph/file.c+8−6
@@ -136,7 +136,6 @@ int ceph_open(struct inode *inode, struct file *file) · 135 unmodified lines
136136 struct ceph_mds_client *mdsc = fsc->mdsc;
137137 struct ceph_mds_request *req;
138138 struct ceph_file_info *cf = file->private_data;
139− struct inode *parent_inode = NULL;
140139 int err;
141140 int flags, fmode, wanted;
142141
@@ -210,10 +209,7 @@ int ceph_open(struct inode *inode, struct file *file) · 67 unmodified lines
210209 ihold(inode);
211210
212211 req->r_num_caps = 1;
213− if (flags & O_CREAT)
214− parent_inode = ceph_get_dentry_parent_inode(file->f_path.dentry);
215− err = ceph_mdsc_do_request(mdsc, parent_inode, req);
216− iput(parent_inode);
212+ err = ceph_mdsc_do_request(mdsc, NULL, req);
217213 if (!err)
218214 err = ceph_init_file(inode, file, req->r_fmode);
219215 ceph_mdsc_put_request(req);
@@ -279,7 +275,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, · 59 unmodified lines
279275 if (err)
280276 goto out_req;
281277
282− if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
278+ if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
283279 err = ceph_handle_notrace_create(dir, dentry);
284280
285281 if (d_unhashed(dentry)) {
@@ -956,6 +952,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) · 670 unmodified lines
956952 /* We can write back this queue in page reclaim */
957953 current->backing_dev_info = inode_to_bdi(inode);
958954
955+ if (iocb->ki_flags & IOCB_APPEND) {
956+ err = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
957+ if (err < 0)
958+ goto out;
959+ }
960+
959961 err = generic_write_checks(iocb, from);
960962 if (err <= 0)
961963 goto out;
fs/ceph/mds_client.c+45−14
@@ -2107,7 +2107,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc, · 2106 unmodified lines
21072107 msg = create_request_message(mdsc, req, mds, drop_cap_releases);
21082108 if (IS_ERR(msg)) {
21092109 req->r_err = PTR_ERR(msg);
2110− complete_request(mdsc, req);
21112110 return PTR_ERR(msg);
21122111 }
21132112 req->r_request = msg;
@@ -2135,7 +2134,7 @@ static int __do_request(struct ceph_mds_client *mdsc, · 21 unmodified lines
21352134 {
21362135 struct ceph_mds_session *session = NULL;
21372136 int mds = -1;
2138− int err = -EAGAIN;
2137+ int err = 0;
21392138
21402139 if (req->r_err || req->r_got_result) {
21412140 if (req->r_aborted)
@@ -2149,6 +2148,11 @@ static int __do_request(struct ceph_mds_client *mdsc, · 7 unmodified lines
21492148 err = -EIO;
21502149 goto finish;
21512150 }
2151+ if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
2152+ dout("do_request forced umount\n");
2153+ err = -EIO;
2154+ goto finish;
2155+ }
21522156
21532157 put_request_session(req);
21542158
@@ -2196,13 +2200,15 @@ static int __do_request(struct ceph_mds_client *mdsc, · 41 unmodified lines
21962200
21972201 out_session:
21982202 ceph_put_mds_session(session);
2203+finish:
2204+ if (err) {
2205+ dout("__do_request early error %d\n", err);
2206+ req->r_err = err;
2207+ complete_request(mdsc, req);
2208+ __unregister_request(mdsc, req);
2209+ }
21992210 out:
22002211 return err;
2201−
2202−finish:
2203− req->r_err = err;
2204− complete_request(mdsc, req);
2205− goto out;
22062212 }
22072213
22082214 /*
@@ -2289,8 +2295,6 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, · 80 unmodified lines
22892295
22902296 if (req->r_err) {
22912297 err = req->r_err;
2292− __unregister_request(mdsc, req);
2293− dout("do_request early error %d\n", err);
22942298 goto out;
22952299 }
22962300
@@ -2411,7 +2415,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) · 114 unmodified lines
24112415 mutex_unlock(&mdsc->mutex);
24122416 goto out;
24132417 }
2414− if (req->r_got_safe && !head->safe) {
2418+ if (req->r_got_safe) {
24152419 pr_warn("got unsafe after safe on %llu from mds%d\n",
24162420 tid, mds);
24172421 mutex_unlock(&mdsc->mutex);
@@ -2520,8 +2524,7 @@ out_err: · 102 unmodified lines
25202524 if (err) {
25212525 req->r_err = err;
25222526 } else {
2523− req->r_reply = msg;
2524− ceph_msg_get(msg);
2527+ req->r_reply = ceph_msg_get(msg);
25252528 req->r_got_result = true;
25262529 }
25272530 } else {
@@ -3555,7 +3558,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc) · 1027 unmodified lines
35553558 {
35563559 u64 want_tid, want_flush, want_snap;
35573560
3558− if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN)
3561+ if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
35593562 return;
35603563
35613564 dout("sync\n");
@@ -3584,7 +3587,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc) · 22 unmodified lines
35843587 */
35853588 static bool done_closing_sessions(struct ceph_mds_client *mdsc)
35863589 {
3587− if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN)
3590+ if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
35883591 return true;
35893592 return atomic_read(&mdsc->num_sessions) == 0;
35903593 }
@@ -3643,6 +3646,34 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) · 52 unmodified lines
36433646 dout("stopped\n");
36443647 }
36453648
3649+void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc)
3650+{
3651+ struct ceph_mds_session *session;
3652+ int mds;
3653+
3654+ dout("force umount\n");
3655+
3656+ mutex_lock(&mdsc->mutex);
3657+ for (mds = 0; mds < mdsc->max_sessions; mds++) {
3658+ session = __ceph_lookup_mds_session(mdsc, mds);
3659+ if (!session)
3660+ continue;
3661+ mutex_unlock(&mdsc->mutex);
3662+ mutex_lock(&session->s_mutex);
3663+ __close_session(mdsc, session);
3664+ if (session->s_state == CEPH_MDS_SESSION_CLOSING) {
3665+ cleanup_session_requests(mdsc, session);
3666+ remove_session_caps(session);
3667+ }
3668+ mutex_unlock(&session->s_mutex);
3669+ ceph_put_mds_session(session);
3670+ mutex_lock(&mdsc->mutex);
3671+ kick_requests(mdsc, mds);
3672+ }
3673+ __wake_requests(mdsc, &mdsc->waiting_for_map);
3674+ mutex_unlock(&mdsc->mutex);
3675+}
3676+
36463677 static void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
36473678 {
36483679 dout("stop\n");
fs/ceph/mds_client.h+1−0
@@ -366,6 +366,7 @@ extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc, · 365 unmodified lines
366366
367367 extern int ceph_mdsc_init(struct ceph_fs_client *fsc);
368368 extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
369+extern void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc);
369370 extern void ceph_mdsc_destroy(struct ceph_fs_client *fsc);
370371
371372 extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
fs/ceph/snap.c+0−7
@@ -338,12 +338,6 @@ static int build_snap_context(struct ceph_snap_realm *realm) · 337 unmodified lines
338338 return 0;
339339 }
340340
341− if (num == 0 && realm->seq == ceph_empty_snapc->seq) {
342− ceph_get_snap_context(ceph_empty_snapc);
343− snapc = ceph_empty_snapc;
344− goto done;
345− }
346−
347341 /* alloc new snap context */
348342 err = -ENOMEM;
349343 if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
@@ -381,7 +375,6 @@ static int build_snap_context(struct ceph_snap_realm *realm) · 31 unmodified lines
381375 realm->ino, realm, snapc, snapc->seq,
382376 (unsigned int) snapc->num_snaps);
383377
384−done:
385378 ceph_put_snap_context(realm->cached_context);
386379 realm->cached_context = snapc;
387380 return 0;
fs/ceph/super.c+1−0
@@ -708,6 +708,7 @@ static void ceph_umount_begin(struct super_block *sb) · 707 unmodified lines
708708 if (!fsc)
709709 return;
710710 fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
711+ ceph_mdsc_force_umount(fsc->mdsc);
711712 return;
712713 }
713714
include/linux/ceph/libceph.h+2−0
@@ -46,6 +46,7 @@ struct ceph_options { · 45 unmodified lines
4646 unsigned long mount_timeout; /* jiffies */
4747 unsigned long osd_idle_ttl; /* jiffies */
4848 unsigned long osd_keepalive_timeout; /* jiffies */
49+ unsigned long monc_ping_timeout; /* jiffies */
4950
5051 /*
5152 * any type that can't be simply compared or doesn't need need
@@ -66,6 +67,7 @@ struct ceph_options { · 14 unmodified lines
6667 #define CEPH_MOUNT_TIMEOUT_DEFAULT msecs_to_jiffies(60 * 1000)
6768 #define CEPH_OSD_KEEPALIVE_DEFAULT msecs_to_jiffies(5 * 1000)
6869 #define CEPH_OSD_IDLE_TTL_DEFAULT msecs_to_jiffies(60 * 1000)
70+#define CEPH_MONC_PING_TIMEOUT_DEFAULT msecs_to_jiffies(30 * 1000)
6971
7072 #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
7173 #define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024)
include/linux/ceph/messenger.h+4−0
@@ -248,6 +248,8 @@ struct ceph_connection { · 247 unmodified lines
248248 int in_base_pos; /* bytes read */
249249 __le64 in_temp_ack; /* for reading an ack */
250250
251+ struct timespec last_keepalive_ack;
252+
251253 struct delayed_work work; /* send|recv work */
252254 unsigned long delay; /* current delay interval */
253255 };
@@ -285,6 +287,8 @@ extern void ceph_msg_revoke(struct ceph_msg *msg); · 31 unmodified lines
285287 extern void ceph_msg_revoke_incoming(struct ceph_msg *msg);
286288
287289 extern void ceph_con_keepalive(struct ceph_connection *con);
290+extern bool ceph_con_keepalive_expired(struct ceph_connection *con,
291+ unsigned long interval);
288292
289293 extern void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
290294 size_t length, size_t alignment);
include/linux/ceph/msgr.h+3−1
@@ -84,10 +84,12 @@ struct ceph_entity_inst { · 83 unmodified lines
8484 #define CEPH_MSGR_TAG_MSG 7 /* message */
8585 #define CEPH_MSGR_TAG_ACK 8 /* message ack */
8686 #define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */
87−#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */
87+#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */
8888 #define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
8989 #define CEPH_MSGR_TAG_FEATURES 12 /* insufficient features */
9090 #define CEPH_MSGR_TAG_SEQ 13 /* 64-bit int follows with seen seq number */
91+#define CEPH_MSGR_TAG_KEEPALIVE2 14 /* keepalive2 byte + ceph_timespec */
92+#define CEPH_MSGR_TAG_KEEPALIVE2_ACK 15 /* keepalive2 reply */
9193
9294
9395 /*
net/ceph/ceph_common.c+1−0
@@ -357,6 +357,7 @@ ceph_parse_options(char *options, const char *dev_name, · 356 unmodified lines
357357 opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
358358 opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
359359 opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
360+ opt->monc_ping_timeout = CEPH_MONC_PING_TIMEOUT_DEFAULT;
360361
361362 /* get mon ip(s) */
362363 /* ip1[:port1][,ip2[:port2]...] */
net/ceph/crypto.c+0−4
@@ -79,10 +79,6 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey) · 78 unmodified lines
7979 return 0;
8080 }
8181
82−
83−
84−#define AES_KEY_SIZE 16
85−
8682 static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
8783 {
8884 return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
net/ceph/messenger.c+62−20
@@ -163,6 +163,7 @@ static struct kmem_cache *ceph_msg_data_cache; · 162 unmodified lines
163163 static char tag_msg = CEPH_MSGR_TAG_MSG;
164164 static char tag_ack = CEPH_MSGR_TAG_ACK;
165165 static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
166+static char tag_keepalive2 = CEPH_MSGR_TAG_KEEPALIVE2;
166167
167168 #ifdef CONFIG_LOCKDEP
168169 static struct lock_class_key socket_class;
@@ -176,7 +177,7 @@ static struct lock_class_key socket_class; · 7 unmodified lines
176177
177178 static void queue_con(struct ceph_connection *con);
178179 static void cancel_con(struct ceph_connection *con);
179−static void con_work(struct work_struct *);
180+static void ceph_con_workfn(struct work_struct *);
180181 static void con_fault(struct ceph_connection *con);
181182
182183 /*
@@ -276,22 +277,22 @@ static void _ceph_msgr_exit(void) · 93 unmodified lines
276277 ceph_msgr_wq = NULL;
277278 }
278279
279− ceph_msgr_slab_exit();
280−
281280 BUG_ON(zero_page == NULL);
282281 page_cache_release(zero_page);
283282 zero_page = NULL;
283+
284+ ceph_msgr_slab_exit();
284285 }
285286
286287 int ceph_msgr_init(void)
287288 {
289+ if (ceph_msgr_slab_init())
290+ return -ENOMEM;
291+
288292 BUG_ON(zero_page != NULL);
289293 zero_page = ZERO_PAGE(0);
290294 page_cache_get(zero_page);
291295
292− if (ceph_msgr_slab_init())
293− return -ENOMEM;
294−
295296 /*
296297 * The number of active work items is limited by the number of
297298 * connections, so leave @max_active at default.
@@ -749,7 +750,7 @@ void ceph_con_init(struct ceph_connection *con, void *private, · 451 unmodified lines
749750 mutex_init(&con->mutex);
750751 INIT_LIST_HEAD(&con->out_queue);
751752 INIT_LIST_HEAD(&con->out_sent);
752− INIT_DELAYED_WORK(&con->work, con_work);
753+ INIT_DELAYED_WORK(&con->work, ceph_con_workfn);
753754
754755 con->state = CON_STATE_CLOSED;
755756 }
@@ -1351,7 +1352,15 @@ static void prepare_write_keepalive(struct ceph_connection *con) · 595 unmodified lines
13511352 {
13521353 dout("prepare_write_keepalive %p\n", con);
13531354 con_out_kvec_reset(con);
1354− con_out_kvec_add(con, sizeof (tag_keepalive), &tag_keepalive);
1355+ if (con->peer_features & CEPH_FEATURE_MSGR_KEEPALIVE2) {
1356+ struct timespec ts = CURRENT_TIME;
1357+ struct ceph_timespec ceph_ts;
1358+ ceph_encode_timespec(&ceph_ts, &ts);
1359+ con_out_kvec_add(con, sizeof(tag_keepalive2), &tag_keepalive2);
1360+ con_out_kvec_add(con, sizeof(ceph_ts), &ceph_ts);
1361+ } else {
1362+ con_out_kvec_add(con, sizeof(tag_keepalive), &tag_keepalive);
1363+ }
13551364 con_flag_set(con, CON_FLAG_WRITE_PENDING);
13561365 }
13571366
@@ -1625,6 +1634,12 @@ static void prepare_read_tag(struct ceph_connection *con) · 267 unmodified lines
16251634 con->in_tag = CEPH_MSGR_TAG_READY;
16261635 }
16271636
1637+static void prepare_read_keepalive_ack(struct ceph_connection *con)
1638+{
1639+ dout("prepare_read_keepalive_ack %p\n", con);
1640+ con->in_base_pos = 0;
1641+}
1642+
16281643 /*
16291644 * Prepare to read a message.
16301645 */
@@ -2322,13 +2337,6 @@ static int read_partial_message(struct ceph_connection *con) · 691 unmodified lines
23222337 return ret;
23232338
23242339 BUG_ON(!con->in_msg ^ skip);
2325− if (con->in_msg && data_len > con->in_msg->data_length) {
2326− pr_warn("%s skipping long message (%u > %zd)\n",
2327− __func__, data_len, con->in_msg->data_length);
2328− ceph_msg_put(con->in_msg);
2329− con->in_msg = NULL;
2330− skip = 1;
2331− }
23322340 if (skip) {
23332341 /* skip this message */
23342342 dout("alloc_msg said skip message\n");
@@ -2457,6 +2465,17 @@ static void process_message(struct ceph_connection *con) · 122 unmodified lines
24572465 mutex_lock(&con->mutex);
24582466 }
24592467
2468+static int read_keepalive_ack(struct ceph_connection *con)
2469+{
2470+ struct ceph_timespec ceph_ts;
2471+ size_t size = sizeof(ceph_ts);
2472+ int ret = read_partial(con, size, size, &ceph_ts);
2473+ if (ret <= 0)
2474+ return ret;
2475+ ceph_decode_timespec(&con->last_keepalive_ack, &ceph_ts);
2476+ prepare_read_tag(con);
2477+ return 1;
2478+}
24602479
24612480 /*
24622481 * Write something to the socket. Called in a worker thread when the
@@ -2526,6 +2545,10 @@ more_kvec: · 63 unmodified lines
25262545
25272546 do_next:
25282547 if (con->state == CON_STATE_OPEN) {
2548+ if (con_flag_test_and_clear(con, CON_FLAG_KEEPALIVE_PENDING)) {
2549+ prepare_write_keepalive(con);
2550+ goto more;
2551+ }
25292552 /* is anything else pending? */
25302553 if (!list_empty(&con->out_queue)) {
25312554 prepare_write_message(con);
@@ -2535,10 +2558,6 @@ do_next: · 3 unmodified lines
25352558 prepare_write_ack(con);
25362559 goto more;
25372560 }
2538− if (con_flag_test_and_clear(con, CON_FLAG_KEEPALIVE_PENDING)) {
2539− prepare_write_keepalive(con);
2540− goto more;
2541− }
25422561 }
25432562
25442563 /* Nothing to do! */
@@ -2641,6 +2660,9 @@ more: · 96 unmodified lines
26412660 case CEPH_MSGR_TAG_ACK:
26422661 prepare_read_ack(con);
26432662 break;
2663+ case CEPH_MSGR_TAG_KEEPALIVE2_ACK:
2664+ prepare_read_keepalive_ack(con);
2665+ break;
26442666 case CEPH_MSGR_TAG_CLOSE:
26452667 con_close_socket(con);
26462668 con->state = CON_STATE_CLOSED;
@@ -2684,6 +2706,12 @@ more: · 37 unmodified lines
26842706 process_ack(con);
26852707 goto more;
26862708 }
2709+ if (con->in_tag == CEPH_MSGR_TAG_KEEPALIVE2_ACK) {
2710+ ret = read_keepalive_ack(con);
2711+ if (ret <= 0)
2712+ goto out;
2713+ goto more;
2714+ }
26872715
26882716 out:
26892717 dout("try_read done on %p ret %d\n", con, ret);
@@ -2799,7 +2827,7 @@ static void con_fault_finish(struct ceph_connection *con) · 109 unmodified lines
27992827 /*
28002828 * Do some work on a connection. Drop a connection ref when we're done.
28012829 */
2802−static void con_work(struct work_struct *work)
2830+static void ceph_con_workfn(struct work_struct *work)
28032831 {
28042832 struct ceph_connection *con = container_of(work, struct ceph_connection,
28052833 work.work);
@@ -3101,6 +3129,20 @@ void ceph_con_keepalive(struct ceph_connection *con) · 295 unmodified lines
31013129 }
31023130 EXPORT_SYMBOL(ceph_con_keepalive);
31033131
3132+bool ceph_con_keepalive_expired(struct ceph_connection *con,
3133+ unsigned long interval)
3134+{
3135+ if (interval > 0 &&
3136+ (con->peer_features & CEPH_FEATURE_MSGR_KEEPALIVE2)) {
3137+ struct timespec now = CURRENT_TIME;
3138+ struct timespec ts;
3139+ jiffies_to_timespec(interval, &ts);
3140+ ts = timespec_add(con->last_keepalive_ack, ts);
3141+ return timespec_compare(&now, &ts) >= 0;
3142+ }
3143+ return false;
3144+}
3145+
31043146 static struct ceph_msg_data *ceph_msg_data_create(enum ceph_msg_data_type type)
31053147 {
31063148 struct ceph_msg_data *data;
net/ceph/mon_client.c+29−8
@@ -149,6 +149,10 @@ static int __open_session(struct ceph_mon_client *monc) · 148 unmodified lines
149149 CEPH_ENTITY_TYPE_MON, monc->cur_mon,
150150 &monc->monmap->mon_inst[monc->cur_mon].addr);
151151
152+ /* send an initial keepalive to ensure our timestamp is
153+ * valid by the time we are in an OPENED state */
154+ ceph_con_keepalive(&monc->con);
155+
152156 /* initiatiate authentication handshake */
153157 ret = ceph_auth_build_hello(monc->auth,
154158 monc->m_auth->front.iov_base,
@@ -170,14 +174,19 @@ static bool __sub_expired(struct ceph_mon_client *monc) · 15 unmodified lines
170174 */
171175 static void __schedule_delayed(struct ceph_mon_client *monc)
172176 {
173− unsigned int delay;
177+ struct ceph_options *opt = monc->client->options;
178+ unsigned long delay;
174179
175− if (monc->cur_mon < 0 || __sub_expired(monc))
180+ if (monc->cur_mon < 0 || __sub_expired(monc)) {
176181 delay = 10 * HZ;
177− else
182+ } else {
178183 delay = 20 * HZ;
179− dout("__schedule_delayed after %u\n", delay);
180− schedule_delayed_work(&monc->delayed_work, delay);
184+ if (opt->monc_ping_timeout > 0)
185+ delay = min(delay, opt->monc_ping_timeout / 3);
186+ }
187+ dout("__schedule_delayed after %lu\n", delay);
188+ schedule_delayed_work(&monc->delayed_work,
189+ round_jiffies_relative(delay));
181190 }
182191
183192 /*
@@ -743,11 +752,23 @@ static void delayed_work(struct work_struct *work) · 559 unmodified lines
743752 __close_session(monc);
744753 __open_session(monc); /* continue hunting */
745754 } else {
746− ceph_con_keepalive(&monc->con);
755+ struct ceph_options *opt = monc->client->options;
756+ int is_auth = ceph_auth_is_authenticated(monc->auth);
757+ if (ceph_con_keepalive_expired(&monc->con,
758+ opt->monc_ping_timeout)) {
759+ dout("monc keepalive timeout\n");
760+ is_auth = 0;
761+ __close_session(monc);
762+ monc->hunting = true;
763+ __open_session(monc);
764+ }
747765
748− __validate_auth(monc);
766+ if (!monc->hunting) {
767+ ceph_con_keepalive(&monc->con);
768+ __validate_auth(monc);
769+ }
749770
750− if (ceph_auth_is_authenticated(monc->auth))
771+ if (is_auth)
751772 __send_subscribe(monc);
752773 }
753774 __schedule_delayed(monc);
net/ceph/osd_client.c+18−33
@@ -2817,8 +2817,9 @@ out: · 2816 unmodified lines
28172817 }
28182818
28192819 /*
2820− * lookup and return message for incoming reply. set up reply message
2821− * pages.
2820+ * Lookup and return message for incoming reply. Don't try to do
2821+ * anything about a larger than preallocated data portion of the
2822+ * message at the moment - for now, just skip the message.
28222823 */
28232824 static struct ceph_msg *get_reply(struct ceph_connection *con,
28242825 struct ceph_msg_header *hdr,
@@ -2836,10 +2837,10 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, · 11 unmodified lines
28362837 mutex_lock(&osdc->request_mutex);
28372838 req = __lookup_request(osdc, tid);
28382839 if (!req) {
2839− *skip = 1;
2840+ pr_warn("%s osd%d tid %llu unknown, skipping\n",
2841+ __func__, osd->o_osd, tid);
28402842 m = NULL;
2841− dout("get_reply unknown tid %llu from osd%d\n", tid,
2842− osd->o_osd);
2843+ *skip = 1;
28432844 goto out;
28442845 }
28452846
@@ -2849,10 +2850,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, · 3 unmodified lines
28492850 ceph_msg_revoke_incoming(req->r_reply);
28502851
28512852 if (front_len > req->r_reply->front_alloc_len) {
2852− pr_warn("get_reply front %d > preallocated %d (%u#%llu)\n",
2853− front_len, req->r_reply->front_alloc_len,
2854− (unsigned int)con->peer_name.type,
2855− le64_to_cpu(con->peer_name.num));
2853+ pr_warn("%s osd%d tid %llu front %d > preallocated %d\n",
2854+ __func__, osd->o_osd, req->r_tid, front_len,
2855+ req->r_reply->front_alloc_len);
28562856 m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front_len, GFP_NOFS,
28572857 false);
28582858 if (!m)
@@ -2860,37 +2860,22 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, · 1 unmodified line
28602860 ceph_msg_put(req->r_reply);
28612861 req->r_reply = m;
28622862 }
2863− m = ceph_msg_get(req->r_reply);
2864−
2865− if (data_len > 0) {
2866− struct ceph_osd_data *osd_data;
28672863
2868− /*
2869− * XXX This is assuming there is only one op containing
2870− * XXX page data. Probably OK for reads, but this
2871− * XXX ought to be done more generally.
2872− */
2873− osd_data = osd_req_op_extent_osd_data(req, 0);
2874− if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) {
2875− if (osd_data->pages &&
2876− unlikely(osd_data->length < data_len)) {
2877−
2878− pr_warn("tid %lld reply has %d bytes we had only %llu bytes ready\n",
2879− tid, data_len, osd_data->length);
2880− *skip = 1;
2881− ceph_msg_put(m);
2882− m = NULL;
2883− goto out;
2884− }
2885− }
2864+ if (data_len > req->r_reply->data_length) {
2865+ pr_warn("%s osd%d tid %llu data %d > preallocated %zu, skipping\n",
2866+ __func__, osd->o_osd, req->r_tid, data_len,
2867+ req->r_reply->data_length);
2868+ m = NULL;
2869+ *skip = 1;
2870+ goto out;
28862871 }
2887− *skip = 0;
2872+
2873+ m = ceph_msg_get(req->r_reply);
28882874 dout("get_reply tid %lld %p\n", tid, m);
28892875
28902876 out:
28912877 mutex_unlock(&osdc->request_mutex);
28922878 return m;
2893−
28942879 }
28952880
28962881 static struct ceph_msg *alloc_msg(struct ceph_connection *con,
net/ceph/osdmap.c+1−1
@@ -1300,7 +1300,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, · 1299 unmodified lines
13001300 ceph_decode_addr(&addr);
13011301 pr_info("osd%d up\n", osd);
13021302 BUG_ON(osd >= map->max_osd);
1303− map->osd_state[osd] |= CEPH_OSD_UP;
1303+ map->osd_state[osd] |= CEPH_OSD_UP | CEPH_OSD_EXISTS;
13041304 map->osd_addr[osd] = addr;
13051305 }
13061306