patch-2.3.41 linux/net/socket.c
Next file: linux/net/sunrpc/xprt.c
Previous file: linux/net/rose/af_rose.c
Back to the patch index
Back to the overall index
- Lines: 124
- Date:
Wed Jan 26 09:40:08 2000
- Orig file:
v2.3.40/linux/net/socket.c
- Orig date:
Fri Jan 21 18:19:17 2000
diff -u --recursive --new-file v2.3.40/linux/net/socket.c linux/net/socket.c
@@ -176,7 +176,10 @@
* Statistics counters of the socket lists
*/
-static int sockets_in_use = 0;
+static union {
+ int counter;
+ char __pad[SMP_CACHE_BYTES];
+} sockets_in_use[NR_CPUS] __cacheline_aligned = {{0}};
/*
* Support routines. Move socket addresses back and forth across the kernel/user
@@ -261,23 +264,14 @@
goto out;
}
- lock_kernel();
file->f_dentry = d_alloc_root(sock->inode);
if (!file->f_dentry) {
- unlock_kernel();
put_filp(file);
put_unused_fd(fd);
fd = -ENOMEM;
goto out;
}
- /*
- * The socket maintains a reference to the inode, so we
- * have to increment the count.
- */
- sock->inode->i_count++;
- unlock_kernel();
-
file->f_op = &socket_file_ops;
file->f_mode = 3;
file->f_flags = O_RDWR;
@@ -360,7 +354,7 @@
sock->sk = NULL;
sock->file = NULL;
- sockets_in_use++;
+ sockets_in_use[smp_processor_id()].counter++;
return sock;
}
@@ -383,9 +377,12 @@
if (sock->fasync_list)
printk(KERN_ERR "sock_release: fasync list not empty!\n");
- --sockets_in_use; /* Bookkeeping.. */
+ sockets_in_use[smp_processor_id()].counter--;
+ if (!sock->file) {
+ iput(sock->inode);
+ return;
+ }
sock->file=NULL;
- iput(sock->inode);
}
int sock_sendmsg(struct socket *sock, struct msghdr *msg, int size)
@@ -889,8 +886,6 @@
int err;
if ((sock = sockfd_lookup(fd, &err)) != NULL) {
- if ((unsigned) backlog == 0) /* BSDism */
- backlog = 1;
if ((unsigned) backlog > SOMAXCONN)
backlog = SOMAXCONN;
err=sock->ops->listen(sock, backlog);
@@ -943,6 +938,9 @@
goto out_release;
}
+ /* File flags are inherited via accept(). It looks silly, but we
+ * have to be compatible with another OSes.
+ */
if ((err = sock_map_fd(newsock)) < 0)
goto out_release;
@@ -1119,7 +1117,7 @@
flags |= MSG_DONTWAIT;
err=sock_recvmsg(sock, &msg, size, flags);
- if(err >= 0 && addr != NULL)
+ if(err >= 0 && addr != NULL && msg.msg_namelen)
{
err2=move_addr_to_user(address, msg.msg_namelen, addr, addr_len);
if(err2<0)
@@ -1341,7 +1339,7 @@
goto out_freeiov;
len = err;
- if (uaddr != NULL) {
+ if (uaddr != NULL && msg_sys.msg_namelen) {
err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
if (err < 0)
goto out_freeiov;
@@ -1595,7 +1593,17 @@
int socket_get_info(char *buffer, char **start, off_t offset, int length)
{
- int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use);
+ int len, cpu;
+ int counter = 0;
+
+ for (cpu=0; cpu<smp_num_cpus; cpu++)
+ counter += sockets_in_use[cpu].counter;
+
+ /* It can be negative, by the way. 8) */
+ if (counter < 0)
+ counter = 0;
+
+ len = sprintf(buffer, "sockets: used %d\n", counter);
if (offset >= len)
{
*start = buffer;
@@ -1605,5 +1613,7 @@
len -= offset;
if (len > length)
len = length;
+ if (len < 0)
+ len = 0;
return len;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)