From 20bdac8a4fb4dcff121f014ce879612a272020ab Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 25 May 2006 15:10:13 +0000 Subject: [PATCH] Use getsock() and fput() instead of fgetsock() and fputsock() in sendfile(). This causes sendfile() to use the file descriptor reference to the socket instead of bumping the socket reference count, which avoids an additional refcount operation, as well as a potential expensive socket refcount drop, which can lead to contention on the accept mutex. This change also has the side effect of further reducing the number of cases where an in-progress I/O operation can occur on a socket after close, as using the file descriptor refcount prevents the socket from closing while in use. MFC after: 3 months --- sys/kern/uipc_syscalls.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index cb47c307942..5cd6f9bed6b 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1802,6 +1802,7 @@ int kern_sendfile(struct thread *td, struct sendfile_args *uap, struct uio *hdr_uio, struct uio *trl_uio, int compat) { + struct file *sock_fp; struct vnode *vp; struct vm_object *obj = NULL; struct socket *so = NULL; @@ -1845,8 +1846,9 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap, error = EINVAL; goto done; } - if ((error = fgetsock(td, uap->s, &so, NULL)) != 0) + if ((error = getsock(td->td_proc->p_fd, uap->s, &sock_fp, NULL)) != 0) goto done; + so = sock_fp->f_data; if (so->so_type != SOCK_STREAM) { error = EINVAL; goto done; @@ -2196,7 +2198,7 @@ done: VFS_UNLOCK_GIANT(vfslocked); } if (so) - fputsock(so); + fdrop(sock_fp, td); if (m_header) m_freem(m_header);