diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index a892cbb7bbf3..cd9e3a7cf1a3 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -182,24 +182,36 @@ pipe(p, uap)
 	pipeinit(wpipe);
 	wpipe->pipe_state |= PIPE_DIRECTOK;
 
+	error = falloc(p, &rf, &fd);
+	if (error) {
+		pipeclose(rpipe);
+		pipeclose(wpipe);
+		return (error);
+	}
+	fhold(rf);
+	p->p_retval[0] = fd;
+
 	/*
 	 * Warning: once we've gotten past allocation of the fd for the
 	 * read-side, we can only drop the read side via fdrop() in order
 	 * to avoid races against processes which manage to dup() the read
 	 * side while we are blocked trying to allocate the write side.
 	 */
-	error = falloc(p, &rf, &fd);
-	if (error)
-		goto free2;
-	fhold(rf);
-	p->p_retval[0] = fd;
 	rf->f_flag = FREAD | FWRITE;
 	rf->f_type = DTYPE_PIPE;
 	rf->f_data = (caddr_t)rpipe;
 	rf->f_ops = &pipeops;
 	error = falloc(p, &wf, &fd);
-	if (error)
-		goto free3;
+	if (error) {
+		if (fdp->fd_ofiles[p->p_retval[0]] == rf) {
+			fdp->fd_ofiles[p->p_retval[0]] = NULL;
+			fdrop(rf, p);
+		}
+		fdrop(rf, p);
+		/* rpipe has been closed by fdrop(). */
+		pipeclose(wpipe);
+		return (error);
+	}
 	wf->f_flag = FREAD | FWRITE;
 	wf->f_type = DTYPE_PIPE;
 	wf->f_data = (caddr_t)wpipe;
@@ -211,18 +223,6 @@ pipe(p, uap)
 	fdrop(rf, p);
 
 	return (0);
-free3:
-	if (fdp->fd_ofiles[p->p_retval[0]] == rf) {
-		fdp->fd_ofiles[p->p_retval[0]] = NULL;
-		fdrop(rf, p);
-	}
-	fdrop(rf, p);
-	/* rpipe has been closed by fdrop() */
-	rpipe = NULL;
-free2:
-	(void)pipeclose(wpipe);
-	(void)pipeclose(rpipe);
-	return (error);
 }
 
 /*