summary refs log tree commit diff
path: root/net
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-01-23 15:57:51 +0100
committerIlya Dryomov <idryomov@gmail.com>2016-03-25 18:51:40 +0100
commitb5d91704f53efc5a2a93e88e323877e6889b0f5b (patch)
tree16dcc0c8a99d937f412e0986a33591c21cf33aa4 /net
parentbee3a37c470e4febcb05556ceafcb70929268edd (diff)
downloadlinux-b5d91704f53efc5a2a93e88e323877e6889b0f5b.tar.gz
libceph: behave in mon_fault() if cur_mon < 0
This can happen if __close_session() in ceph_monc_stop() races with
a connection reset.  We need to ignore such faults, otherwise it's
likely we would take !hunting, call __schedule_delayed() and end up
with delayed_work() executing on invalid memory, among other things.

The (two!) con->private tests are useless, as nothing ever clears
con->private.  Nuke them.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/mon_client.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index a2b45cf79dca..cf638c009cfa 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -1155,22 +1155,17 @@ static void mon_fault(struct ceph_connection *con)
 {
 	struct ceph_mon_client *monc = con->private;
 
-	if (!monc)
-		return;
-
-	dout("mon_fault\n");
 	mutex_lock(&monc->mutex);
-	if (!con->private)
-		goto out;
-
-	if (!monc->hunting) {
-		dout("%s hunting for new mon\n", __func__);
-		reopen_session(monc);
-		__schedule_delayed(monc);
-	} else {
-		dout("%s already hunting\n", __func__);
+	dout("%s mon%d\n", __func__, monc->cur_mon);
+	if (monc->cur_mon >= 0) {
+		if (!monc->hunting) {
+			dout("%s hunting for new mon\n", __func__);
+			reopen_session(monc);
+			__schedule_delayed(monc);
+		} else {
+			dout("%s already hunting\n", __func__);
+		}
 	}
-out:
 	mutex_unlock(&monc->mutex);
 }