]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/socket.c
xps: Transmit Packet Steering
[net-next-2.6.git] / net / socket.c
index 5247ae10f374e9a9fe2331d8e1ad0c83f0da6f32..c898df76e924f3d9a0e51f1c102f65018ab16e84 100644 (file)
@@ -156,7 +156,7 @@ static const struct file_operations socket_file_ops = {
  */
 
 static DEFINE_SPINLOCK(net_family_lock);
-static const struct net_proto_family *net_families[NPROTO] __read_mostly;
+static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
 
 /*
  *     Statistics counters of the socket lists
@@ -1200,7 +1200,7 @@ int __sock_create(struct net *net, int family, int type, int protocol,
         * requested real, full-featured networking support upon configuration.
         * Otherwise module support will break!
         */
-       if (net_families[family] == NULL)
+       if (rcu_access_pointer(net_families[family]) == NULL)
                request_module("net-pf-%d", family);
 #endif
 
@@ -1652,6 +1652,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
        struct iovec iov;
        int fput_needed;
 
+       if (len > INT_MAX)
+               len = INT_MAX;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -1709,6 +1711,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        int err, err2;
        int fput_needed;
 
+       if (size > INT_MAX)
+               size = INT_MAX;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -2328,10 +2332,11 @@ int sock_register(const struct net_proto_family *ops)
        }
 
        spin_lock(&net_family_lock);
-       if (net_families[ops->family])
+       if (rcu_dereference_protected(net_families[ops->family],
+                                     lockdep_is_held(&net_family_lock)))
                err = -EEXIST;
        else {
-               net_families[ops->family] = ops;
+               rcu_assign_pointer(net_families[ops->family], ops);
                err = 0;
        }
        spin_unlock(&net_family_lock);
@@ -2359,7 +2364,7 @@ void sock_unregister(int family)
        BUG_ON(family < 0 || family >= NPROTO);
 
        spin_lock(&net_family_lock);
-       net_families[family] = NULL;
+       rcu_assign_pointer(net_families[family], NULL);
        spin_unlock(&net_family_lock);
 
        synchronize_rcu();