[PATCH] ceph: abort osd requests on force umount

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux