/*
- * Atomically queue work on a connection.  Bump @con reference to
- * avoid races with connection teardown.
+ * Atomically queue work on a connection after the specified delay.
+ * Bump @con reference to avoid races with connection teardown.
+ * Returns 0 if work was queued, or an error code otherwise.
  */
-static void queue_con(struct ceph_connection *con)
+static int queue_con_delay(struct ceph_connection *con, unsigned long delay)
 {
        if (!con->ops->get(con)) {
-               dout("queue_con %p ref count 0\n", con);
-               return;
+               dout("%s %p ref count 0\n", __func__, con);
+
+               return -ENOENT;
        }
 
-       if (!queue_delayed_work(ceph_msgr_wq, &con->work, 0)) {
-               dout("queue_con %p - already queued\n", con);
+       if (!queue_delayed_work(ceph_msgr_wq, &con->work, delay)) {
+               dout("%s %p - already queued\n", __func__, con);
                con->ops->put(con);
-       } else {
-               dout("queue_con %p\n", con);
+
+               return -EBUSY;
        }
+
+       dout("%s %p %lu\n", __func__, con, delay);
+
+       return 0;
+}
+
+static void queue_con(struct ceph_connection *con)
+{
+       (void) queue_con_delay(con, 0);
 }
 
 /*
 
        if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) {
                dout("con_work %p backing off\n", con);
-               if (queue_delayed_work(ceph_msgr_wq, &con->work,
-                                      round_jiffies_relative(con->delay))) {
-                       dout("con_work %p backoff %lu\n", con, con->delay);
-                       mutex_unlock(&con->mutex);
-                       return;
-               } else {
+               ret = queue_con_delay(con, round_jiffies_relative(con->delay));
+               if (ret) {
                        dout("con_work %p FAILED to back off %lu\n", con,
                             con->delay);
+                       BUG_ON(ret == -ENOENT);
                        set_bit(CON_FLAG_BACKOFF, &con->flags);
                }
                goto done;