]> err.no Git - linux-2.6/blobdiff - fs/ocfs2/cluster/tcp.c
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[linux-2.6] / fs / ocfs2 / cluster / tcp.c
index 4ea4b0a269757371792bbec19993600477782c75..a27d61581bd6fa299fc017c04fb405538664520c 100644 (file)
@@ -142,23 +142,55 @@ static void o2net_idle_timer(unsigned long data);
 static void o2net_sc_postpone_idle(struct o2net_sock_container *sc);
 static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc);
 
-/*
- * FIXME: These should use to_o2nm_cluster_from_node(), but we end up
- * losing our parent link to the cluster during shutdown. This can be
- * solved by adding a pre-removal callback to configfs, or passing
- * around the cluster with the node. -jeffm
- */
-static inline int o2net_reconnect_delay(struct o2nm_node *node)
+#ifdef CONFIG_DEBUG_FS
+void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
+                   u32 msgkey, struct task_struct *task, u8 node)
+{
+       INIT_LIST_HEAD(&nst->st_net_debug_item);
+       nst->st_task = task;
+       nst->st_msg_type = msgtype;
+       nst->st_msg_key = msgkey;
+       nst->st_node = node;
+}
+
+void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
+{
+       do_gettimeofday(&nst->st_sock_time);
+}
+
+void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
+{
+       do_gettimeofday(&nst->st_send_time);
+}
+
+void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
+{
+       do_gettimeofday(&nst->st_status_time);
+}
+
+void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
+                                        struct o2net_sock_container *sc)
+{
+       nst->st_sc = sc;
+}
+
+void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, u32 msg_id)
+{
+       nst->st_id = msg_id;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static inline int o2net_reconnect_delay(void)
 {
        return o2nm_single_cluster->cl_reconnect_delay_ms;
 }
 
-static inline int o2net_keepalive_delay(struct o2nm_node *node)
+static inline int o2net_keepalive_delay(void)
 {
        return o2nm_single_cluster->cl_keepalive_delay_ms;
 }
 
-static inline int o2net_idle_timeout(struct o2nm_node *node)
+static inline int o2net_idle_timeout(void)
 {
        return o2nm_single_cluster->cl_idle_timeout_ms;
 }
@@ -296,6 +328,7 @@ static void sc_kref_release(struct kref *kref)
        o2nm_node_put(sc->sc_node);
        sc->sc_node = NULL;
 
+       o2net_debug_del_sc(sc);
        kfree(sc);
 }
 
@@ -336,6 +369,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
 
        ret = sc;
        sc->sc_page = page;
+       o2net_debug_add_sc(sc);
        sc = NULL;
        page = NULL;
 
@@ -444,9 +478,9 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                /* delay if we're withing a RECONNECT_DELAY of the
                 * last attempt */
                delay = (nn->nn_last_connect_attempt +
-                        msecs_to_jiffies(o2net_reconnect_delay(NULL)))
+                        msecs_to_jiffies(o2net_reconnect_delay()))
                        - jiffies;
-               if (delay > msecs_to_jiffies(o2net_reconnect_delay(NULL)))
+               if (delay > msecs_to_jiffies(o2net_reconnect_delay()))
                        delay = 0;
                mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay);
                queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay);
@@ -460,7 +494,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                 * the connect_expired work will do anything.  The rest will see
                 * that it's already queued and do nothing.
                 */
-               delay += msecs_to_jiffies(o2net_idle_timeout(NULL));
+               delay += msecs_to_jiffies(o2net_idle_timeout());
                queue_delayed_work(o2net_wq, &nn->nn_connect_expired, delay);
        }
 
@@ -919,6 +953,9 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
        struct o2net_status_wait nsw = {
                .ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item),
        };
+       struct o2net_send_tracking nst;
+
+       o2net_init_nst(&nst, msg_type, key, current, target_node);
 
        if (o2net_wq == NULL) {
                mlog(0, "attempt to tx without o2netd running\n");
@@ -944,6 +981,10 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                goto out;
        }
 
+       o2net_debug_add_nst(&nst);
+
+       o2net_set_nst_sock_time(&nst);
+
        ret = wait_event_interruptible(nn->nn_sc_wq,
                                       o2net_tx_can_proceed(nn, &sc, &error));
        if (!ret && error)
@@ -951,6 +992,8 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
        if (ret)
                goto out;
 
+       o2net_set_nst_sock_container(&nst, sc);
+
        veclen = caller_veclen + 1;
        vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC);
        if (vec == NULL) {
@@ -977,6 +1020,9 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                goto out;
 
        msg->msg_num = cpu_to_be32(nsw.ns_id);
+       o2net_set_nst_msg_id(&nst, nsw.ns_id);
+
+       o2net_set_nst_send_time(&nst);
 
        /* finally, convert the message header to network byte-order
         * and send */
@@ -991,6 +1037,7 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
        }
 
        /* wait on other node's handler */
