History

ceph: add flag to designate that a request is asynchronous

...and ensure that such requests are never queued. The MDS has need to know that a request is asynchronous so add flags and proper infrastructure for that. Also, delegated inode numbers and directory caps are associated with the session, so ensure that async requests are always transmitted on the first attempt and are never queued to wait for session reestablishment. If it does end up looking like we'll need to queue the request, then have it return -EJUKEBOX so the caller can reattempt with a synchronous request.

Jeff Layton committed 6 years ago

Commit 3bb48b41 parent c7e4f854 files · +20 −2Browse files

Unified · Split

4 files
  1. fs/ceph/inode.c +1 −0
  2. fs/ceph/mds_client.c +15 −0
  3. fs/ceph/mds_client.h +1 −0
  4. include/linux/ceph/ceph_fs.h +3 −2
fs/ceph/inode.c+1−0
@@ -1311,6 +1311,7 @@ retry_lookup: · 1310 unmodified lines
1311 err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL,1311 err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL,
1312 session,1312 session,
1313 (!test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags) &&1313 (!test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags) &&
1314 !test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags) &&
1314 rinfo->head->result == 0) ? req->r_fmode : -1,1315 rinfo->head->result == 0) ? req->r_fmode : -1,
1315 &req->r_caps_reservation);1316 &req->r_caps_reservation);
1316 if (err < 0) {1317 if (err < 0) {
fs/ceph/mds_client.c+15−0
@@ -2528,6 +2528,8 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc, · 2527 unmodified lines
2528 rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));2528 rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));
2529 if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags))2529 if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags))
2530 flags |= CEPH_MDS_FLAG_REPLAY;2530 flags |= CEPH_MDS_FLAG_REPLAY;
2531 if (test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags))
2532 flags |= CEPH_MDS_FLAG_ASYNC;
2531 if (req->r_parent)2533 if (req->r_parent)
2532 flags |= CEPH_MDS_FLAG_WANT_DENTRY;2534 flags |= CEPH_MDS_FLAG_WANT_DENTRY;
2533 rhead->flags = cpu_to_le32(flags);2535 rhead->flags = cpu_to_le32(flags);
@@ -2611,6 +2613,10 @@ static void __do_request(struct ceph_mds_client *mdsc, · 77 unmodified lines
2611 mds = __choose_mds(mdsc, req, &random);2613 mds = __choose_mds(mdsc, req, &random);
2612 if (mds < 0 ||2614 if (mds < 0 ||
2613 ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {2615 ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
2616 if (test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags)) {
2617 err = -EJUKEBOX;
2618 goto finish;
2619 }
2614 dout("do_request no mds or not active, waiting for map\n");2620 dout("do_request no mds or not active, waiting for map\n");
2615 list_add(&req->r_wait, &mdsc->waiting_for_map);2621 list_add(&req->r_wait, &mdsc->waiting_for_map);
2616 return;2622 return;
@@ -2635,6 +2641,15 @@ static void __do_request(struct ceph_mds_client *mdsc, · 18 unmodified lines
2635 err = -EACCES;2641 err = -EACCES;
2636 goto out_session;2642 goto out_session;
2637 }2643 }
2644 /*
2645 * We cannot queue async requests since the caps and delegated
2646 * inodes are bound to the session. Just return -EJUKEBOX and
2647 * let the caller retry a sync request in that case.
2648 */
2649 if (test_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags)) {
2650 err = -EJUKEBOX;
2651 goto out_session;
2652 }
2638 if (session->s_state == CEPH_MDS_SESSION_NEW ||2653 if (session->s_state == CEPH_MDS_SESSION_NEW ||
2639 session->s_state == CEPH_MDS_SESSION_CLOSING) {2654 session->s_state == CEPH_MDS_SESSION_CLOSING) {
2640 __open_session(mdsc, session);2655 __open_session(mdsc, session);
fs/ceph/mds_client.h+1−0
@@ -255,6 +255,7 @@ struct ceph_mds_request { · 254 unmodified lines
255#define CEPH_MDS_R_GOT_RESULT (5) /* got a result */255#define CEPH_MDS_R_GOT_RESULT (5) /* got a result */
256#define CEPH_MDS_R_DID_PREPOPULATE (6) /* prepopulated readdir */256#define CEPH_MDS_R_DID_PREPOPULATE (6) /* prepopulated readdir */
257#define CEPH_MDS_R_PARENT_LOCKED (7) /* is r_parent->i_rwsem wlocked? */257#define CEPH_MDS_R_PARENT_LOCKED (7) /* is r_parent->i_rwsem wlocked? */
258#define CEPH_MDS_R_ASYNC (8) /* async request */
258 unsigned long r_req_flags;259 unsigned long r_req_flags;
259 260
260 struct mutex r_fill_mutex;261 struct mutex r_fill_mutex;
include/linux/ceph/ceph_fs.h+3−2
@@ -444,8 +444,9 @@ union ceph_mds_request_args { · 443 unmodified lines
444 } __attribute__ ((packed)) lookupino;444 } __attribute__ ((packed)) lookupino;
445} __attribute__ ((packed));445} __attribute__ ((packed));
446 446
447#define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */447#define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */
448#define CEPH_MDS_FLAG_WANT_DENTRY 2 /* want dentry in reply */448#define CEPH_MDS_FLAG_WANT_DENTRY 2 /* want dentry in reply */
449#define CEPH_MDS_FLAG_ASYNC 4 /* request is asynchronous */
449 450
450struct ceph_mds_request_head {451struct ceph_mds_request_head {
451 __le64 oldest_client_tid;452 __le64 oldest_client_tid;