diff options
Diffstat (limited to 'fs/ocfs2/cluster/tcp.c')
-rw-r--r-- | fs/ocfs2/cluster/tcp.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 681691bc233a..ea34952f9496 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -1480,6 +1480,14 @@ static int o2net_set_nodelay(struct socket *sock) | |||
1480 | return ret; | 1480 | return ret; |
1481 | } | 1481 | } |
1482 | 1482 | ||
1483 | static int o2net_set_usertimeout(struct socket *sock) | ||
1484 | { | ||
1485 | int user_timeout = O2NET_TCP_USER_TIMEOUT; | ||
1486 | |||
1487 | return kernel_setsockopt(sock, SOL_TCP, TCP_USER_TIMEOUT, | ||
1488 | (char *)&user_timeout, sizeof(user_timeout)); | ||
1489 | } | ||
1490 | |||
1483 | static void o2net_initialize_handshake(void) | 1491 | static void o2net_initialize_handshake(void) |
1484 | { | 1492 | { |
1485 | o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32( | 1493 | o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32( |
@@ -1536,16 +1544,20 @@ static void o2net_idle_timer(unsigned long data) | |||
1536 | #endif | 1544 | #endif |
1537 | 1545 | ||
1538 | printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been " | 1546 | printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been " |
1539 | "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc), | 1547 | "idle for %lu.%lu secs.\n", |
1540 | msecs / 1000, msecs % 1000); | 1548 | SC_NODEF_ARGS(sc), msecs / 1000, msecs % 1000); |
1541 | 1549 | ||
1542 | /* | 1550 | /* idle timerout happen, don't shutdown the connection, but |
1543 | * Initialize the nn_timeout so that the next connection attempt | 1551 | * make fence decision. Maybe the connection can recover before |
1544 | * will continue in o2net_start_connect. | 1552 | * the decision is made. |
1545 | */ | 1553 | */ |
1546 | atomic_set(&nn->nn_timeout, 1); | 1554 | atomic_set(&nn->nn_timeout, 1); |
1555 | o2quo_conn_err(o2net_num_from_nn(nn)); | ||
1556 | queue_delayed_work(o2net_wq, &nn->nn_still_up, | ||
1557 | msecs_to_jiffies(O2NET_QUORUM_DELAY_MS)); | ||
1558 | |||
1559 | o2net_sc_reset_idle_timer(sc); | ||
1547 | 1560 | ||
1548 | o2net_sc_queue_work(sc, &sc->sc_shutdown_work); | ||
1549 | } | 1561 | } |
1550 | 1562 | ||
1551 | static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) | 1563 | static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) |
@@ -1560,6 +1572,15 @@ static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) | |||
1560 | 1572 | ||
1561 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) | 1573 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) |
1562 | { | 1574 | { |
1575 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); | ||
1576 | |||
1577 | /* clear fence decision since the connection recover from timeout*/ | ||
1578 | if (atomic_read(&nn->nn_timeout)) { | ||
1579 | o2quo_conn_up(o2net_num_from_nn(nn)); | ||
1580 | cancel_delayed_work(&nn->nn_still_up); | ||
1581 | atomic_set(&nn->nn_timeout, 0); | ||
1582 | } | ||
1583 | |||
1563 | /* Only push out an existing timer */ | 1584 | /* Only push out an existing timer */ |
1564 | if (timer_pending(&sc->sc_idle_timeout)) | 1585 | if (timer_pending(&sc->sc_idle_timeout)) |
1565 | o2net_sc_reset_idle_timer(sc); | 1586 | o2net_sc_reset_idle_timer(sc); |
@@ -1650,6 +1671,12 @@ static void o2net_start_connect(struct work_struct *work) | |||
1650 | goto out; | 1671 | goto out; |
1651 | } | 1672 | } |
1652 | 1673 | ||
1674 | ret = o2net_set_usertimeout(sock); | ||
1675 | if (ret) { | ||
1676 | mlog(ML_ERROR, "set TCP_USER_TIMEOUT failed with %d\n", ret); | ||
1677 | goto out; | ||
1678 | } | ||
1679 | |||
1653 | o2net_register_callbacks(sc->sc_sock->sk, sc); | 1680 | o2net_register_callbacks(sc->sc_sock->sk, sc); |
1654 | 1681 | ||
1655 | spin_lock(&nn->nn_lock); | 1682 | spin_lock(&nn->nn_lock); |
@@ -1831,6 +1858,12 @@ static int o2net_accept_one(struct socket *sock, int *more) | |||
1831 | goto out; | 1858 | goto out; |
1832 | } | 1859 | } |
1833 | 1860 | ||
1861 | ret = o2net_set_usertimeout(new_sock); | ||
1862 | if (ret) { | ||
1863 | mlog(ML_ERROR, "set TCP_USER_TIMEOUT failed with %d\n", ret); | ||
1864 | goto out; | ||
1865 | } | ||
1866 | |||
1834 | slen = sizeof(sin); | 1867 | slen = sizeof(sin); |
1835 | ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, | 1868 | ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, |
1836 | &slen, 1); | 1869 | &slen, 1); |