+       o2net_set_nst_status_time(&nst);
        wait_event(nsw.ns_wq, o2net_nsw_completed(nn, &nsw));
 
        /* Note that we avoid overwriting the callers status return
@@ -1003,6 +1050,7 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
        mlog(0, "woken, returning system status %d, user status %d\n",
             ret, nsw.ns_status);
 out:
+       o2net_debug_del_nst(&nst); /* must be before dropping sc and node */
        if (sc)
                sc_put(sc);
        if (vec)
@@ -1159,23 +1207,23 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
         * but isn't. This can ultimately cause corruption.
         */
        if (be32_to_cpu(hand->o2net_idle_timeout_ms) !=
-                               o2net_idle_timeout(sc->sc_node)) {
+                               o2net_idle_timeout()) {
                mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of "
                     "%u ms, but we use %u ms locally.  disconnecting\n",
                     SC_NODEF_ARGS(sc),
                     be32_to_cpu(hand->o2net_idle_timeout_ms),
-                    o2net_idle_timeout(sc->sc_node));
+                    o2net_idle_timeout());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2net_keepalive_delay_ms) !=
-                       o2net_keepalive_delay(sc->sc_node)) {
+                       o2net_keepalive_delay()) {
                mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of "
                     "%u ms, but we use %u ms locally.  disconnecting\n",
                     SC_NODEF_ARGS(sc),
                     be32_to_cpu(hand->o2net_keepalive_delay_ms),
-                    o2net_keepalive_delay(sc->sc_node));
+                    o2net_keepalive_delay());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
@@ -1353,12 +1401,11 @@ static void o2net_initialize_handshake(void)
 {
        o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32(
                O2HB_MAX_WRITE_TIMEOUT_MS);
-       o2net_hand->o2net_idle_timeout_ms = cpu_to_be32(
-               o2net_idle_timeout(NULL));
+       o2net_hand->o2net_idle_timeout_ms = cpu_to_be32(o2net_idle_timeout());
        o2net_hand->o2net_keepalive_delay_ms = cpu_to_be32(
-               o2net_keepalive_delay(NULL));
+               o2net_keepalive_delay());
        o2net_hand->o2net_reconnect_delay_ms = cpu_to_be32(
-               o2net_reconnect_delay(NULL));
+               o2net_reconnect_delay());
 }
 
 /* ------------------------------------------------------------ */
@@ -1404,8 +1451,8 @@ static void o2net_idle_timer(unsigned long data)
 
        printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
             "seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
-                    o2net_idle_timeout(sc->sc_node) / 1000,
-                    o2net_idle_timeout(sc->sc_node) % 1000);
+                    o2net_idle_timeout() / 1000,
+                    o2net_idle_timeout() % 1000);
        mlog(ML_NOTICE, "here are some times that might help debug the "
             "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv "
             "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n",
@@ -1433,10 +1480,10 @@ static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc)
 {
        o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
        o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work,
-                     msecs_to_jiffies(o2net_keepalive_delay(sc->sc_node)));
+                     msecs_to_jiffies(o2net_keepalive_delay()));
        do_gettimeofday(&sc->sc_tv_timer);
        mod_timer(&sc->sc_idle_timeout,
-              jiffies + msecs_to_jiffies(o2net_idle_timeout(sc->sc_node)));
+              jiffies + msecs_to_jiffies(o2net_idle_timeout()));
 }
 
 static void o2net_sc_postpone_idle(struct o2net_sock_container *sc)
@@ -1578,8 +1625,8 @@ static void o2net_connect_expired(struct work_struct *work)
                mlog(ML_ERROR, "no connection established with node %u after "
                     "%u.%u seconds, giving up and returning errors.\n",
                     o2net_num_from_nn(nn),
-                    o2net_idle_timeout(NULL) / 1000,
-                    o2net_idle_timeout(NULL) % 1000);
+                    o2net_idle_timeout() / 1000,
+                    o2net_idle_timeout() % 1000);
 
                o2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
        }
@@ -1634,7 +1681,7 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
 
        /* ensure an immediate connect attempt */
        nn->nn_last_connect_attempt = jiffies -
-               (msecs_to_jiffies(o2net_reconnect_delay(node)) + 1);
+               (msecs_to_jiffies(o2net_reconnect_delay()) + 1);
 
        if (node_num != o2nm_this_node()) {
                /* believe it or not, accept and node hearbeating testing
@@ -1942,6 +1989,9 @@ int o2net_init(void)
 
        o2quo_init();
 
+       if (o2net_debugfs_init())
+               return -ENOMEM;
+
        o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL);
        o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
        o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
@@ -1983,4 +2033,5 @@ void o2net_exit(void)
        kfree(o2net_hand);
        kfree(o2net_keep_req);
        kfree(o2net_keep_resp);
+       o2net_debugfs_exit();
 }