svn commit: r198017 - user/kmacy/releng_8_fcs/sys/kern

Kip Macy kmacy at FreeBSD.org
Tue Oct 13 04:40:21 UTC 2009


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);
 }
 


More information about the svn-src-user mailing list