#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/kref.h>
+#include <linux/net.h>
#include <net/tcp.h>
#include <asm/uaccess.h>
#include "tcp_internal.h"
-/*
- * The linux network stack isn't sparse endian clean.. It has macros like
- * ntohs() which perform the endian checks and structs like sockaddr_in
- * which aren't annotated. So __force is found here to get the build
- * clean. When they emerge from the dark ages and annotate the code
- * we can remove these.
- */
-
#define SC_NODEF_FMT "node %s (num %u) at %u.%u.%u.%u:%u"
#define SC_NODEF_ARGS(sc) sc->sc_node->nd_name, sc->sc_node->nd_num, \
NIPQUAD(sc->sc_node->nd_ipv4_address), \
static void o2net_complete_nodes_nsw(struct o2net_node *nn)
{
- struct list_head *iter, *tmp;
+ struct o2net_status_wait *nsw, *tmp;
unsigned int num_kills = 0;
- struct o2net_status_wait *nsw;
assert_spin_locked(&nn->nn_lock);
- list_for_each_safe(iter, tmp, &nn->nn_status_list) {
- nsw = list_entry(iter, struct o2net_status_wait, ns_node_item);
+ list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) {
o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0);
num_kills++;
}
/* delay if we're withing a RECONNECT_DELAY of the
* last attempt */
delay = (nn->nn_last_connect_attempt +
- msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node)))
+ msecs_to_jiffies(o2net_reconnect_delay(NULL)))
- jiffies;
- if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node)))
+ if (delay > msecs_to_jiffies(o2net_reconnect_delay(NULL)))
delay = 0;
mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay);
queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay);
del_timer_sync(&sc->sc_idle_timeout);
o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
sc_put(sc);
- sc->sc_sock->ops->shutdown(sc->sc_sock,
- RCV_SHUTDOWN|SEND_SHUTDOWN);
+ kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR);
}
/* not fatal so failed connects before the other guy has our
void o2net_unregister_handler_list(struct list_head *list)
{
- struct list_head *pos, *n;
- struct o2net_msg_handler *nmh;
+ struct o2net_msg_handler *nmh, *n;
write_lock(&o2net_handler_lock);
- list_for_each_safe(pos, n, list) {
- nmh = list_entry(pos, struct o2net_msg_handler,
- nh_unregister_item);
+ list_for_each_entry_safe(nmh, n, list, nh_unregister_item) {
mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n",
nmh->nh_func, nmh->nh_msg_type, nmh->nh_key);
rb_erase(&nmh->nh_node, &o2net_handler_tree);
struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
ssize_t ret;
-
- mutex_lock(&sc->sc_send_lock);
- ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
- virt_to_page(kmalloced_virt),
- (long)kmalloced_virt & ~PAGE_MASK,
- size, MSG_DONTWAIT);
- mutex_unlock(&sc->sc_send_lock);
- if (ret != size) {
+ while (1) {
+ mutex_lock(&sc->sc_send_lock);
+ ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
+ virt_to_page(kmalloced_virt),
+ (long)kmalloced_virt & ~PAGE_MASK,
+ size, MSG_DONTWAIT);
+ mutex_unlock(&sc->sc_send_lock);
+ if (ret == size)
+ break;
+ if (ret == (ssize_t)-EAGAIN) {
+ mlog(0, "sendpage of size %zu to " SC_NODEF_FMT
+ " returned EAGAIN\n", size, SC_NODEF_ARGS(sc));
+ cond_resched();
+ continue;
+ }
mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT
" failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
o2net_ensure_shutdown(nn, sc, 0);
+ break;
}
}
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = mynode->nd_ipv4_address;
- myaddr.sin_port = (__force u16)htons(0); /* any port */
+ myaddr.sin_port = htons(0); /* any port */
ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr,
sizeof(myaddr));
spin_lock(&nn->nn_lock);
if (!nn->nn_sc_valid) {
- struct o2nm_node *node = nn->nn_sc->sc_node;
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(node) / 1000,
- o2net_idle_timeout(node) % 1000);
+ o2net_idle_timeout(NULL) / 1000,
+ o2net_idle_timeout(NULL) % 1000);
o2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
}
if (ret < 0)
goto out;
- node = o2nm_get_node_by_ip((__force __be32)sin.sin_addr.s_addr);
+ node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
if (node == NULL) {
mlog(ML_NOTICE, "attempt to connect from unknown node at "
"%u.%u.%u.%u:%d\n", NIPQUAD(sin.sin_addr.s_addr),
- ntohs((__force __be16)sin.sin_port));
+ ntohs(sin.sin_port));
ret = -EINVAL;
goto out;
}
mlog(ML_NOTICE, "unexpected connect attempted from a lower "
"numbered node '%s' at " "%u.%u.%u.%u:%d with num %u\n",
node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
- ntohs((__force __be16)sin.sin_port), node->nd_num);
+ ntohs(sin.sin_port), node->nd_num);
ret = -EINVAL;
goto out;
}
mlog(ML_CONN, "attempt to connect from node '%s' at "
"%u.%u.%u.%u:%d but it isn't heartbeating\n",
node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
- ntohs((__force __be16)sin.sin_port));
+ ntohs(sin.sin_port));
ret = -EINVAL;
goto out;
}
mlog(ML_NOTICE, "attempt to connect from node '%s' at "
"%u.%u.%u.%u:%d but it already has an open connection\n",
node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
- ntohs((__force __be16)sin.sin_port));
+ ntohs(sin.sin_port));
goto out;
}