diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-18 00:24:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-18 00:24:27 +0000 |
commit | b9558d5f86c471a125abf1fb3a3882fb053b1f8c (patch) | |
tree | 707b53ec64e740a7da87d5f36485e3cd9b1c794e /net/socket.c | |
parent | b3ac367c7a3e6047abe74817db27e34e759f279f (diff) |
Merge with Linux 2.3.41.
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/net/socket.c b/net/socket.c index 4b4bc45b9..b1a0d5400 100644 --- a/net/socket.c +++ b/net/socket.c @@ -176,7 +176,10 @@ static __inline__ void net_family_read_unlock(void) * 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 @@ static int sock_map_fd(struct socket *sock) 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 @@ struct socket *sock_alloc(void) sock->sk = NULL; sock->file = NULL; - sockets_in_use++; + sockets_in_use[smp_processor_id()].counter++; return sock; } @@ -383,9 +377,12 @@ void sock_release(struct socket *sock) 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 @@ asmlinkage long sys_listen(int fd, int backlog) 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 @@ asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_a 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 @@ asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags, 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 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags) 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 @@ void __init sock_init(void) 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 @@ int socket_get_info(char *buffer, char **start, off_t offset, int length) len -= offset; if (len > length) len = length; + if (len < 0) + len = 0; return len; } |