libceph: behave in mon_fault() if cur_mon < 0
authorIlya Dryomov <idryomov@gmail.com>
Sat, 23 Jan 2016 14:57:51 +0000 (15:57 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 25 Mar 2016 17:51:40 +0000 (18:51 +0100)
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>
net/ceph/mon_client.c

index a2b45cf..cf638c0 100644 (file)
@@ -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);
 }