summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-04-12 13:49:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-12 13:49:28 -0400
commit8065248069097dddf9945acfb2081025e9618c16 (patch)
treeeddf3fb0372ba0f65c01382d386942ea8d18932d /net
parente66a8ddff72e85605f2212a0ebc666c7e9116641 (diff)
parentb4838d12e1f3cb48c2489a0b08733b5dbf848297 (diff)
downloadlinux-8065248069097dddf9945acfb2081025e9618c16.tar.bz2
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Diffstat (limited to 'net')
-rw-r--r--net/802/fc.c1
-rw-r--r--net/802/fddi.c1
-rw-r--r--net/802/garp.c22
-rw-r--r--net/802/hippi.c1
-rw-r--r--net/802/tr.c1
-rw-r--r--net/9p/client.c26
-rw-r--r--net/atm/clip.c1
-rw-r--r--net/ax25/af_ax25.c1
-rw-r--r--net/ax25/ax25_addr.c1
-rw-r--r--net/ax25/ax25_dev.c1
-rw-r--r--net/ax25/ax25_ds_in.c1
-rw-r--r--net/ax25/ax25_ds_subr.c1
-rw-r--r--net/ax25/ax25_ds_timer.c1
-rw-r--r--net/ax25/ax25_iface.c1
-rw-r--r--net/ax25/ax25_in.c1
-rw-r--r--net/ax25/ax25_ip.c1
-rw-r--r--net/ax25/ax25_out.c1
-rw-r--r--net/ax25/ax25_route.c1
-rw-r--r--net/ax25/ax25_std_in.c1
-rw-r--r--net/ax25/ax25_std_subr.c1
-rw-r--r--net/ax25/ax25_std_timer.c1
-rw-r--r--net/ax25/ax25_subr.c1
-rw-r--r--net/ax25/ax25_timer.c1
-rw-r--r--net/ax25/ax25_uid.c1
-rw-r--r--net/bluetooth/bnep/sock.c1
-rw-r--r--net/bluetooth/cmtp/sock.c1
-rw-r--r--net/bluetooth/hci_conn.c1
-rw-r--r--net/bluetooth/hci_core.c8
-rw-r--r--net/bluetooth/hci_event.c1
-rw-r--r--net/bluetooth/hci_sock.c4
-rw-r--r--net/bluetooth/l2cap_core.c4
-rw-r--r--net/bluetooth/l2cap_sock.c5
-rw-r--r--net/bluetooth/mgmt.c13
-rw-r--r--net/bluetooth/rfcomm/sock.c1
-rw-r--r--net/bluetooth/sco.c1
-rw-r--r--net/ceph/ceph_common.c26
-rw-r--r--net/ceph/messenger.c456
-rw-r--r--net/ceph/osdmap.c3
-rw-r--r--net/compat.c65
-rw-r--r--net/core/datagram.c1
-rw-r--r--net/core/dev.c60
-rw-r--r--net/core/dev_addr_lists.c3
-rw-r--r--net/core/filter.c10
-rw-r--r--net/core/gen_estimator.c1
-rw-r--r--net/core/rtnetlink.c1
-rw-r--r--net/core/scm.c1
-rw-r--r--net/core/skbuff.c5
-rw-r--r--net/core/sock.c1
-rw-r--r--net/core/utils.c1
-rw-r--r--net/decnet/af_decnet.c1
-rw-r--r--net/decnet/dn_dev.c1
-rw-r--r--net/decnet/dn_nsp_in.c1
-rw-r--r--net/decnet/dn_nsp_out.c1
-rw-r--r--net/econet/af_econet.c1
-rw-r--r--net/ethernet/eth.c1
-rw-r--r--net/ipv4/af_inet.c1
-rw-r--r--net/ipv4/arp.c1
-rw-r--r--net/ipv4/devinet.c1
-rw-r--r--net/ipv4/fib_frontend.c1
-rw-r--r--net/ipv4/fib_semantics.c1
-rw-r--r--net/ipv4/fib_trie.c1
-rw-r--r--net/ipv4/icmp.c1
-rw-r--r--net/ipv4/igmp.c1
-rw-r--r--net/ipv4/ip_input.c1
-rw-r--r--net/ipv4/ip_output.c1
-rw-r--r--net/ipv4/ipmr.c1
-rw-r--r--net/ipv4/ping.c1
-rw-r--r--net/ipv4/route.c3
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/udp.c1
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/icmp.c1
-rw-r--r--net/ipv6/ip6mr.c1
-rw-r--r--net/ipv6/mcast.c2
-rw-r--r--net/ipv6/route.c34
-rw-r--r--net/irda/irlan/irlan_client.c1
-rw-r--r--net/irda/irlan/irlan_common.c1
-rw-r--r--net/irda/irlan/irlan_provider.c1
-rw-r--r--net/irda/timer.c1
-rw-r--r--net/lapb/lapb_iface.c1
-rw-r--r--net/lapb/lapb_in.c1
-rw-r--r--net/lapb/lapb_out.c1
-rw-r--r--net/lapb/lapb_subr.c1
-rw-r--r--net/lapb/lapb_timer.c1
-rw-r--r--net/mac80211/debugfs.c12
-rw-r--r--net/mac80211/debugfs.h1
-rw-r--r--net/mac80211/debugfs_key.c4
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/debugfs_sta.c4
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/rate.c2
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_app.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c1
-rw-r--r--net/netfilter/nf_conntrack_core.c1
-rw-r--r--net/netfilter/nfnetlink.c1
-rw-r--r--net/netfilter/nfnetlink_acct.c2
-rw-r--r--net/netfilter/xt_CT.c28
-rw-r--r--net/netlink/af_netlink.c24
-rw-r--r--net/netrom/af_netrom.c1
-rw-r--r--net/netrom/nr_dev.c1
-rw-r--r--net/netrom/nr_in.c1
-rw-r--r--net/netrom/nr_out.c1
-rw-r--r--net/netrom/nr_route.c1
-rw-r--r--net/netrom/nr_subr.c1
-rw-r--r--net/netrom/nr_timer.c1
-rw-r--r--net/nfc/llcp/commands.c4
-rw-r--r--net/openvswitch/datapath.c1
-rw-r--r--net/packet/af_packet.c1
-rw-r--r--net/phonet/pep.c3
-rw-r--r--net/rose/af_rose.c1
-rw-r--r--net/rose/rose_dev.c5
-rw-r--r--net/rose/rose_in.c1
-rw-r--r--net/rose/rose_link.c1
-rw-r--r--net/rose/rose_out.c1
-rw-r--r--net/rose/rose_route.c1
-rw-r--r--net/rose/rose_subr.c1
-rw-r--r--net/rose/rose_timer.c1
-rw-r--r--net/sctp/socket.c5
-rw-r--r--net/socket.c24
-rw-r--r--net/sunrpc/cache.c2
-rw-r--r--net/sunrpc/clnt.c1
-rw-r--r--net/sunrpc/rpc_pipe.c5
-rw-r--r--net/sunrpc/rpcb_clnt.c2
-rw-r--r--net/sunrpc/svcauth_unix.c2
-rw-r--r--net/sunrpc/svcsock.c2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma.c1
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_marshal.c66
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c20
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c26
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c10
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h7
-rw-r--r--net/sunrpc/xprtsock.c1
-rw-r--r--net/wireless/debugfs.c10
-rw-r--r--net/wireless/nl80211.c31
-rw-r--r--net/wireless/wext-core.c6
136 files changed, 560 insertions, 593 deletions
diff --git a/net/802/fc.c b/net/802/fc.c
index bd345f3d29f8..b324e31401a9 100644
--- a/net/802/fc.c
+++ b/net/802/fc.c
@@ -11,7 +11,6 @@
*/
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/802/fddi.c b/net/802/fddi.c
index 94b3ad08f39a..5ab25cd4314b 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -27,7 +27,6 @@
*/
#include <linux/module.h>
-#include <asm/system.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/802/garp.c b/net/802/garp.c
index 8e21b6db3981..a5c224830439 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -167,7 +167,8 @@ static struct garp_attr *garp_attr_lookup(const struct garp_applicant *app,
return NULL;
}
-static void garp_attr_insert(struct garp_applicant *app, struct garp_attr *new)
+static struct garp_attr *garp_attr_create(struct garp_applicant *app,
+ const void *data, u8 len, u8 type)
{
struct rb_node *parent = NULL, **p = &app->gid.rb_node;
struct garp_attr *attr;
@@ -176,21 +177,16 @@ static void garp_attr_insert(struct garp_applicant *app, struct garp_attr *new)
while (*p) {
parent = *p;
attr = rb_entry(parent, struct garp_attr, node);
- d = garp_attr_cmp(attr, new->data, new->dlen, new->type);
+ d = garp_attr_cmp(attr, data, len, type);
if (d < 0)
p = &parent->rb_left;
else if (d > 0)
p = &parent->rb_right;
+ else {
+ /* The attribute already exists; re-use it. */
+ return attr;
+ }
}
- rb_link_node(&new->node, parent, p);
- rb_insert_color(&new->node, &app->gid);
-}
-
-static struct garp_attr *garp_attr_create(struct garp_applicant *app,
- const void *data, u8 len, u8 type)
-{
- struct garp_attr *attr;
-
attr = kmalloc(sizeof(*attr) + len, GFP_ATOMIC);
if (!attr)
return attr;
@@ -198,7 +194,9 @@ static struct garp_attr *garp_attr_create(struct garp_applicant *app,
attr->type = type;
attr->dlen = len;
memcpy(attr->data, data, len);
- garp_attr_insert(app, attr);
+
+ rb_link_node(&attr->node, parent, p);
+ rb_insert_color(&attr->node, &app->gid);
return attr;
}
diff --git a/net/802/hippi.c b/net/802/hippi.c
index 91aca8780fd0..056794e66375 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -35,7 +35,6 @@
#include <net/arp.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
/*
* Create the HIPPI MAC header for an arbitrary protocol layer
diff --git a/net/802/tr.c b/net/802/tr.c
index 5e20cf8a074b..b9a3a145e348 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -16,7 +16,6 @@
*/
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/9p/client.c b/net/9p/client.c
index 776618cd2be5..b23a17c431c8 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -740,10 +740,18 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
c->status = Disconnected;
goto reterr;
}
+again:
/* Wait for the response */
err = wait_event_interruptible(*req->wq,
req->status >= REQ_STATUS_RCVD);
+ if ((err == -ERESTARTSYS) && (c->status == Connected)
+ && (type == P9_TFLUSH)) {
+ sigpending = 1;
+ clear_thread_flag(TIF_SIGPENDING);
+ goto again;
+ }
+
if (req->status == REQ_STATUS_ERROR) {
p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
err = req->t_err;
@@ -1420,6 +1428,7 @@ int p9_client_clunk(struct p9_fid *fid)
int err;
struct p9_client *clnt;
struct p9_req_t *req;
+ int retries = 0;
if (!fid) {
pr_warn("%s (%d): Trying to clunk with NULL fid\n",
@@ -1428,7 +1437,9 @@ int p9_client_clunk(struct p9_fid *fid)
return 0;
}
- p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
+again:
+ p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
+ retries);
err = 0;
clnt = fid->clnt;
@@ -1444,8 +1455,14 @@ int p9_client_clunk(struct p9_fid *fid)
error:
/*
* Fid is not valid even after a failed clunk
+ * If interrupted, retry once then give up and
+ * leak fid until umount.
*/
- p9_fid_destroy(fid);
+ if (err == -ERESTARTSYS) {
+ if (retries++ == 0)
+ goto again;
+ } else
+ p9_fid_destroy(fid);
return err;
}
EXPORT_SYMBOL(p9_client_clunk);
@@ -1470,7 +1487,10 @@ int p9_client_remove(struct p9_fid *fid)
p9_free_req(clnt, req);
error:
- p9_fid_destroy(fid);
+ if (err == -ERESTARTSYS)
+ p9_client_clunk(fid);
+ else
+ p9_fid_destroy(fid);
return err;
}
EXPORT_SYMBOL(p9_client_remove);
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 5de42ea309bc..8ae3a7879335 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -37,7 +37,6 @@
#include <linux/param.h> /* for HZ */
#include <linux/uaccess.h>
#include <asm/byteorder.h> /* for htons etc. */
-#include <asm/system.h> /* save/restore_flags */
#include <linux/atomic.h>
#include "common.h"
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 3cd0a0dc91cb..0906c194a413 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -33,7 +33,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
#include <linux/mm.h>
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index 7e7964dd987b..9162409559cf 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -22,7 +22,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
index c1cb982f6e86..d0de30e89591 100644
--- a/net/ax25/ax25_dev.c
+++ b/net/ax25/ax25_dev.c
@@ -24,7 +24,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_ds_in.c b/net/ax25/ax25_ds_in.c
index 8273b1200eee..9bd31e88aeca 100644
--- a/net/ax25/ax25_ds_in.c
+++ b/net/ax25/ax25_ds_in.c
@@ -23,7 +23,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
index 85816e612dc0..5ea7fd3e2af9 100644
--- a/net/ax25/ax25_ds_subr.c
+++ b/net/ax25/ax25_ds_subr.c
@@ -24,7 +24,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c
index c7d81436213d..993c439b4f71 100644
--- a/net/ax25/ax25_ds_timer.c
+++ b/net/ax25/ax25_ds_timer.c
@@ -25,7 +25,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 60b545e2822a..7d5f24b82cc8 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -24,7 +24,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index 9bb776541203..96f4cab3a2f9 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -27,7 +27,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index cf0c47a26530..846ae4e2b115 100644
--- a/net/ax25/ax25_ip.c
+++ b/net/ax25/ax25_ip.c
@@ -24,7 +24,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
#include <linux/mm.h>
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index 37507d806f65..be8a25e0db65 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -27,7 +27,6 @@
#include <linux/netfilter.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 87fddab22e0f..a65588040b9e 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -32,7 +32,6 @@
#include <linux/spinlock.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_std_in.c b/net/ax25/ax25_std_in.c
index a8eef88d8652..3fbf8f7b2cf4 100644
--- a/net/ax25/ax25_std_in.c
+++ b/net/ax25/ax25_std_in.c
@@ -30,7 +30,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_std_subr.c b/net/ax25/ax25_std_subr.c
index 277f81bb979a..8b66a41e538f 100644
--- a/net/ax25/ax25_std_subr.c
+++ b/net/ax25/ax25_std_subr.c
@@ -21,7 +21,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_std_timer.c b/net/ax25/ax25_std_timer.c
index 96e4b9273250..004467c9e6e1 100644
--- a/net/ax25/ax25_std_timer.c
+++ b/net/ax25/ax25_std_timer.c
@@ -25,7 +25,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
index c6715ee4ab8f..1997538a5d23 100644
--- a/net/ax25/ax25_subr.c
+++ b/net/ax25/ax25_subr.c
@@ -26,7 +26,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_timer.c b/net/ax25/ax25_timer.c
index db29ea71e80a..c3cffa79bafb 100644
--- a/net/ax25/ax25_timer.c
+++ b/net/ax25/ax25_timer.c
@@ -29,7 +29,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index 4c83137b5954..e3c579ba6325 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -26,7 +26,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 9f9c8dcd8af0..180bfc45810d 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -42,7 +42,6 @@
#include <linux/uaccess.h>
#include <net/sock.h>
-#include <asm/system.h>
#include "bnep.h"
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 1230faaac29b..311668d14571 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -39,7 +39,6 @@
#include <linux/isdn/capilli.h>
-#include <asm/system.h>
#include "cmtp.h"
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 947172bf1621..5238b6b3ea6a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -37,7 +37,6 @@
#include <linux/interrupt.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 59ec99eb739b..92a857e3786d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -45,7 +45,6 @@
#include <linux/crypto.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
@@ -666,6 +665,11 @@ int hci_dev_open(__u16 dev)
hci_req_lock(hdev);
+ if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
+ ret = -ENODEV;
+ goto done;
+ }
+
if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
ret = -ERFKILL;
goto done;
@@ -1850,6 +1854,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
+ set_bit(HCI_UNREGISTER, &hdev->dev_flags);
+
write_lock(&hci_dev_list_lock);
list_del(&hdev->list);
write_unlock(&hci_dev_list_lock);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index badb7851d116..b37531094c49 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -37,7 +37,6 @@
#include <linux/interrupt.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 63afd234283e..5914623f426a 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -42,7 +42,6 @@
#include <linux/ioctl.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
@@ -734,7 +733,8 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_
data = &tv;
len = sizeof(tv);
#ifdef CONFIG_COMPAT
- if (msg->msg_flags & MSG_CMSG_COMPAT) {
+ if (!COMPAT_USE_64BIT_TIME &&
+ (msg->msg_flags & MSG_CMSG_COMPAT)) {
ctv.tv_sec = tv.tv_sec;
ctv.tv_usec = tv.tv_usec;
data = &ctv;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3e450f4a3125..94552b33d528 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -49,7 +49,6 @@
#include <linux/crc16.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -1309,6 +1308,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
if (chan->retry_count >= chan->remote_max_tx) {
l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return;
}
@@ -1317,6 +1317,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
}
static void l2cap_retrans_timeout(struct work_struct *work)
@@ -1336,6 +1337,7 @@ static void l2cap_retrans_timeout(struct work_struct *work)
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
}
static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c4fe583b0af6..29122ed28ea9 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -82,7 +82,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
}
if (la.l2_cid)
- err = l2cap_add_scid(chan, la.l2_cid);
+ err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));
else
err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
@@ -123,7 +123,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
if (la.l2_cid && la.l2_psm)
return -EINVAL;
- err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
+ err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
+ &la.l2_bdaddr);
if (err)
return err;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 7fcff8887131..4ef275c69675 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2523,13 +2523,18 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
if (cp->val) {
type = PAGE_SCAN_TYPE_INTERLACED;
- acp.interval = 0x0024; /* 22.5 msec page scan interval */
+
+ /* 22.5 msec page scan interval */
+ acp.interval = __constant_cpu_to_le16(0x0024);
} else {
type = PAGE_SCAN_TYPE_STANDARD; /* default */
- acp.interval = 0x0800; /* default 1.28 sec page scan */
+
+ /* default 1.28 sec page scan */
+ acp.interval = __constant_cpu_to_le16(0x0800);
}
- acp.window = 0x0012; /* default 11.25 msec page scan window */
+ /* default 11.25 msec page scan window */
+ acp.window = __constant_cpu_to_le16(0x0012);
err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, sizeof(acp),
&acp);
@@ -2936,7 +2941,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
name, name_len);
if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
- eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
+ eir_len = eir_append_data(ev->eir, eir_len,
EIR_CLASS_OF_DEV, dev_class, 3);
put_unaligned_le16(eir_len, &ev->eir_len);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 22169c3f1482..a55a43e9f70e 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -45,7 +45,6 @@
#include <linux/security.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h>
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 8bf26d1bc5c1..f6ab12907963 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -44,7 +44,6 @@
#include <linux/security.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h>
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 761ad9d6cc3b..cc913193d992 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -201,7 +201,9 @@ enum {
Opt_ip,
Opt_last_string,
/* string args above */
+ Opt_share,
Opt_noshare,
+ Opt_crc,
Opt_nocrc,
};
@@ -217,7 +219,9 @@ static match_table_t opt_tokens = {
{Opt_key, "key=%s"},
{Opt_ip, "ip=%s"},
/* string args above */
+ {Opt_share, "share"},
{Opt_noshare, "noshare"},
+ {Opt_crc, "crc"},
{Opt_nocrc, "nocrc"},
{-1, NULL}
};
@@ -277,10 +281,11 @@ out:
return err;
}
-int ceph_parse_options(struct ceph_options **popt, char *options,
- const char *dev_name, const char *dev_name_end,
- int (*parse_extra_token)(char *c, void *private),
- void *private)
+struct ceph_options *
+ceph_parse_options(char *options, const char *dev_name,
+ const char *dev_name_end,
+ int (*parse_extra_token)(char *c, void *private),
+ void *private)
{
struct ceph_options *opt;
const char *c;
@@ -289,7 +294,7 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
opt = kzalloc(sizeof(*opt), GFP_KERNEL);
if (!opt)
- return err;
+ return ERR_PTR(-ENOMEM);
opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr),
GFP_KERNEL);
if (!opt->mon_addr)
@@ -398,10 +403,16 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
opt->mount_timeout = intval;
break;
+ case Opt_share:
+ opt->flags &= ~CEPH_OPT_NOSHARE;
+ break;
case Opt_noshare:
opt->flags |= CEPH_OPT_NOSHARE;
break;
+ case Opt_crc:
+ opt->flags &= ~CEPH_OPT_NOCRC;
+ break;
case Opt_nocrc:
opt->flags |= CEPH_OPT_NOCRC;
break;
@@ -412,12 +423,11 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
}
/* success */
- *popt = opt;
- return 0;
+ return opt;
out:
ceph_destroy_options(opt);
- return err;
+ return ERR_PTR(err);
}
EXPORT_SYMBOL(ceph_parse_options);
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index ad5b70801f37..f0993af2ae4d 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -38,48 +38,54 @@ static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
static struct lock_class_key socket_class;
#endif
+/*
+ * When skipping (ignoring) a block of input we read it into a "skip
+ * buffer," which is this many bytes in size.
+ */
+#define SKIP_BUF_SIZE 1024
static void queue_con(struct ceph_connection *con);
static void con_work(struct work_struct *);
static void ceph_fault(struct ceph_connection *con);
/*
- * nicely render a sockaddr as a string.
+ * Nicely render a sockaddr as a string. An array of formatted
+ * strings is used, to approximate reentrancy.
*/
-#define MAX_ADDR_STR 20
-#define MAX_ADDR_STR_LEN 60
-static char addr_str[MAX_ADDR_STR][MAX_ADDR_STR_LEN];
-static DEFINE_SPINLOCK(addr_str_lock);
-static int last_addr_str;
+#define ADDR_STR_COUNT_LOG 5 /* log2(# address strings in array) */
+#define ADDR_STR_COUNT (1 << ADDR_STR_COUNT_LOG)
+#define ADDR_STR_COUNT_MASK (ADDR_STR_COUNT - 1)
+#define MAX_ADDR_STR_LEN 64 /* 54 is enough */
+
+static char addr_str[ADDR_STR_COUNT][MAX_ADDR_STR_LEN];
+static atomic_t addr_str_seq = ATOMIC_INIT(0);
+
+static struct page *zero_page; /* used in certain error cases */
const char *ceph_pr_addr(const struct sockaddr_storage *ss)
{
int i;
char *s;
- struct sockaddr_in *in4 = (void *)ss;
- struct sockaddr_in6 *in6 = (void *)ss;
-
- spin_lock(&addr_str_lock);
- i = last_addr_str++;
- if (last_addr_str == MAX_ADDR_STR)
- last_addr_str = 0;
- spin_unlock(&addr_str_lock);
+ struct sockaddr_in *in4 = (struct sockaddr_in *) ss;
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) ss;
+
+ i = atomic_inc_return(&addr_str_seq) & ADDR_STR_COUNT_MASK;
s = addr_str[i];
switch (ss->ss_family) {
case AF_INET:
- snprintf(s, MAX_ADDR_STR_LEN, "%pI4:%u", &in4->sin_addr,
- (unsigned int)ntohs(in4->sin_port));
+ snprintf(s, MAX_ADDR_STR_LEN, "%pI4:%hu", &in4->sin_addr,
+ ntohs(in4->sin_port));
break;
case AF_INET6:
- snprintf(s, MAX_ADDR_STR_LEN, "[%pI6c]:%u", &in6->sin6_addr,
- (unsigned int)ntohs(in6->sin6_port));
+ snprintf(s, MAX_ADDR_STR_LEN, "[%pI6c]:%hu", &in6->sin6_addr,
+ ntohs(in6->sin6_port));
break;
default:
- snprintf(s, MAX_ADDR_STR_LEN, "(unknown sockaddr family %d)",
- (int)ss->ss_family);
+ snprintf(s, MAX_ADDR_STR_LEN, "(unknown sockaddr family %hu)",
+ ss->ss_family);
}
return s;
@@ -95,22 +101,43 @@ static void encode_my_addr(struct ceph_messenger *msgr)
/*
* work queue for all reading and writing to/from the socket.
*/
-struct workqueue_struct *ceph_msgr_wq;
+static struct workqueue_struct *ceph_msgr_wq;
+
+void _ceph_msgr_exit(void)
+{
+ if (ceph_msgr_wq) {
+ destroy_workqueue(ceph_msgr_wq);
+ ceph_msgr_wq = NULL;
+ }
+
+ BUG_ON(zero_page == NULL);
+ kunmap(zero_page);
+ page_cache_release(zero_page);
+ zero_page = NULL;
+}
int ceph_msgr_init(void)
{
+ BUG_ON(zero_page != NULL);
+ zero_page = ZERO_PAGE(0);
+ page_cache_get(zero_page);
+
ceph_msgr_wq = alloc_workqueue("ceph-msgr", WQ_NON_REENTRANT, 0);
- if (!ceph_msgr_wq) {
- pr_err("msgr_init failed to create workqueue\n");
- return -ENOMEM;
- }
- return 0;
+ if (ceph_msgr_wq)
+ return 0;
+
+ pr_err("msgr_init failed to create workqueue\n");
+ _ceph_msgr_exit();
+
+ return -ENOMEM;
}
EXPORT_SYMBOL(ceph_msgr_init);
void ceph_msgr_exit(void)
{
- destroy_workqueue(ceph_msgr_wq);
+ BUG_ON(ceph_msgr_wq == NULL);
+
+ _ceph_msgr_exit();
}
EXPORT_SYMBOL(ceph_msgr_exit);
@@ -128,8 +155,8 @@ EXPORT_SYMBOL(ceph_msgr_flush);
/* data available on socket, or listen socket received a connect */
static void ceph_data_ready(struct sock *sk, int count_unused)
{
- struct ceph_connection *con =
- (struct ceph_connection *)sk->sk_user_data;
+ struct ceph_connection *con = sk->sk_user_data;
+
if (sk->sk_state != TCP_CLOSE_WAIT) {
dout("ceph_data_ready on %p state = %lu, queueing work\n",
con, con->state);
@@ -140,26 +167,30 @@ static void ceph_data_ready(struct sock *sk, int count_unused)
/* socket has buffer space for writing */
static void ceph_write_space(struct sock *sk)
{
- struct ceph_connection *con =
- (struct ceph_connection *)sk->sk_user_data;
+ struct ceph_connection *con = sk->sk_user_data;
- /* only queue to workqueue if there is data we want to write. */
+ /* only queue to workqueue if there is data we want to write,
+ * and there is sufficient space in the socket buffer to accept
+ * more data. clear SOCK_NOSPACE so that ceph_write_space()
+ * doesn't get called again until try_write() fills the socket
+ * buffer. See net/ipv4/tcp_input.c:tcp_check_space()
+ * and net/core/stream.c:sk_stream_write_space().
+ */
if (test_bit(WRITE_PENDING, &con->state)) {
- dout("ceph_write_space %p queueing write work\n", con);
- queue_con(con);
+ if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
+ dout("ceph_write_space %p queueing write work\n", con);
+ clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+ queue_con(con);
+ }
} else {
dout("ceph_write_space %p nothing to write\n", con);
}
-
- /* since we have our own write_space, clear the SOCK_NOSPACE flag */
- clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
}
/* socket's state has changed */
static void ceph_state_change(struct sock *sk)
{
- struct ceph_connection *con =
- (struct ceph_connection *)sk->sk_user_data;
+ struct ceph_connection *con = sk->sk_user_data;
dout("ceph_state_change %p state = %lu sk_state = %u\n",
con, con->state, sk->sk_state);
@@ -184,6 +215,8 @@ static void ceph_state_change(struct sock *sk)
dout("ceph_state_change TCP_ESTABLISHED\n");
queue_con(con);
break;
+ default: /* Everything else is uninteresting */
+ break;
}
}
@@ -194,7 +227,7 @@ static void set_sock_callbacks(struct socket *sock,
struct ceph_connection *con)
{
struct sock *sk = sock->sk;
- sk->sk_user_data = (void *)con;
+ sk->sk_user_data = con;
sk->sk_data_ready = ceph_data_ready;
sk->sk_write_space = ceph_write_space;
sk->sk_state_change = ceph_state_change;
@@ -208,7 +241,7 @@ static void set_sock_callbacks(struct socket *sock,
/*
* initiate connection to a remote socket.
*/
-static struct socket *ceph_tcp_connect(struct ceph_connection *con)
+static int ceph_tcp_connect(struct ceph_connection *con)
{
struct sockaddr_storage *paddr = &con->peer_addr.in_addr;
struct socket *sock;
@@ -218,8 +251,7 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)
ret = sock_create_kern(con->peer_addr.in_addr.ss_family, SOCK_STREAM,
IPPROTO_TCP, &sock);
if (ret)
- return ERR_PTR(ret);
- con->sock = sock;
+ return ret;
sock->sk->sk_allocation = GFP_NOFS;
#ifdef CONFIG_LOCKDEP
@@ -236,19 +268,17 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)
dout("connect %s EINPROGRESS sk_state = %u\n",
ceph_pr_addr(&con->peer_addr.in_addr),
sock->sk->sk_state);
- ret = 0;
- }
- if (ret < 0) {
+ } else if (ret < 0) {
pr_err("connect %s error %d\n",
ceph_pr_addr(&con->peer_addr.in_addr), ret);
sock_release(sock);
- con->sock = NULL;
con->error_msg = "connect error";
+
+ return ret;
}
+ con->sock = sock;
- if (ret < 0)
- return ERR_PTR(ret);
- return sock;
+ return 0;
}
static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
@@ -284,6 +314,19 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
return r;
}
+static int ceph_tcp_sendpage(struct socket *sock, struct page *page,
+ int offset, size_t size, int more)
+{
+ int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR);
+ int ret;
+
+ ret = kernel_sendpage(sock, page, offset, size, flags);
+ if (ret == -EAGAIN)
+ ret = 0;
+
+ return ret;
+}
+
/*
* Shutdown/close the socket for the given connection.
@@ -391,22 +434,23 @@ bool ceph_con_opened(struct ceph_connection *con)
*/
struct ceph_connection *ceph_con_get(struct ceph_connection *con)
{
- dout("con_get %p nref = %d -> %d\n", con,
- atomic_read(&con->nref), atomic_read(&con->nref) + 1);
- if (atomic_inc_not_zero(&con->nref))
- return con;
- return NULL;
+ int nref = __atomic_add_unless(&con->nref, 1, 0);
+
+ dout("con_get %p nref = %d -> %d\n", con, nref, nref + 1);
+
+ return nref ? con : NULL;
}
void ceph_con_put(struct ceph_connection *con)
{
- dout("con_put %p nref = %d -> %d\n", con,
- atomic_read(&con->nref), atomic_read(&con->nref) - 1);
- BUG_ON(atomic_read(&con->nref) == 0);
- if (atomic_dec_and_test(&con->nref)) {
+ int nref = atomic_dec_return(&con->nref);
+
+ BUG_ON(nref < 0);
+ if (nref == 0) {
BUG_ON(con->sock);
kfree(con);
}
+ dout("con_put %p nref = %d -> %d\n", con, nref + 1, nref);
}
/*
@@ -442,14 +486,35 @@ static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt)
return ret;
}
+static void ceph_con_out_kvec_reset(struct ceph_connection *con)
+{
+ con->out_kvec_left = 0;
+ con->out_kvec_bytes = 0;
+ con->out_kvec_cur = &con->out_kvec[0];
+}
+
+static void ceph_con_out_kvec_add(struct ceph_connection *con,
+ size_t size, void *data)
+{
+ int index;
+
+ index = con->out_kvec_left;
+ BUG_ON(index >= ARRAY_SIZE(con->out_kvec));
+
+ con->out_kvec[index].iov_len = size;
+ con->out_kvec[index].iov_base = data;
+ con->out_kvec_left++;
+ con->out_kvec_bytes += size;
+}
/*
* Prepare footer for currently outgoing message, and finish things
* off. Assumes out_kvec* are already valid.. we just add on to the end.
*/
-static void prepare_write_message_footer(struct ceph_connection *con, int v)
+static void prepare_write_message_footer(struct ceph_connection *con)
{
struct ceph_msg *m = con->out_msg;
+ int v = con->out_kvec_left;
dout("prepare_write_message_footer %p\n", con);
con->out_kvec_is_msg = true;
@@ -467,9 +532,9 @@ static void prepare_write_message_footer(struct ceph_connection *con, int v)
static void prepare_write_message(struct ceph_connection *con)
{
struct ceph_msg *m;
- int v = 0;
+ u32 crc;
- con->out_kvec_bytes = 0;
+ ceph_con_out_kvec_reset(con);
con->out_kvec_is_msg = true;
con->out_msg_done = false;
@@ -477,16 +542,13 @@ static void prepare_write_message(struct ceph_connection *con)
* TCP packet that's a good thing. */
if (con->in_seq > con->in_seq_acked) {
con->in_seq_acked = con->in_seq;
- con->out_kvec[v].iov_base = &tag_ack;
- con->out_kvec[v++].iov_len = 1;
+ ceph_con_out_kvec_add(con, sizeof (tag_ack), &tag_ack);
con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
- con->out_kvec[v].iov_base = &con->out_temp_ack;
- con->out_kvec[v++].iov_len = sizeof(con->out_temp_ack);
- con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+ ceph_con_out_kvec_add(con, sizeof (con->out_temp_ack),
+ &con->out_temp_ack);
}
- m = list_first_entry(&con->out_queue,
- struct ceph_msg, list_head);
+ m = list_first_entry(&con->out_queue, struct ceph_msg, list_head);
con->out_msg = m;
/* put message on sent list */
@@ -510,30 +572,26 @@ static void prepare_write_message(struct ceph_connection *con)
BUG_ON(le32_to_cpu(m->hdr.front_len) != m->front.iov_len);
/* tag + hdr + front + middle */
- con->out_kvec[v].iov_base = &tag_msg;
- con->out_kvec[v++].iov_len = 1;
- con->out_kvec[v].iov_base = &m->hdr;
- con->out_kvec[v++].iov_len = sizeof(m->hdr);
- con->out_kvec[v++] = m->front;
+ ceph_con_out_kvec_add(con, sizeof (tag_msg), &tag_msg);
+ ceph_con_out_kvec_add(con, sizeof (m->hdr), &m->hdr);
+ ceph_con_out_kvec_add(con, m->front.iov_len, m->front.iov_base);
+
if (m->middle)
- con->out_kvec[v++] = m->middle->vec;
- con->out_kvec_left = v;
- con->out_kvec_bytes += 1 + sizeof(m->hdr) + m->front.iov_len +
- (m->middle ? m->middle->vec.iov_len : 0);
- con->out_kvec_cur = con->out_kvec;
+ ceph_con_out_kvec_add(con, m->middle->vec.iov_len,
+ m->middle->vec.iov_base);
/* fill in crc (except data pages), footer */
- con->out_msg->hdr.crc =
- cpu_to_le32(crc32c(0, (void *)&m->hdr,
- sizeof(m->hdr) - sizeof(m->hdr.crc)));
+ crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc));
+ con->out_msg->hdr.crc = cpu_to_le32(crc);
con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE;
- con->out_msg->footer.front_crc =
- cpu_to_le32(crc32c(0, m->front.iov_base, m->front.iov_len));
- if (m->middle)
- con->out_msg->footer.middle_crc =
- cpu_to_le32(crc32c(0, m->middle->vec.iov_base,
- m->middle->vec.iov_len));
- else
+
+ crc = crc32c(0, m->front.iov_base, m->front.iov_len);
+ con->out_msg->footer.front_crc = cpu_to_le32(crc);
+ if (m->middle) {
+ crc = crc32c(0, m->middle->vec.iov_base,
+ m->middle->vec.iov_len);
+ con->out_msg->footer.middle_crc = cpu_to_le32(crc);
+ } else
con->out_msg->footer.middle_crc = 0;
con->out_msg->footer.data_crc = 0;
dout("prepare_write_message front_crc %u data_crc %u\n",
@@ -549,11 +607,11 @@ static void prepare_write_message(struct ceph_connection *con)
else
con->out_msg_pos.page_pos = 0;
con->out_msg_pos.data_pos = 0;
- con->out_msg_pos.did_page_crc = 0;
+ con->out_msg_pos.did_page_crc = false;
con->out_more = 1; /* data + footer will follow */
} else {
/* no, queue up footer too and be done */
- prepare_write_message_footer(con, v);
+ prepare_write_message_footer(con);
}
set_bit(WRITE_PENDING, &con->state);
@@ -568,14 +626,14 @@ static void prepare_write_ack(struct ceph_connection *con)
con->in_seq_acked, con->in_seq);
con->in_seq_acked = con->in_seq;
- con->out_kvec[0].iov_base = &tag_ack;
- con->out_kvec[0].iov_len = 1;
+ ceph_con_out_kvec_reset(con);
+
+ ceph_con_out_kvec_add(con, sizeof (tag_ack), &tag_ack);
+
con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
- con->out_kvec[1].iov_base = &con->out_temp_ack;
- con->out_kvec[1].iov_len = sizeof(con->out_temp_ack);
- con->out_kvec_left = 2;
- con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
- con->out_kvec_cur = con->out_kvec;
+ ceph_con_out_kvec_add(con, sizeof (con->out_temp_ack),
+ &con->out_temp_ack);
+
con->out_more = 1; /* more will follow.. eventually.. */
set_bit(WRITE_PENDING, &con->state);
}
@@ -586,11 +644,8 @@ static void prepare_write_ack(struct ceph_connection *con)
static void prepare_write_keepalive(struct ceph_connection *con)
{
dout("prepare_write_keepalive %p\n", con);
- con->out_kvec[0].iov_base = &tag_keepalive;
- con->out_kvec[0].iov_len = 1;
- con->out_kvec_left = 1;
- con->out_kvec_bytes = 1;
- con->out_kvec_cur = con->out_kvec;
+ ceph_con_out_kvec_reset(con);
+ ceph_con_out_kvec_add(con, sizeof (tag_keepalive), &tag_keepalive);
set_bit(WRITE_PENDING, &con->state);
}
@@ -619,12 +674,9 @@ static int prepare_connect_authorizer(struct ceph_connection *con)
con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol);
con->out_connect.authorizer_len = cpu_to_le32(auth_len);
- if (auth_len) {
- con->out_kvec[con->out_kvec_left].iov_base = auth_buf;
- con->out_kvec[con->out_kvec_left].iov_len = auth_len;
- con->out_kvec_left++;
- con->out_kvec_bytes += auth_len;
- }
+ if (auth_len)
+ ceph_con_out_kvec_add(con, auth_len, auth_buf);
+
return 0;
}
@@ -634,22 +686,18 @@ static int prepare_connect_authorizer(struct ceph_connection *con)
static void prepare_write_banner(struct ceph_messenger *msgr,
struct ceph_connection *con)
{
- int len = strlen(CEPH_BANNER);
+ ceph_con_out_kvec_reset(con);
+ ceph_con_out_kvec_add(con, strlen(CEPH_BANNER), CEPH_BANNER);
+ ceph_con_out_kvec_add(con, sizeof (msgr->my_enc_addr),
+ &msgr->my_enc_addr);
- con->out_kvec[0].iov_base = CEPH_BANNER;
- con->out_kvec[0].iov_len = len;
- con->out_kvec[1].iov_base = &msgr->my_enc_addr;
- con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr);
- con->out_kvec_left = 2;
- con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr);
- con->out_kvec_cur = con->out_kvec;
con->out_more = 0;
set_bit(WRITE_PENDING, &con->state);
}
static int prepare_write_connect(struct ceph_messenger *msgr,
struct ceph_connection *con,
- int after_banner)
+ int include_banner)
{
unsigned global_seq = get_global_seq(con->msgr, 0);
int proto;
@@ -678,22 +726,18 @@ static int prepare_write_connect(struct ceph_messenger *msgr,
con->out_connect.protocol_version = cpu_to_le32(proto);
con->out_connect.flags = 0;
- if (!after_banner) {
- con->out_kvec_left = 0;
- con->out_kvec_bytes = 0;
- }
- con->out_kvec[con->out_kvec_left].iov_base = &con->out_connect;
- con->out_kvec[con->out_kvec_left].iov_len = sizeof(con->out_connect);
- con->out_kvec_left++;
- con->out_kvec_bytes += sizeof(con->out_connect);
- con->out_kvec_cur = con->out_kvec;
+ if (include_banner)
+ prepare_write_banner(msgr, con);
+ else
+ ceph_con_out_kvec_reset(con);
+ ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect);
+
con->out_more = 0;
set_bit(WRITE_PENDING, &con->state);
return prepare_connect_authorizer(con);
}
-
/*
* write as much of pending kvecs to the socket as we can.
* 1 -> done
@@ -714,17 +758,18 @@ static int write_partial_kvec(struct ceph_connection *con)
con->out_kvec_bytes -= ret;
if (con->out_kvec_bytes == 0)
break; /* done */
- while (ret > 0) {
- if (ret >= con->out_kvec_cur->iov_len) {
- ret -= con->out_kvec_cur->iov_len;
- con->out_kvec_cur++;
- con->out_kvec_left--;
- } else {
- con->out_kvec_cur->iov_len -= ret;
- con->out_kvec_cur->iov_base += ret;
- ret = 0;
- break;
- }
+
+ /* account for full iov entries consumed */
+ while (ret >= con->out_kvec_cur->iov_len) {
+ BUG_ON(!con->out_kvec_left);
+ ret -= con->out_kvec_cur->iov_len;
+ con->out_kvec_cur++;
+ con->out_kvec_left--;
+ }
+ /* and for a partially-consumed entry */
+ if (ret) {
+ con->out_kvec_cur->iov_len -= ret;
+ con->out_kvec_cur->iov_base += ret;
}
}
con->out_kvec_left = 0;
@@ -773,7 +818,7 @@ static int write_partial_msg_pages(struct ceph_connection *con)
struct ceph_msg *msg = con->out_msg;
unsigned data_len = le32_to_cpu(msg->hdr.data_len);
size_t len;
- int crc = con->msgr->nocrc;
+ bool do_datacrc = !con->msgr->nocrc;
int ret;
int total_max_write;
int in_trail = 0;
@@ -790,9 +835,8 @@ static int write_partial_msg_pages(struct ceph_connection *con)
while (data_len > con->out_msg_pos.data_pos) {
struct page *page = NULL;
- void *kaddr = NULL;
int max_write = PAGE_SIZE;
- int page_shift = 0;
+ int bio_offset = 0;
total_max_write = data_len - trail_len -
con->out_msg_pos.data_pos;
@@ -811,58 +855,47 @@ static int write_partial_msg_pages(struct ceph_connection *con)
page = list_first_entry(&msg->trail->head,
struct page, lru);
- if (crc)
- kaddr = kmap(page);
max_write = PAGE_SIZE;
} else if (msg->pages) {
page = msg->pages[con->out_msg_pos.page];
- if (crc)
- kaddr = kmap(page);
} else if (msg->pagelist) {
page = list_first_entry(&msg->pagelist->head,
struct page, lru);
- if (crc)
- kaddr = kmap(page);
#ifdef CONFIG_BLOCK
} else if (msg->bio) {
struct bio_vec *bv;
bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg);
page = bv->bv_page;
- page_shift = bv->bv_offset;
- if (crc)
- kaddr = kmap(page) + page_shift;
+ bio_offset = bv->bv_offset;
max_write = bv->bv_len;
#endif
} else {
- page = con->msgr->zero_page;
- if (crc)
- kaddr = page_address(con->msgr->zero_page);
+ page = zero_page;
}
len = min_t(int, max_write - con->out_msg_pos.page_pos,
total_max_write);
- if (crc && !con->out_msg_pos.did_page_crc) {
- void *base = kaddr + con->out_msg_pos.page_pos;
+ if (do_datacrc && !con->out_msg_pos.did_page_crc) {
+ void *base;
+ u32 crc;
u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc);
+ char *kaddr;
+ kaddr = kmap(page);
BUG_ON(kaddr == NULL);
- con->out_msg->footer.data_crc =
- cpu_to_le32(crc32c(tmpcrc, base, len));
- con->out_msg_pos.did_page_crc = 1;
+ base = kaddr + con->out_msg_pos.page_pos + bio_offset;
+ crc = crc32c(tmpcrc, base, len);
+ con->out_msg->footer.data_crc = cpu_to_le32(crc);
+ con->out_msg_pos.did_page_crc = true;
}
- ret = kernel_sendpage(con->sock, page,
- con->out_msg_pos.page_pos + page_shift,
- len,
- MSG_DONTWAIT | MSG_NOSIGNAL |
- MSG_MORE);
-
- if (crc &&
- (msg->pages || msg->pagelist || msg->bio || in_trail))
+ ret = ceph_tcp_sendpage(con->sock, page,
+ con->out_msg_pos.page_pos + bio_offset,
+ len, 1);
+
+ if (do_datacrc)
kunmap(page);
- if (ret == -EAGAIN)
- ret = 0;
if (ret <= 0)
goto out;
@@ -871,7 +904,7 @@ static int write_partial_msg_pages(struct ceph_connection *con)
if (ret == len) {
con->out_msg_pos.page_pos = 0;
con->out_msg_pos.page++;
- con->out_msg_pos.did_page_crc = 0;
+ con->out_msg_pos.did_page_crc = false;
if (in_trail)
list_move_tail(&page->lru,
&msg->trail->head);
@@ -888,12 +921,10 @@ static int write_partial_msg_pages(struct ceph_connection *con)
dout("write_partial_msg_pages %p msg %p done\n", con, msg);
/* prepare and queue up footer, too */
- if (!crc)
+ if (!do_datacrc)
con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
- con->out_kvec_bytes = 0;
- con->out_kvec_left = 0;
- con->out_kvec_cur = con->out_kvec;
- prepare_write_message_footer(con, 0);
+ ceph_con_out_kvec_reset(con);
+ prepare_write_message_footer(con);
ret = 1;
out:
return ret;
@@ -907,12 +938,9 @@ static int write_partial_skip(struct ceph_connection *con)
int ret;
while (con->out_skip > 0) {
- struct kvec iov = {
- .iov_base = page_address(con->msgr->zero_page),
- .iov_len = min(con->out_skip, (int)PAGE_CACHE_SIZE)
- };
+ size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE);
- ret = ceph_tcp_sendmsg(con->sock, &iov, 1, iov.iov_len, 1);
+ ret = ceph_tcp_sendpage(con->sock, zero_page, 0, size, 1);
if (ret <= 0)
goto out;
con->out_skip -= ret;
@@ -1085,8 +1113,8 @@ static void addr_set_port(struct sockaddr_storage *ss, int p)
static int ceph_pton(const char *str, size_t len, struct sockaddr_storage *ss,
char delim, const char **ipend)
{
- struct sockaddr_in *in4 = (void *)ss;
- struct sockaddr_in6 *in6 = (void *)ss;
+ struct sockaddr_in *in4 = (struct sockaddr_in *) ss;
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) ss;
memset(ss, 0, sizeof(*ss));
@@ -1512,10 +1540,9 @@ static int read_partial_message_section(struct ceph_connection *con,
if (ret <= 0)
return ret;
section->iov_len += ret;
- if (section->iov_len == sec_len)
- *crc = crc32c(0, section->iov_base,
- section->iov_len);
}
+ if (section->iov_len == sec_len)
+ *crc = crc32c(0, section->iov_base, section->iov_len);
return 1;
}
@@ -1527,7 +1554,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
static int read_partial_message_pages(struct ceph_connection *con,
struct page **pages,
- unsigned data_len, int datacrc)
+ unsigned data_len, bool do_datacrc)
{
void *p;
int ret;
@@ -1540,7 +1567,7 @@ static int read_partial_message_pages(struct ceph_connection *con,
p = kmap(pages[con->in_msg_pos.page]);
ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
left);
- if (ret > 0 && datacrc)
+ if (ret > 0 && do_datacrc)
con->in_data_crc =
crc32c(con->in_data_crc,
p + con->in_msg_pos.page_pos, ret);
@@ -1560,7 +1587,7 @@ static int read_partial_message_pages(struct ceph_connection *con,
#ifdef CONFIG_BLOCK
static int read_partial_message_bio(struct ceph_connection *con,
struct bio **bio_iter, int *bio_seg,
- unsigned data_len, int datacrc)
+ unsigned data_len, bool do_datacrc)
{
struct bio_vec *bv = bio_iovec_idx(*bio_iter, *bio_seg);
void *p;
@@ -1576,7 +1603,7 @@ static int read_partial_message_bio(struct ceph_connection *con,
ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
left);
- if (ret > 0 && datacrc)
+ if (ret > 0 && do_datacrc)
con->in_data_crc =
crc32c(con->in_data_crc,
p + con->in_msg_pos.page_pos, ret);
@@ -1603,9 +1630,10 @@ static int read_partial_message(struct ceph_connection *con)
int ret;
int to, left;
unsigned front_len, middle_len, data_len;
- int datacrc = con->msgr->nocrc;
+ bool do_datacrc = !con->msgr->nocrc;
int skip;
u64 seq;
+ u32 crc;
dout("read_partial_message con %p msg %p\n", con, m);
@@ -1618,17 +1646,16 @@ static int read_partial_message(struct ceph_connection *con)
if (ret <= 0)
return ret;
con->in_base_pos += ret;
- if (con->in_base_pos == sizeof(con->in_hdr)) {
- u32 crc = crc32c(0, (void *)&con->in_hdr,
- sizeof(con->in_hdr) - sizeof(con->in_hdr.crc));
- if (crc != le32_to_cpu(con->in_hdr.crc)) {
- pr_err("read_partial_message bad hdr "
- " crc %u != expected %u\n",
- crc, con->in_hdr.crc);
- return -EBADMSG;
- }
- }
}
+
+ crc = crc32c(0, &con->in_hdr, offsetof(struct ceph_msg_header, crc));
+ if (cpu_to_le32(crc) != con->in_hdr.crc) {
+ pr_err("read_partial_message bad hdr "
+ " crc %u != expected %u\n",
+ crc, con->in_hdr.crc);
+ return -EBADMSG;
+ }
+
front_len = le32_to_cpu(con->in_hdr.front_len);
if (front_len > CEPH_MSG_MAX_FRONT_LEN)
return -EIO;
@@ -1714,7 +1741,7 @@ static int read_partial_message(struct ceph_connection *con)
while (con->in_msg_pos.data_pos < data_len) {
if (m->pages) {
ret = read_partial_message_pages(con, m->pages,
- data_len, datacrc);
+ data_len, do_datacrc);
if (ret <= 0)
return ret;
#ifdef CONFIG_BLOCK
@@ -1722,7 +1749,7 @@ static int read_partial_message(struct ceph_connection *con)
ret = read_partial_message_bio(con,
&m->bio_iter, &m->bio_seg,
- data_len, datacrc);
+ data_len, do_datacrc);
if (ret <= 0)
return ret;
#endif
@@ -1757,7 +1784,7 @@ static int read_partial_message(struct ceph_connection *con)
m, con->in_middle_crc, m->footer.middle_crc);
return -EBADMSG;
}
- if (datacrc &&
+ if (do_datacrc &&
(m->footer.flags & CEPH_MSG_FOOTER_NOCRC) == 0 &&
con->in_data_crc != le32_to_cpu(m->footer.data_crc)) {
pr_err("read_partial_message %p data crc %u != exp. %u\n", m,
@@ -1819,7 +1846,6 @@ more:
/* open the socket first? */
if (con->sock == NULL) {
- prepare_write_banner(msgr, con);
prepare_write_connect(msgr, con, 1);
prepare_read_banner(con);
set_bit(CONNECTING, &con->state);
@@ -1829,11 +1855,9 @@ more:
con->in_tag = CEPH_MSGR_TAG_READY;
dout("try_write initiating connect on %p new state %lu\n",
con, con->state);
- con->sock = ceph_tcp_connect(con);
- if (IS_ERR(con->sock)) {
- con->sock = NULL;
+ ret = ceph_tcp_connect(con);
+ if (ret < 0) {
con->error_msg = "connect error";
- ret = -1;
goto out;
}
}
@@ -1953,8 +1977,9 @@ more:
*
* FIXME: there must be a better way to do this!
*/
- static char buf[1024];
- int skip = min(1024, -con->in_base_pos);
+ static char buf[SKIP_BUF_SIZE];
+ int skip = min((int) sizeof (buf), -con->in_base_pos);
+
dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
ret = ceph_tcp_recvmsg(con->sock, buf, skip);
if (ret <= 0)
@@ -2216,15 +2241,6 @@ struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr,
spin_lock_init(&msgr->global_seq_lock);
- /* the zero page is needed if a request is "canceled" while the message
- * is being written over the socket */
- msgr->zero_page = __page_cache_alloc(GFP_KERNEL | __GFP_ZERO);
- if (!msgr->zero_page) {
- kfree(msgr);
- return ERR_PTR(-ENOMEM);
- }
- kmap(msgr->zero_page);
-
if (myaddr)
msgr->inst.addr = *myaddr;
@@ -2241,8 +2257,6 @@ EXPORT_SYMBOL(ceph_messenger_create);
void ceph_messenger_destroy(struct ceph_messenger *msgr)
{
dout("destroy %p\n", msgr);
- kunmap(msgr->zero_page);
- __free_page(msgr->zero_page);
kfree(msgr);
dout("destroyed messenger %p\n", msgr);
}
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index fd863fe76934..29ad46ec9dcf 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -283,7 +283,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
ceph_decode_32_safe(p, end, yes, bad);
#if BITS_PER_LONG == 32
err = -EINVAL;
- if (yes > ULONG_MAX / sizeof(struct crush_rule_step))
+ if (yes > (ULONG_MAX - sizeof(*r))
+ / sizeof(struct crush_rule_step))
goto bad;
#endif
r = c->rules[i] = kmalloc(sizeof(*r) +
diff --git a/net/compat.c b/net/compat.c
index 64b4515a64e6..e055708b8ec9 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -219,8 +219,6 @@ Efault:
int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
{
- struct compat_timeval ctv;
- struct compat_timespec cts[3];
struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
struct compat_cmsghdr cmhdr;
int cmlen;
@@ -230,24 +228,28 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
return 0; /* XXX: return error? check spec. */
}
- if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
- struct timeval *tv = (struct timeval *)data;
- ctv.tv_sec = tv->tv_sec;
- ctv.tv_usec = tv->tv_usec;
- data = &ctv;
- len = sizeof(ctv);
- }
- if (level == SOL_SOCKET &&
- (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
- int count = type == SCM_TIMESTAMPNS ? 1 : 3;
- int i;
- struct timespec *ts = (struct timespec *)data;
- for (i = 0; i < count; i++) {
- cts[i].tv_sec = ts[i].tv_sec;
- cts[i].tv_nsec = ts[i].tv_nsec;
+ if (!COMPAT_USE_64BIT_TIME) {
+ struct compat_timeval ctv;
+ struct compat_timespec cts[3];
+ if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
+ struct timeval *tv = (struct timeval *)data;
+ ctv.tv_sec = tv->tv_sec;
+ ctv.tv_usec = tv->tv_usec;
+ data = &ctv;
+ len = sizeof(ctv);
+ }
+ if (level == SOL_SOCKET &&
+ (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
+ int count = type == SCM_TIMESTAMPNS ? 1 : 3;
+ int i;
+ struct timespec *ts = (struct timespec *)data;
+ for (i = 0; i < count; i++) {
+ cts[i].tv_sec = ts[i].tv_sec;
+ cts[i].tv_nsec = ts[i].tv_nsec;
+ }
+ data = &cts;
+ len = sizeof(cts[0]) * count;
}
- data = &cts;
- len = sizeof(cts[0]) * count;
}
cmlen = CMSG_COMPAT_LEN(len);
@@ -454,11 +456,15 @@ static int compat_sock_getsockopt(struct socket *sock, int level, int optname,
int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
{
- struct compat_timeval __user *ctv =
- (struct compat_timeval __user *) userstamp;
- int err = -ENOENT;
+ struct compat_timeval __user *ctv;
+ int err;
struct timeval tv;
+ if (COMPAT_USE_64BIT_TIME)
+ return sock_get_timestamp(sk, userstamp);
+
+ ctv = (struct compat_timeval __user *) userstamp;
+ err = -ENOENT;
if (!sock_flag(sk, SOCK_TIMESTAMP))
sock_enable_timestamp(sk, SOCK_TIMESTAMP);
tv = ktime_to_timeval(sk->sk_stamp);
@@ -478,11 +484,15 @@ EXPORT_SYMBOL(compat_sock_get_timestamp);
int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
{
- struct compat_timespec __user *ctv =
- (struct compat_timespec __user *) userstamp;
- int err = -ENOENT;
+ struct compat_timespec __user *ctv;
+ int err;
struct timespec ts;
+ if (COMPAT_USE_64BIT_TIME)
+ return sock_get_timestampns (sk, userstamp);
+
+ ctv = (struct compat_timespec __user *) userstamp;
+ err = -ENOENT;
if (!sock_flag(sk, SOCK_TIMESTAMP))
sock_enable_timestamp(sk, SOCK_TIMESTAMP);
ts = ktime_to_timespec(sk->sk_stamp);
@@ -767,6 +777,11 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
int datagrams;
struct timespec ktspec;
+ if (COMPAT_USE_64BIT_TIME)
+ return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
+ flags | MSG_CMSG_COMPAT,
+ (struct timespec *) timeout);
+
if (timeout == NULL)
return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
flags | MSG_CMSG_COMPAT, NULL);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index d3cf12f62c8f..e4fbfd6e2bd4 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -37,7 +37,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
diff --git a/net/core/dev.c b/net/core/dev.c
index 452db7090d18..c25d453b2803 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -73,7 +73,6 @@
*/
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/cpu.h>
@@ -1597,6 +1596,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
kfree_skb(skb);
return NET_RX_DROP;
}
+ skb->skb_iif = 0;
skb_set_dev(skb, dev);
skb->tstamp.tv64 = 0;
skb->pkt_type = PACKET_HOST;
@@ -4028,54 +4028,41 @@ static int dev_ifconf(struct net *net, char __user *arg)
#ifdef CONFIG_PROC_FS
-#define BUCKET_SPACE (32 - NETDEV_HASHBITS)
-
-struct dev_iter_state {
- struct seq_net_private p;
- unsigned int pos; /* bucket << BUCKET_SPACE + offset */
-};
+#define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
#define get_bucket(x) ((x) >> BUCKET_SPACE)
#define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1))
#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
-static inline struct net_device *dev_from_same_bucket(struct seq_file *seq)
+static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos)
{
- struct dev_iter_state *state = seq->private;
struct net *net = seq_file_net(seq);
struct net_device *dev;
struct hlist_node *p;
struct hlist_head *h;
- unsigned int count, bucket, offset;
+ unsigned int count = 0, offset = get_offset(*pos);
- bucket = get_bucket(state->pos);
- offset = get_offset(state->pos);
- h = &net->dev_name_head[bucket];
- count = 0;
+ h = &net->dev_name_head[get_bucket(*pos)];
hlist_for_each_entry_rcu(dev, p, h, name_hlist) {
- if (count++ == offset) {
- state->pos = set_bucket_offset(bucket, count);
+ if (++count == offset)
return dev;
- }
}
return NULL;
}
-static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
+static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *pos)
{
- struct dev_iter_state *state = seq->private;
struct net_device *dev;
unsigned int bucket;
- bucket = get_bucket(state->pos);
do {
- dev = dev_from_same_bucket(seq);
+ dev = dev_from_same_bucket(seq, pos);
if (dev)
return dev;
- bucket++;
- state->pos = set_bucket_offset(bucket, 0);
+ bucket = get_bucket(*pos) + 1;
+ *pos = set_bucket_offset(bucket, 1);
} while (bucket < NETDEV_HASHENTRIES);
return NULL;
@@ -4088,33 +4075,20 @@ static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
{
- struct dev_iter_state *state = seq->private;
-
rcu_read_lock();
if (!*pos)
return SEQ_START_TOKEN;
- /* check for end of the hash */
- if (state->pos == 0 && *pos > 1)
+ if (get_bucket(*pos) >= NETDEV_HASHENTRIES)
return NULL;
- return dev_from_new_bucket(seq);
+ return dev_from_bucket(seq, pos);
}
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct net_device *dev;
-
++*pos;
-
- if (v == SEQ_START_TOKEN)
- return dev_from_new_bucket(seq);
-
- dev = dev_from_same_bucket(seq);
- if (dev)
- return dev;
-
- return dev_from_new_bucket(seq);
+ return dev_from_bucket(seq, pos);
}
void dev_seq_stop(struct seq_file *seq, void *v)
@@ -4213,13 +4187,7 @@ static const struct seq_operations dev_seq_ops = {
static int dev_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &dev_seq_ops,
- sizeof(struct dev_iter_state));
-}
-
-int dev_seq_open_ops(struct inode *inode, struct file *file,
- const struct seq_operations *ops)
-{
- return seq_open_net(inode, file, ops, sizeof(struct dev_iter_state));
+ sizeof(struct seq_net_private));
}
static const struct file_operations dev_seq_fops = {
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 29c07fef9228..626698f0db8b 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -696,7 +696,8 @@ static const struct seq_operations dev_mc_seq_ops = {
static int dev_mc_seq_open(struct inode *inode, struct file *file)
{
- return dev_seq_open_ops(inode, file, &dev_mc_seq_ops);
+ return seq_open_net(inode, file, &dev_mc_seq_ops,
+ sizeof(struct seq_net_private));
}
static const struct file_operations dev_mc_seq_fops = {
diff --git a/net/core/filter.c b/net/core/filter.c
index 5dea45279215..6f755cca4520 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -33,15 +33,17 @@
#include <net/sock.h>
#include <linux/errno.h>
#include <linux/timer.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/filter.h>
#include <linux/reciprocal_div.h>
#include <linux/ratelimit.h>
-/* No hurry in this branch */
-static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
+/* No hurry in this branch
+ *
+ * Exported for the bpf jit load helper.
+ */
+void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, unsigned int size)
{
u8 *ptr = NULL;
@@ -60,7 +62,7 @@ static inline void *load_pointer(const struct sk_buff *skb, int k,
{
if (k >= 0)
return skb_header_pointer(skb, k, size, buffer);
- return __load_pointer(skb, k, size);
+ return bpf_internal_load_pointer_neg_helper(skb, k, size);
}
/**
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 43b03dd71e85..d9d198aa9fed 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -14,7 +14,6 @@
*/
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/types.h>
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1a63c6efd2ea..90430b776ece 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -38,7 +38,6 @@
#include <linux/pci.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/core/scm.c b/net/core/scm.c
index ff52ad0a5150..611c5efd4cb0 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -28,7 +28,6 @@
#include <linux/nsproxy.h>
#include <linux/slab.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <net/protocol.h>
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index a690cae91cdd..baf8d281152c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -66,7 +66,6 @@
#include <net/xfrm.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <trace/events/skb.h>
#include "kmap_skb.h"
@@ -3162,6 +3161,8 @@ static void sock_rmem_free(struct sk_buff *skb)
*/
int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
{
+ int len = skb->len;
+
if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
(unsigned)sk->sk_rcvbuf)
return -ENOMEM;
@@ -3176,7 +3177,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
skb_queue_tail(&sk->sk_error_queue, skb);
if (!sock_flag(sk, SOCK_DEAD))
- sk->sk_data_ready(sk, skb->len);
+ sk->sk_data_ready(sk, len);
return 0;
}
EXPORT_SYMBOL(sock_queue_err_skb);
diff --git a/net/core/sock.c b/net/core/sock.c
index 9be6d0d6c533..b2e14c07d920 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -115,7 +115,6 @@
#include <linux/memcontrol.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/netdevice.h>
#include <net/protocol.h>
diff --git a/net/core/utils.c b/net/core/utils.c
index 386e263f6066..dc3c3faff2f4 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -30,7 +30,6 @@
#include <net/net_ratelimit.h>
#include <asm/byteorder.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
int net_msg_warn __read_mostly = 1;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 19acd00a6382..4136987d94da 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -119,7 +119,6 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat
#include <net/sock.h>
#include <net/tcp_states.h>
#include <net/flow.h>
-#include <asm/system.h>
#include <asm/ioctls.h>
#include <linux/capability.h>
#include <linux/mm.h>
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 74d321a60e7b..c00e3077988c 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -42,7 +42,6 @@
#include <linux/notifier.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <net/net_namespace.h>
#include <net/neighbour.h>
#include <net/dst.h>
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 73fa268fe2e8..f6544b2c91b0 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -60,7 +60,6 @@
#include <linux/slab.h>
#include <net/sock.h>
#include <net/tcp_states.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/termios.h>
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index bd78836a81eb..e446e85e64a6 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -52,7 +52,6 @@
#include <linux/route.h>
#include <linux/slab.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/termios.h>
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 7e717cb35ad1..71b5edcee401 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -47,7 +47,6 @@
#include <linux/mutex.h>
#include <linux/uaccess.h>
-#include <asm/system.h>
static const struct proto_ops econet_ops;
static struct hlist_head econet_sklist;
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a93af86b8474..bf10a311cf1c 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -59,7 +59,6 @@
#include <net/ip.h>
#include <net/dsa.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
__setup("ether=", netdev_boot_setup);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index fdf49fd44bb4..10e3751466b5 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -91,7 +91,6 @@
#include <linux/slab.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/inet.h>
#include <linux/igmp.h>
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 73f46d691abc..18d9b81ecb1a 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -113,7 +113,6 @@
#include <net/ax25.h>
#include <net/netrom.h>
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <linux/netfilter_arp.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index d4fad5c77447..6e447ff94dfa 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -27,7 +27,6 @@
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/module.h>
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 76e72bacc217..cbe3a68507cf 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/types.h>
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index a8c5c1d6715b..5063fa38ac7b 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -14,7 +14,6 @@
*/
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index da9b9cb2282d..bce36f1a37b4 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -51,7 +51,6 @@
#define VERSION "0.409"
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 9664d353ccd8..2cb2bf845641 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -91,7 +91,6 @@
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/init.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <net/checksum.h>
#include <net/xfrm.h>
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 450e5d21ed2a..5dfecfd7d5e9 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -73,7 +73,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index f3f1108940f5..26eccc5bab1c 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -115,7 +115,6 @@
#define pr_fmt(fmt) "IPv4: " fmt
-#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ff302bde8890..4910176d24ed 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -43,7 +43,6 @@
*/
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 0518a4fb177b..960fbfc3e976 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -26,7 +26,6 @@
*
*/
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/capability.h>
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index ab6b36e6da15..50009c787bcd 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -20,7 +20,6 @@
*
*/
-#include <asm/system.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/fcntl.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 12ccf880eb88..167ea10b521a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -66,7 +66,6 @@
#include <linux/module.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -2042,7 +2041,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (err < 0)
goto e_err;
}
- rth = rt_dst_alloc(init_net.loopback_dev,
+ rth = rt_dst_alloc(dev_net(dev)->loopback_dev,
IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
if (!rth)
goto e_nobufs;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index cfd7edda0a8e..5d54ed30e821 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -860,7 +860,7 @@ wait_for_memory:
}
out:
- if (copied)
+ if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
tcp_push(sk, flags, mss_now, tp->nonagle);
return copied;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d6f5feeb3eaf..fe141052a1be 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -79,7 +79,6 @@
#define pr_fmt(fmt) "UDP: " fmt
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <linux/bootmem.h>
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 5605f9dca87e..8ed1b930e75f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -60,7 +60,6 @@
#endif
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/mroute6.h>
MODULE_AUTHOR("Cast of dozens");
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index af88934e4d79..27ac95a63429 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -66,7 +66,6 @@
#include <net/inet_common.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
/*
* The ICMP socket(s). This is the most convenient way to flow control
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 5aa3981a3922..8110362e0af5 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -16,7 +16,6 @@
*
*/
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/sched.h>
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 16c33e308121..b2869cab2092 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2044,7 +2044,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca,
if (!delta)
pmc->mca_sfcount[sfmode]--;
for (j=0; j<i; j++)
- (void) ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
+ ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]);
} else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) {
struct ip6_sf_list *psf;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 496b62712fe8..3992e26a6039 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -881,6 +881,16 @@ static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *
return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
}
+static struct dst_entry *ip6_route_input_lookup(struct net *net,
+ struct net_device *dev,
+ struct flowi6 *fl6, int flags)
+{
+ if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG)
+ flags |= RT6_LOOKUP_F_IFACE;
+
+ return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input);
+}
+
void ip6_route_input(struct sk_buff *skb)
{
const struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -895,10 +905,7 @@ void ip6_route_input(struct sk_buff *skb)
.flowi6_proto = iph->nexthdr,
};
- if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
- flags |= RT6_LOOKUP_F_IFACE;
-
- skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input));
+ skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags));
}
static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
@@ -2537,7 +2544,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
struct sk_buff *skb;
struct rtmsg *rtm;
struct flowi6 fl6;
- int err, iif = 0;
+ int err, iif = 0, oif = 0;
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
if (err < 0)
@@ -2564,15 +2571,29 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
iif = nla_get_u32(tb[RTA_IIF]);
if (tb[RTA_OIF])
- fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]);
+ oif = nla_get_u32(tb[RTA_OIF]);
if (iif) {
struct net_device *dev;
+ int flags = 0;
+
dev = __dev_get_by_index(net, iif);
if (!dev) {
err = -ENODEV;
goto errout;
}
+
+ fl6.flowi6_iif = iif;
+
+ if (!ipv6_addr_any(&fl6.saddr))
+ flags |= RT6_LOOKUP_F_HAS_SADDR;
+
+ rt = (struct rt6_info *)ip6_route_input_lookup(net, dev, &fl6,
+ flags);
+ } else {
+ fl6.flowi6_oif = oif;
+
+ rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
}
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -2587,7 +2608,6 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
skb_reset_mac_header(skb);
skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
- rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6);
skb_dst_set(skb, &rt->dst);
err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
index ba1a3fc39b5c..42cf1390ce9c 100644
--- a/net/irda/irlan/irlan_client.c
+++ b/net/irda/irlan/irlan_client.c
@@ -37,7 +37,6 @@
#include <linux/bitops.h>
#include <net/arp.h>
-#include <asm/system.h>
#include <asm/byteorder.h>
#include <net/irda/irda.h>
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index 579617cca125..7ac4d1becbfc 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -40,7 +40,6 @@
#include <linux/moduleparam.h>
#include <linux/bitops.h>
-#include <asm/system.h>
#include <asm/byteorder.h>
#include <net/irda/irda.h>
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
index 8b61cf0d8a69..32dcaac70b0c 100644
--- a/net/irda/irlan/irlan_provider.c
+++ b/net/irda/irlan/irlan_provider.c
@@ -36,7 +36,6 @@
#include <linux/bitops.h>
#include <linux/slab.h>
-#include <asm/system.h>
#include <asm/byteorder.h>
#include <net/irda/irda.h>
diff --git a/net/irda/timer.c b/net/irda/timer.c
index f418cb2ad49c..1d552b3946fc 100644
--- a/net/irda/timer.c
+++ b/net/irda/timer.c
@@ -24,7 +24,6 @@
*
********************************************************************/
-#include <asm/system.h>
#include <linux/delay.h>
#include <net/irda/timer.h>
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index 8d0324bac01c..ab3d35f23257 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -32,7 +32,6 @@
#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/lapb/lapb_in.c b/net/lapb/lapb_in.c
index 2ec1af5c36cc..f4e3c1accab7 100644
--- a/net/lapb/lapb_in.c
+++ b/net/lapb/lapb_in.c
@@ -30,7 +30,6 @@
#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c
index c75a79540f9f..baab2760f651 100644
--- a/net/lapb/lapb_out.c
+++ b/net/lapb/lapb_out.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/lapb/lapb_subr.c b/net/lapb/lapb_subr.c
index 43a2a7fb327b..066225b4e824 100644
--- a/net/lapb/lapb_subr.c
+++ b/net/lapb/lapb_subr.c
@@ -27,7 +27,6 @@
#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/lapb/lapb_timer.c b/net/lapb/lapb_timer.c
index af6d14b44e2e..f8cd641dfc82 100644
--- a/net/lapb/lapb_timer.c
+++ b/net/lapb/lapb_timer.c
@@ -28,7 +28,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index cc5b7a6e7e0b..778e5916d7c3 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -15,12 +15,6 @@
#include "rate.h"
#include "debugfs.h"
-int mac80211_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#define DEBUGFS_FORMAT_BUFFER_SIZE 100
int mac80211_format_buffer(char __user *userbuf, size_t count,
@@ -50,7 +44,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
#define DEBUGFS_READONLY_FILE_OPS(name) \
static const struct file_operations name## _ops = { \
.read = name## _read, \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -93,7 +87,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
static const struct file_operations reset_ops = {
.write = reset_write,
- .open = mac80211_open_file_generic,
+ .open = simple_open,
.llseek = noop_llseek,
};
@@ -254,7 +248,7 @@ static ssize_t stats_ ##name## _read(struct file *file, \
\
static const struct file_operations stats_ ##name## _ops = { \
.read = stats_ ##name## _read, \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h
index 7c87529630f5..9be4e6d71d00 100644
--- a/net/mac80211/debugfs.h
+++ b/net/mac80211/debugfs.h
@@ -3,7 +3,6 @@
#ifdef CONFIG_MAC80211_DEBUGFS
extern void debugfs_hw_add(struct ieee80211_local *local);
-extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
extern int mac80211_format_buffer(char __user *userbuf, size_t count,
loff_t *ppos, char *fmt, ...);
#else
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 59edcd95a58d..7932767bb482 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -30,7 +30,7 @@ static ssize_t key_##name##_read(struct file *file, \
#define KEY_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
.read = key_##name##_read, \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
}
@@ -45,7 +45,7 @@ static const struct file_operations key_ ##name## _ops = { \
#define KEY_CONF_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
.read = key_conf_##name##_read, \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
}
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index b0fc205411c1..e7af5227e322 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -135,7 +135,7 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \
static const struct file_operations name##_ops = { \
.read = ieee80211_if_read_##name, \
.write = (_write), \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index ceeefd424103..5ccec2c1e9f6 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -33,7 +33,7 @@ static ssize_t sta_ ##name## _read(struct file *file, \
#define STA_OPS(name) \
static const struct file_operations sta_ ##name## _ops = { \
.read = sta_##name##_read, \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
}
@@ -41,7 +41,7 @@ static const struct file_operations sta_ ##name## _ops = { \
static const struct file_operations sta_ ##name## _ops = { \
.read = sta_##name##_read, \
.write = sta_##name##_write, \
- .open = mac80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 12ca9820689a..bbf1100d90d6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3402,8 +3402,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
*/
printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
sdata->name, ifmgd->bssid);
- assoc_data->timeout = jiffies +
- TU_TO_EXP_TIME(req->bss->beacon_interval);
+ assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval);
} else {
assoc_data->have_beacon = true;
assoc_data->sent_assoc = false;
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index b4f7600a3e36..3313c117b322 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -145,7 +145,7 @@ static ssize_t rcname_read(struct file *file, char __user *userbuf,
static const struct file_operations rcname_ops = {
.read = rcname_read,
- .open = mac80211_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
#endif
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 33cd16901378..c70e17677135 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -370,7 +370,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
*/
drv_sw_scan_start(local);
- local->leave_oper_channel_time = 0;
+ local->leave_oper_channel_time = jiffies;
local->next_scan_state = SCAN_DECISION;
local->scan_channel_idx = 0;
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index fe6cb4304d72..52856178c9d7 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -31,7 +31,6 @@
#include <net/net_namespace.h>
#include <net/protocol.h>
#include <net/tcp.h>
-#include <asm/system.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 85312939695f..f843a8833250 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -25,7 +25,6 @@
#include <net/protocol.h>
#include <net/tcp.h>
#include <net/udp.h>
-#include <asm/system.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index cbdb754dbb10..3cc4487ac349 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -735,6 +735,7 @@ __nf_conntrack_alloc(struct net *net, u16 zone,
#ifdef CONFIG_NF_CONNTRACK_ZONES
out_free:
+ atomic_dec(&net->ct.count);
kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
return ERR_PTR(-ENOMEM);
#endif
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 4d70785b953d..e6ddde165612 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -23,7 +23,6 @@
#include <linux/net.h>
#include <linux/skbuff.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <linux/init.h>
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 3eb348bfc4fb..d98c868c148b 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
+#include <linux/atomic.h>
#include <linux/netlink.h>
#include <linux/rculist.h>
#include <linux/slab.h>
@@ -17,7 +18,6 @@
#include <linux/errno.h>
#include <net/netlink.h>
#include <net/sock.h>
-#include <asm/atomic.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 0c8e43810ce3..59530e93fa58 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -150,6 +150,17 @@ err1:
return ret;
}
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout)
+{
+ typeof(nf_ct_timeout_put_hook) timeout_put;
+
+ timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
+ if (timeout_put)
+ timeout_put(timeout);
+}
+#endif
+
static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
{
struct xt_ct_target_info_v1 *info = par->targinfo;
@@ -158,7 +169,9 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
struct nf_conn *ct;
int ret = 0;
u8 proto;
-
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+ struct ctnl_timeout *timeout;
+#endif
if (info->flags & ~XT_CT_NOTRACK)
return -EINVAL;
@@ -216,7 +229,6 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
if (info->timeout) {
typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
- struct ctnl_timeout *timeout;
struct nf_conn_timeout *timeout_ext;
rcu_read_lock();
@@ -245,7 +257,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
pr_info("Timeout policy `%s' can only be "
"used by L3 protocol number %d\n",
info->timeout, timeout->l3num);
- goto err4;
+ goto err5;
}
/* Make sure the timeout policy matches any existing
* protocol tracker, otherwise default to generic.
@@ -258,13 +270,13 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
"used by L4 protocol number %d\n",
info->timeout,
timeout->l4proto->l4proto);
- goto err4;
+ goto err5;
}
timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
- GFP_KERNEL);
+ GFP_ATOMIC);
if (timeout_ext == NULL) {
ret = -ENOMEM;
- goto err4;
+ goto err5;
}
} else {
ret = -ENOENT;
@@ -281,8 +293,12 @@ out:
info->ct = ct;
return 0;
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+err5:
+ __xt_ct_tg_timeout_put(timeout);
err4:
rcu_read_unlock();
+#endif
err3:
nf_conntrack_free(ct);
err2:
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 32bb75324e76..faa48f70b7c9 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -829,12 +829,19 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
return 0;
}
-int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
+static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
{
int len = skb->len;
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, len);
+ return len;
+}
+
+int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
+{
+ int len = __netlink_sendskb(sk, skb);
+
sock_put(sk);
return len;
}
@@ -957,8 +964,7 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
!test_bit(0, &nlk->state)) {
skb_set_owner_r(skb, sk);
- skb_queue_tail(&sk->sk_receive_queue, skb);
- sk->sk_data_ready(sk, skb->len);
+ __netlink_sendskb(sk, skb);
return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
}
return -1;
@@ -1698,10 +1704,8 @@ static int netlink_dump(struct sock *sk)
if (sk_filter(sk, skb))
kfree_skb(skb);
- else {
- skb_queue_tail(&sk->sk_receive_queue, skb);
- sk->sk_data_ready(sk, skb->len);
- }
+ else
+ __netlink_sendskb(sk, skb);
return 0;
}
@@ -1715,10 +1719,8 @@ static int netlink_dump(struct sock *sk)
if (sk_filter(sk, skb))
kfree_skb(skb);
- else {
- skb_queue_tail(&sk->sk_receive_queue, skb);
- sk->sk_data_ready(sk, skb->len);
- }
+ else
+ __netlink_sendskb(sk, skb);
if (cb->done)
cb->done(cb);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 7dab229bfbcc..06592d8b4a2b 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -31,7 +31,6 @@
#include <net/net_namespace.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
#include <linux/mm.h>
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 64e6dde9749d..1c51d7a58f0b 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -21,7 +21,6 @@
#include <linux/if_ether.h> /* For the statistics structure. */
#include <linux/slab.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index 6d4ef6d65b3d..c3073a2ef634 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -24,7 +24,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
index 607fddb4fdbb..0b4bcb2bf38f 100644
--- a/net/netrom/nr_out.c
+++ b/net/netrom/nr_out.c
@@ -23,7 +23,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 2cf330162d7e..70ffff76a967 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -26,7 +26,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
#include <linux/mm.h>
diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c
index 6a947ae50dbd..ca40e2298f5a 100644
--- a/net/netrom/nr_subr.c
+++ b/net/netrom/nr_subr.c
@@ -23,7 +23,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c
index 1cb98e88f5e1..ff2c1b142f57 100644
--- a/net/netrom/nr_timer.c
+++ b/net/netrom/nr_timer.c
@@ -24,7 +24,6 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index 7b76eb7192f3..ef10ffcb4b6f 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -474,7 +474,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
while (remaining_len > 0) {
- frag_len = min_t(u16, local->remote_miu, remaining_len);
+ frag_len = min_t(size_t, local->remote_miu, remaining_len);
pr_debug("Fragment %zd bytes remaining %zd",
frag_len, remaining_len);
@@ -497,7 +497,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
release_sock(sk);
remaining_len -= frag_len;
- msg_ptr += len;
+ msg_ptr += frag_len;
}
kfree(msg_data);
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 2c030505b335..e44e631ea952 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -38,7 +38,6 @@
#include <linux/udp.h>
#include <linux/ethtool.h>
#include <linux/wait.h>
-#include <asm/system.h>
#include <asm/div64.h>
#include <linux/highmem.h>
#include <linux/netfilter_bridge.h>
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ae2d484416dd..4f2c0df79563 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -73,7 +73,6 @@
#include <net/sock.h>
#include <linux/errno.h>
#include <linux/timer.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <asm/page.h>
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 9f60008740e3..9726fe684ab8 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -1130,6 +1130,9 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
int flags = msg->msg_flags;
int err, done;
+ if (len > USHRT_MAX)
+ return -EMSGSIZE;
+
if ((msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|
MSG_CMSG_COMPAT)) ||
!(msg->msg_flags & MSG_EOR))
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index f9ea925ad9cb..c4719ce604c2 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -34,7 +34,6 @@
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/fcntl.h>
#include <linux/termios.h>
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 178ff4f73c85..906cc05bba63 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -21,7 +21,6 @@
#include <linux/if_ether.h>
#include <linux/slab.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <linux/inet.h>
@@ -96,11 +95,11 @@ static int rose_set_mac_address(struct net_device *dev, void *addr)
struct sockaddr *sa = addr;
int err;
- if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len))
+ if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
return 0;
if (dev->flags & IFF_UP) {
- err = rose_add_loopback_node((rose_address *)dev->dev_addr);
+ err = rose_add_loopback_node((rose_address *)sa->sa_data);
if (err)
return err;
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
index 7f7fcb46b4fa..79c4abcfa6b4 100644
--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -26,7 +26,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/tcp_states.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
index 7a02bd1cc5a0..bc5514211b0c 100644
--- a/net/rose/rose_link.c
+++ b/net/rose/rose_link.c
@@ -22,7 +22,6 @@
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/rose/rose_out.c b/net/rose/rose_out.c
index 4ebf33afbe47..9ad98b524646 100644
--- a/net/rose/rose_out.c
+++ b/net/rose/rose_out.c
@@ -21,7 +21,6 @@
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/sock.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index cd9b7ee60f3e..40148932c8a4 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -25,7 +25,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/tcp_states.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/fcntl.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index f6c71caa94b9..47f1fdb346b0 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -22,7 +22,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/tcp_states.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
index b6c8f38cc26c..bc5469d6d9cb 100644
--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -23,7 +23,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/tcp_states.h>
-#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 06b42b7f5a02..92ba71dfe080 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4133,9 +4133,10 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
int __user *optlen)
{
- if (len < sizeof(struct sctp_event_subscribe))
+ if (len <= 0)
return -EINVAL;
- len = sizeof(struct sctp_event_subscribe);
+ if (len > sizeof(struct sctp_event_subscribe))
+ len = sizeof(struct sctp_event_subscribe);
if (put_user(len, optlen))
return -EFAULT;
if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len))
diff --git a/net/socket.c b/net/socket.c
index 12a48d846223..851edcd6b098 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -811,9 +811,9 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
sock = file->private_data;
- flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
- if (more)
- flags |= MSG_MORE;
+ flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+ /* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
+ flags |= more;
return kernel_sendpage(sock, page, offset, size, flags);
}
@@ -2592,7 +2592,7 @@ void socket_seq_show(struct seq_file *seq)
#ifdef CONFIG_COMPAT
static int do_siocgstamp(struct net *net, struct socket *sock,
- unsigned int cmd, struct compat_timeval __user *up)
+ unsigned int cmd, void __user *up)
{
mm_segment_t old_fs = get_fs();
struct timeval ktv;
@@ -2601,15 +2601,14 @@ static int do_siocgstamp(struct net *net, struct socket *sock,
set_fs(KERNEL_DS);
err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
set_fs(old_fs);
- if (!err) {
- err = put_user(ktv.tv_sec, &up->tv_sec);
- err |= __put_user(ktv.tv_usec, &up->tv_usec);
- }
+ if (!err)
+ err = compat_put_timeval(up, &ktv);
+
return err;
}
static int do_siocgstampns(struct net *net, struct socket *sock,
- unsigned int cmd, struct compat_timespec __user *up)
+ unsigned int cmd, void __user *up)
{
mm_segment_t old_fs = get_fs();
struct timespec kts;
@@ -2618,10 +2617,9 @@ static int do_siocgstampns(struct net *net, struct socket *sock,
set_fs(KERNEL_DS);
err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
set_fs(old_fs);
- if (!err) {
- err = put_user(kts.tv_sec, &up->tv_sec);
- err |= __put_user(kts.tv_nsec, &up->tv_nsec);
- }
+ if (!err)
+ err = compat_put_timespec(up, &kts);
+
return err;
}
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index f21ece088764..de0b0f39d9d8 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -830,6 +830,8 @@ static ssize_t cache_do_downcall(char *kaddr, const char __user *buf,
{
ssize_t ret;
+ if (count == 0)
+ return -EINVAL;
if (copy_from_user(kaddr, buf, count))
return -EFAULT;
kaddr[count] = '\0';
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 7a4cb5fdc212..67972462a543 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -17,7 +17,6 @@
* Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de>
*/
-#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index c84c0e0c41cb..0af37fc46818 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1014,6 +1014,7 @@ enum {
RPCAUTH_statd,
RPCAUTH_nfsd4_cb,
RPCAUTH_cache,
+ RPCAUTH_nfsd,
RPCAUTH_RootEOF
};
@@ -1046,6 +1047,10 @@ static const struct rpc_filelist files[] = {
.name = "cache",
.mode = S_IFDIR | S_IRUGO | S_IXUGO,
},
+ [RPCAUTH_nfsd] = {
+ .name = "nfsd",
+ .mode = S_IFDIR | S_IRUGO | S_IXUGO,
+ },
};
/*
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 207a74696c9f..78ac39fd9fe7 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -734,7 +734,7 @@ void rpcb_getport_async(struct rpc_task *task)
map->r_vers = clnt->cl_vers;
map->r_prot = xprt->prot;
map->r_port = 0;
- map->r_xprt = xprt_get(xprt);
+ map->r_xprt = xprt;
map->r_status = -EIO;
switch (bind_version) {
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index bcd574f2ac56..521d8f7dc833 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -507,7 +507,7 @@ static int unix_gid_parse(struct cache_detail *cd,
time_t expiry;
struct unix_gid ug, *ugp;
- if (mlen <= 0 || mesg[mlen-1] != '\n')
+ if (mesg[mlen - 1] != '\n')
return -EINVAL;
mesg[mlen-1] = 0;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 40ae884db865..824d32fb3121 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1381,8 +1381,6 @@ void svc_sock_update_bufs(struct svc_serv *serv)
spin_lock_bh(&serv->sv_lock);
list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list)
set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
- list_for_each_entry(svsk, &serv->sv_tempsocks, sk_xprt.xpt_list)
- set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
spin_unlock_bh(&serv->sv_lock);
}
EXPORT_SYMBOL_GPL(svc_sock_update_bufs);
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
index 09af4fab1a45..8343737e85f4 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -47,6 +47,7 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/svc_rdma.h>
+#include "xprt_rdma.h"
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
index 9530ef2d40dc..8d2edddf48cf 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
@@ -60,21 +60,11 @@ static u32 *decode_read_list(u32 *va, u32 *vaend)
struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va;
while (ch->rc_discrim != xdr_zero) {
- u64 ch_offset;
-
if (((unsigned long)ch + sizeof(struct rpcrdma_read_chunk)) >
(unsigned long)vaend) {
dprintk("svcrdma: vaend=%p, ch=%p\n", vaend, ch);
return NULL;
}
-
- ch->rc_discrim = ntohl(ch->rc_discrim);
- ch->rc_position = ntohl(ch->rc_position);
- ch->rc_target.rs_handle = ntohl(ch->rc_target.rs_handle);
- ch->rc_target.rs_length = ntohl(ch->rc_target.rs_length);
- va = (u32 *)&ch->rc_target.rs_offset;
- xdr_decode_hyper(va, &ch_offset);
- put_unaligned(ch_offset, (u64 *)va);
ch++;
}
return (u32 *)&ch->rc_position;
@@ -91,7 +81,7 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
*byte_count = 0;
*ch_count = 0;
for (; ch->rc_discrim != 0; ch++) {
- *byte_count = *byte_count + ch->rc_target.rs_length;
+ *byte_count = *byte_count + ntohl(ch->rc_target.rs_length);
*ch_count = *ch_count + 1;
}
}
@@ -108,7 +98,8 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
*/
static u32 *decode_write_list(u32 *va, u32 *vaend)
{
- int ch_no;
+ int nchunks;
+
struct rpcrdma_write_array *ary =
(struct rpcrdma_write_array *)va;
@@ -121,37 +112,24 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
return NULL;
}
- ary->wc_discrim = ntohl(ary->wc_discrim);
- ary->wc_nchunks = ntohl(ary->wc_nchunks);
+ nchunks = ntohl(ary->wc_nchunks);
if (((unsigned long)&ary->wc_array[0] +
- (sizeof(struct rpcrdma_write_chunk) * ary->wc_nchunks)) >
+ (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
(unsigned long)vaend) {
dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
- ary, ary->wc_nchunks, vaend);
+ ary, nchunks, vaend);
return NULL;
}
- for (ch_no = 0; ch_no < ary->wc_nchunks; ch_no++) {
- u64 ch_offset;
-
- ary->wc_array[ch_no].wc_target.rs_handle =
- ntohl(ary->wc_array[ch_no].wc_target.rs_handle);
- ary->wc_array[ch_no].wc_target.rs_length =
- ntohl(ary->wc_array[ch_no].wc_target.rs_length);
- va = (u32 *)&ary->wc_array[ch_no].wc_target.rs_offset;
- xdr_decode_hyper(va, &ch_offset);
- put_unaligned(ch_offset, (u64 *)va);
- }
-
/*
* rs_length is the 2nd 4B field in wc_target and taking its
* address skips the list terminator
*/
- return (u32 *)&ary->wc_array[ch_no].wc_target.rs_length;
+ return (u32 *)&ary->wc_array[nchunks].wc_target.rs_length;
}
static u32 *decode_reply_array(u32 *va, u32 *vaend)
{
- int ch_no;
+ int nchunks;
struct rpcrdma_write_array *ary =
(struct rpcrdma_write_array *)va;
@@ -164,28 +142,15 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
return NULL;
}
- ary->wc_discrim = ntohl(ary->wc_discrim);
- ary->wc_nchunks = ntohl(ary->wc_nchunks);
+ nchunks = ntohl(ary->wc_nchunks);
if (((unsigned long)&ary->wc_array[0] +
- (sizeof(struct rpcrdma_write_chunk) * ary->wc_nchunks)) >
+ (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
(unsigned long)vaend) {
dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
- ary, ary->wc_nchunks, vaend);
+ ary, nchunks, vaend);
return NULL;
}
- for (ch_no = 0; ch_no < ary->wc_nchunks; ch_no++) {
- u64 ch_offset;
-
- ary->wc_array[ch_no].wc_target.rs_handle =
- ntohl(ary->wc_array[ch_no].wc_target.rs_handle);
- ary->wc_array[ch_no].wc_target.rs_length =
- ntohl(ary->wc_array[ch_no].wc_target.rs_length);
- va = (u32 *)&ary->wc_array[ch_no].wc_target.rs_offset;
- xdr_decode_hyper(va, &ch_offset);
- put_unaligned(ch_offset, (u64 *)va);
- }
-
- return (u32 *)&ary->wc_array[ch_no];
+ return (u32 *)&ary->wc_array[nchunks];
}
int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
@@ -386,13 +351,14 @@ void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *ary,
void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary,
int chunk_no,
- u32 rs_handle, u64 rs_offset,
+ __be32 rs_handle,
+ __be64 rs_offset,
u32 write_len)
{
struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target;
- seg->rs_handle = htonl(rs_handle);
+ seg->rs_handle = rs_handle;
+ seg->rs_offset = rs_offset;
seg->rs_length = htonl(write_len);
- xdr_encode_hyper((u32 *) &seg->rs_offset, rs_offset);
}
void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt,
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index df67211c4baf..41cb63b623df 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -147,7 +147,7 @@ static int map_read_chunks(struct svcxprt_rdma *xprt,
page_off = 0;
ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
ch_no = 0;
- ch_bytes = ch->rc_target.rs_length;
+ ch_bytes = ntohl(ch->rc_target.rs_length);
head->arg.head[0] = rqstp->rq_arg.head[0];
head->arg.tail[0] = rqstp->rq_arg.tail[0];
head->arg.pages = &head->pages[head->count];
@@ -183,7 +183,7 @@ static int map_read_chunks(struct svcxprt_rdma *xprt,
ch_no++;
ch++;
chl_map->ch[ch_no].start = sge_no;
- ch_bytes = ch->rc_target.rs_length;
+ ch_bytes = ntohl(ch->rc_target.rs_length);
/* If bytes remaining account for next chunk */
if (byte_count) {
head->arg.page_len += ch_bytes;
@@ -281,11 +281,12 @@ static int fast_reg_read_chunks(struct svcxprt_rdma *xprt,
offset = 0;
ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
for (ch_no = 0; ch_no < ch_count; ch_no++) {
+ int len = ntohl(ch->rc_target.rs_length);
rpl_map->sge[ch_no].iov_base = frmr->kva + offset;
- rpl_map->sge[ch_no].iov_len = ch->rc_target.rs_length;
+ rpl_map->sge[ch_no].iov_len = len;
chl_map->ch[ch_no].count = 1;
chl_map->ch[ch_no].start = ch_no;
- offset += ch->rc_target.rs_length;
+ offset += len;
ch++;
}
@@ -316,7 +317,7 @@ static int rdma_set_ctxt_sge(struct svcxprt_rdma *xprt,
for (i = 0; i < count; i++) {
ctxt->sge[i].length = 0; /* in case map fails */
if (!frmr) {
- BUG_ON(0 == virt_to_page(vec[i].iov_base));
+ BUG_ON(!virt_to_page(vec[i].iov_base));
off = (unsigned long)vec[i].iov_base & ~PAGE_MASK;
ctxt->sge[i].addr =
ib_dma_map_page(xprt->sc_cm_id->device,
@@ -426,6 +427,7 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
ch->rc_discrim != 0; ch++, ch_no++) {
+ u64 rs_offset;
next_sge:
ctxt = svc_rdma_get_context(xprt);
ctxt->direction = DMA_FROM_DEVICE;
@@ -440,10 +442,10 @@ next_sge:
read_wr.opcode = IB_WR_RDMA_READ;
ctxt->wr_op = read_wr.opcode;
read_wr.send_flags = IB_SEND_SIGNALED;
- read_wr.wr.rdma.rkey = ch->rc_target.rs_handle;
- read_wr.wr.rdma.remote_addr =
- get_unaligned(&(ch->rc_target.rs_offset)) +
- sgl_offset;
+ read_wr.wr.rdma.rkey = ntohl(ch->rc_target.rs_handle);
+ xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset,
+ &rs_offset);
+ read_wr.wr.rdma.remote_addr = rs_offset + sgl_offset;
read_wr.sg_list = ctxt->sge;
read_wr.num_sge =
rdma_read_max_sge(xprt, chl_map->ch[ch_no].count);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 249a835b703f..42eb7ba0b903 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -409,21 +409,21 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
u64 rs_offset;
arg_ch = &arg_ary->wc_array[chunk_no].wc_target;
- write_len = min(xfer_len, arg_ch->rs_length);
+ write_len = min(xfer_len, ntohl(arg_ch->rs_length));
/* Prepare the response chunk given the length actually
* written */
- rs_offset = get_unaligned(&(arg_ch->rs_offset));
+ xdr_decode_hyper((__be32 *)&arg_ch->rs_offset, &rs_offset);
svc_rdma_xdr_encode_array_chunk(res_ary, chunk_no,
- arg_ch->rs_handle,
- rs_offset,
- write_len);
+ arg_ch->rs_handle,
+ arg_ch->rs_offset,
+ write_len);
chunk_off = 0;
while (write_len) {
int this_write;
this_write = min(write_len, max_write);
ret = send_write(xprt, rqstp,
- arg_ch->rs_handle,
+ ntohl(arg_ch->rs_handle),
rs_offset + chunk_off,
xdr_off,
this_write,
@@ -457,6 +457,7 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
u32 xdr_off;
int chunk_no;
int chunk_off;
+ int nchunks;
struct rpcrdma_segment *ch;
struct rpcrdma_write_array *arg_ary;
struct rpcrdma_write_array *res_ary;
@@ -476,26 +477,27 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
max_write = xprt->sc_max_sge * PAGE_SIZE;
/* xdr offset starts at RPC message */
+ nchunks = ntohl(arg_ary->wc_nchunks);
for (xdr_off = 0, chunk_no = 0;
- xfer_len && chunk_no < arg_ary->wc_nchunks;
+ xfer_len && chunk_no < nchunks;
chunk_no++) {
u64 rs_offset;
ch = &arg_ary->wc_array[chunk_no].wc_target;
- write_len = min(xfer_len, ch->rs_length);
+ write_len = min(xfer_len, htonl(ch->rs_length));
/* Prepare the reply chunk given the length actually
* written */
- rs_offset = get_unaligned(&(ch->rs_offset));
+ xdr_decode_hyper((__be32 *)&ch->rs_offset, &rs_offset);
svc_rdma_xdr_encode_array_chunk(res_ary, chunk_no,
- ch->rs_handle, rs_offset,
- write_len);
+ ch->rs_handle, ch->rs_offset,
+ write_len);
chunk_off = 0;
while (write_len) {
int this_write;
this_write = min(write_len, max_write);
ret = send_write(xprt, rqstp,
- ch->rs_handle,
+ ntohl(ch->rs_handle),
rs_offset + chunk_off,
xdr_off,
this_write,
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 894cb42db91d..73b428bef598 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -51,6 +51,7 @@
#include <rdma/rdma_cm.h>
#include <linux/sunrpc/svc_rdma.h>
#include <linux/export.h>
+#include "xprt_rdma.h"
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
@@ -90,12 +91,6 @@ struct svc_xprt_class svc_rdma_class = {
.xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
};
-/* WR context cache. Created in svc_rdma.c */
-extern struct kmem_cache *svc_rdma_ctxt_cachep;
-
-/* Workqueue created in svc_rdma.c */
-extern struct workqueue_struct *svc_rdma_wq;
-
struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
{
struct svc_rdma_op_ctxt *ctxt;
@@ -150,9 +145,6 @@ void svc_rdma_put_context(struct svc_rdma_op_ctxt *ctxt, int free_pages)
atomic_dec(&xprt->sc_ctxt_used);
}
-/* Temporary NFS request map cache. Created in svc_rdma.c */
-extern struct kmem_cache *svc_rdma_map_cachep;
-
/*
* Temporary NFS req mappings are shared across all transport
* instances. These are short lived and should be bounded by the number
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 08c5d5a128fc..9a66c95b5837 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -343,4 +343,11 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *);
*/
int rpcrdma_marshal_req(struct rpc_rqst *);
+/* Temporary NFS request map cache. Created in svc_rdma.c */
+extern struct kmem_cache *svc_rdma_map_cachep;
+/* WR context cache. Created in svc_rdma.c */
+extern struct kmem_cache *svc_rdma_ctxt_cachep;
+/* Workqueue created in svc_rdma.c */
+extern struct workqueue_struct *svc_rdma_wq;
+
#endif /* _LINUX_SUNRPC_XPRT_RDMA_H */
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 92bc5181dbeb..890b03f8d877 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2475,6 +2475,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
static struct rpc_xprt_ops bc_tcp_ops = {
.reserve_xprt = xprt_reserve_xprt,
.release_xprt = xprt_release_xprt,
+ .rpcbind = xs_local_rpcbind,
.buf_alloc = bc_malloc,
.buf_free = bc_free,
.send_request = bc_send_request,
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 39765bcfb472..920cabe0461b 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -13,12 +13,6 @@
#include "core.h"
#include "debugfs.h"
-static int cfg80211_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
static ssize_t name## _read(struct file *file, char __user *userbuf, \
size_t count, loff_t *ppos) \
@@ -33,7 +27,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
\
static const struct file_operations name## _ops = { \
.read = name## _read, \
- .open = cfg80211_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -102,7 +96,7 @@ static ssize_t ht40allow_map_read(struct file *file,
static const struct file_operations ht40allow_map_ops = {
.read = ht40allow_map_read,
- .open = cfg80211_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3e82af72bf5..5e261234d271 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1297,6 +1297,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
goto bad_res;
}
+ if (!netif_running(netdev)) {
+ result = -ENETDOWN;
+ goto bad_res;
+ }
+
nla_for_each_nested(nl_txq_params,
info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
rem_txq_params) {
@@ -6407,7 +6412,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_get_key,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6439,7 +6444,7 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_set_beacon,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6447,7 +6452,7 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_start_ap,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6455,7 +6460,7 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.doit = nl80211_stop_ap,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6471,7 +6476,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_set_station,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6487,7 +6492,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_del_station,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6520,7 +6525,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_del_mpath,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6528,7 +6533,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_set_bss,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6554,7 +6559,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_get_mesh_config,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6687,7 +6692,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_setdel_pmksa,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6695,7 +6700,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_setdel_pmksa,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6703,7 +6708,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_flush_pmksa,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
@@ -6863,7 +6868,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_probe_client,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 0af7f54e4f61..af648e08e61b 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -780,8 +780,10 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
if (cmd == SIOCSIWENCODEEXT) {
struct iw_encode_ext *ee = (void *) extra;
- if (iwp->length < sizeof(*ee) + ee->key_len)
- return -EFAULT;
+ if (iwp->length < sizeof(*ee) + ee->key_len) {
+ err = -EFAULT;
+ goto out;
+ }
}
}