this avoid force umount getting stuck at ceph_osdc_sync() Signed-off-by: "Yan, Zheng" <zyan@xxxxxxxxxx> --- fs/ceph/super.c | 1 + include/linux/ceph/osd_client.h | 5 ++++- net/ceph/osd_client.c | 43 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 3c1155803444..40664e13cc0f 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -793,6 +793,7 @@ static void ceph_umount_begin(struct super_block *sb) if (!fsc) return; fsc->mount_state = CEPH_MOUNT_SHUTDOWN; + ceph_osdc_abort_requests(&fsc->client->osdc, -EIO); ceph_mdsc_force_umount(fsc->mdsc); return; } diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index b73dd7ebe585..f61736963236 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -347,6 +347,7 @@ struct ceph_osd_client { struct rb_root linger_map_checks; atomic_t num_requests; atomic_t num_homeless; + int abort_code; struct delayed_work timeout_work; struct delayed_work osds_timeout_work; #ifdef CONFIG_DEBUG_FS @@ -377,7 +378,9 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg); extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg); -void ceph_osdc_update_epoch_barrier(struct ceph_osd_client *osdc, u32 eb); +extern void ceph_osdc_update_epoch_barrier(struct ceph_osd_client *osdc, u32); +extern void ceph_osdc_abort_requests(struct ceph_osd_client *osdc, + int err_code); extern void osd_req_op_init(struct ceph_osd_request *osd_req, unsigned int which, u16 opcode, u32 flags); diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 08b5fc1f90cc..959af0e165ba 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -2165,9 +2165,9 @@ static void __submit_request(struct ceph_osd_request *req, bool wrlocked) struct ceph_osd_client *osdc = req->r_osdc; struct ceph_osd *osd; enum calc_target_result ct_res; + bool abort_code = 0; bool need_send = false; bool promoted = false; - bool need_abort = false; WARN_ON(req->r_tid); dout("%s req %p wrlocked %d\n", __func__, req, wrlocked); @@ -2183,7 +2183,9 @@ static void __submit_request(struct ceph_osd_request *req, bool wrlocked) goto promote; } - if (osdc->osdmap->epoch < osdc->epoch_barrier) { + if (osdc->abort_code) { + abort_code = osdc->abort_code; + } else if (osdc->osdmap->epoch < osdc->epoch_barrier) { dout("req %p epoch %u barrier %u\n", req, osdc->osdmap->epoch, osdc->epoch_barrier); req->r_t.paused = true; @@ -2208,7 +2210,7 @@ static void __submit_request(struct ceph_osd_request *req, bool wrlocked) req->r_t.paused = true; maybe_request_map(osdc); if (req->r_abort_on_full) - need_abort = true; + abort_code = -ENOSPC; } else if (!osd_homeless(osd)) { need_send = true; } else { @@ -2225,8 +2227,8 @@ static void __submit_request(struct ceph_osd_request *req, bool wrlocked) link_request(osd, req); if (need_send) send_request(req); - else if (need_abort) - complete_request(req, -ENOSPC); + else if (abort_code) + complete_request(req, abort_code); mutex_unlock(&osd->lock); if (ct_res == CALC_TARGET_POOL_DNE) @@ -2366,6 +2368,37 @@ void ceph_osdc_update_epoch_barrier(struct ceph_osd_client *osdc, u32 eb) } EXPORT_SYMBOL(ceph_osdc_update_epoch_barrier); +void ceph_osdc_abort_requests(struct ceph_osd_client *osdc, int err_code) +{ + struct rb_node *n, *m; + struct ceph_osd *osd; + struct ceph_osd_request *req; + + dout("%s err_code %d\n", __func__, err_code); + + down_write(&osdc->lock); + osdc->abort_code = err_code; + + for (n = rb_first(&osdc->osds); n; n = rb_next(n)) { + osd = rb_entry(n, struct ceph_osd, o_node); + m = rb_first(&osd->o_requests); + while (m) { + req = rb_entry(m, struct ceph_osd_request, r_node); + m = rb_next(m); + abort_request(req, err_code); + } + } + + m = rb_first(&osdc->homeless_osd.o_requests); + while (m) { + req = rb_entry(m, struct ceph_osd_request, r_node); + m = rb_next(m); + abort_request(req, err_code); + } + up_write(&osdc->lock); +} +EXPORT_SYMBOL(ceph_osdc_abort_requests); + /* * Drop all pending requests that are stalled waiting on a full condition to * clear, and complete them with ENOSPC as the return code. Set the -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html