Date: Tue, 13 Oct 2009 04:40:20 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r198017 - user/kmacy/releng_8_fcs/sys/kern Message-ID: <200910130440.n9D4eKOb094969@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Tue Oct 13 04:40:20 2009 New Revision: 198017 URL: http://svn.freebsd.org/changeset/base/198017 Log: clear SB_SENDING flag in socketref_free to avoid race with sofree Modified: user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c Modified: user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c ============================================================================== --- user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c Tue Oct 13 04:26:04 2009 (r198016) +++ user/kmacy/releng_8_fcs/sys/kern/uipc_socket.c Tue Oct 13 04:40:20 2009 (r198017) @@ -3393,10 +3393,13 @@ socketref_free(struct socketref *sr) struct file *sock_fp = sr->sr_sock_fp; struct proc *p = sr->sr_proc; struct ucred *cred = sr->sr_ucred; + struct sockbuf *sb = &sr->sr_so->so_snd; if (cred != NULL) crfree(cred); vrele(fp->f_vnode); + sb->sb_flags &= ~(SB_SENDING|SB_SENDING_TASK); + SOCKBUF_UNLOCK(sb); fdrop(fp, NULL); fdrop(sock_fp, NULL); PRELE(p); @@ -3515,10 +3518,16 @@ sendfile_task_func(void *context, int pe sock_fp = sr->sr_sock_fp; fp = sr->sr_fp; - if (sock_fp->f_type != DTYPE_SOCKET) - goto done; - + if (sock_fp->f_type != DTYPE_SOCKET) { + printf("bad socket type 0x%x\n", sock_fp->f_type); + /* XXX memory leak */ + return; + } + so = sock_fp->f_data; + sb = &so->so_snd; + SOCKBUF_UNLOCK_ASSERT(sb); + SOCKBUF_LOCK(sb); if ((so->so_state & SS_ISCONNECTED) == 0) goto done; @@ -3526,13 +3535,9 @@ sendfile_task_func(void *context, int pe (sr->sr_ucred = crdup(sr->sr_proc->p_ucred)) == NULL) goto done; - sb = &so->so_snd; - SOCKBUF_UNLOCK_ASSERT(sb); - SOCKBUF_LOCK(sb); sb->sb_flags &= ~(SB_SENDING|SB_SENDING_TASK); if (sb->sb_state & SBS_CANTSENDMORE) { CTR1(KTR_SPARE2, "SBS_CANTSENDMORE - socket %p", so); - sowwakeup_locked(so); goto done; } else if (sowriteable(so)) { sb->sb_flags |= (SB_SENDING|SB_SENDING_TASK); @@ -3555,7 +3560,6 @@ sendfile_task_func(void *context, int pe sr->sr_uap.offset += sbytes; if (sr->sr_uap.nbytes) sr->sr_uap.nbytes -= sbytes; - sb->sb_flags &= ~(SB_SENDING|SB_SENDING_TASK); if (error == EAGAIN) { if (sr->sr_uap.offset + sbytes == sr->sr_vnp_size) { CTR0(KTR_SPARE2, "EAGAIN on full send"); @@ -3574,9 +3578,9 @@ sendfile_task_func(void *context, int pe CTR1(KTR_SPARE2, "error %d", error); #endif - sowwakeup_locked(so); done: - SOCKBUF_UNLOCK_ASSERT(sb); + SOCKBUF_LOCK_ASSERT(sb); + sowwakeup_locked(so); socketref_free(sr); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910130440.n9D4eKOb094969>