Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Jun 2013 02:27:13 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r252288 - in stable/9/sys: kern sys
Message-ID:  <201306270227.r5R2RDTc056963@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Thu Jun 27 02:27:13 2013
New Revision: 252288
URL: http://svnweb.freebsd.org/changeset/base/252288

Log:
  MFC r249480:
  Add fdallocn function and use it when passing fds over unix socket.
  
  This gets rid of "unp_externalize fdalloc failed" panic.

Modified:
  stable/9/sys/kern/kern_descrip.c
  stable/9/sys/kern/uipc_usrreq.c
  stable/9/sys/sys/filedesc.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/sys/   (props changed)

Modified: stable/9/sys/kern/kern_descrip.c
==============================================================================
--- stable/9/sys/kern/kern_descrip.c	Thu Jun 27 00:56:09 2013	(r252287)
+++ stable/9/sys/kern/kern_descrip.c	Thu Jun 27 02:27:13 2013	(r252288)
@@ -1588,6 +1588,34 @@ fdalloc(struct thread *td, int minfd, in
 }
 
 /*
+ * Allocate n file descriptors for the process.
+ */
+int
+fdallocn(struct thread *td, int minfd, int *fds, int n)
+{
+	struct proc *p = td->td_proc;
+	struct filedesc *fdp = p->p_fd;
+	int i;
+
+	FILEDESC_XLOCK_ASSERT(fdp);
+
+	if (!fdavail(td, n))
+		return (EMFILE);
+
+	for (i = 0; i < n; i++)
+		if (fdalloc(td, 0, &fds[i]) != 0)
+			break;
+
+	if (i < n) {
+		for (i--; i >= 0; i--)
+			fdunused(fdp, fds[i]);
+		return (EMFILE);
+	}
+
+	return (0);
+}
+
+/*
  * Check to see whether n user file descriptors are available to the process
  * p.
  */

Modified: stable/9/sys/kern/uipc_usrreq.c
==============================================================================
--- stable/9/sys/kern/uipc_usrreq.c	Thu Jun 27 00:56:09 2013	(r252287)
+++ stable/9/sys/kern/uipc_usrreq.c	Thu Jun 27 02:27:13 2013	(r252288)
@@ -1684,7 +1684,6 @@ unp_externalize(struct mbuf *control, st
 	void *data;
 	socklen_t clen = control->m_len, datalen;
 	int error, newfds;
-	int f;
 	u_int newlen;
 
 	UNP_LINK_UNLOCK_ASSERT();
@@ -1710,14 +1709,6 @@ unp_externalize(struct mbuf *control, st
 				goto next;
 			}
 			FILEDESC_XLOCK(td->td_proc->p_fd);
-			/* if the new FD's will not fit free them.  */
-			if (!fdavail(td, newfds)) {
-				FILEDESC_XUNLOCK(td->td_proc->p_fd);
-				error = EMSGSIZE;
-				unp_freerights(rp, newfds);
-				goto next;
-			}
-
 			/*
 			 * Now change each pointer to an fd in the global
 			 * table to an integer that is the index to the local
@@ -1736,13 +1727,18 @@ unp_externalize(struct mbuf *control, st
 
 			fdp = (int *)
 			    CMSG_DATA(mtod(*controlp, struct cmsghdr *));
+			if (fdallocn(td, 0, fdp, newfds) != 0) {
+				FILEDESC_XUNLOCK(td->td_proc->p_fd);
+				error = EMSGSIZE;
+				unp_freerights(rp, newfds);
+				m_freem(*controlp);
+				*controlp = NULL;
+				goto next;
+			}
 			for (i = 0; i < newfds; i++) {
-				if (fdalloc(td, 0, &f))
-					panic("unp_externalize fdalloc failed");
 				fp = *rp++;
-				td->td_proc->p_fd->fd_ofiles[f] = fp;
+				td->td_proc->p_fd->fd_ofiles[fdp[i]] = fp;
 				unp_externalize_fp(fp);
-				*fdp++ = f;
 			}
 			FILEDESC_XUNLOCK(td->td_proc->p_fd);
 		} else {

Modified: stable/9/sys/sys/filedesc.h
==============================================================================
--- stable/9/sys/sys/filedesc.h	Thu Jun 27 00:56:09 2013	(r252287)
+++ stable/9/sys/sys/filedesc.h	Thu Jun 27 02:27:13 2013	(r252288)
@@ -116,6 +116,7 @@ int	falloc(struct thread *td, struct fil
 int	falloc_noinstall(struct thread *td, struct file **resultfp);
 int	finstall(struct thread *td, struct file *fp, int *resultfp, int flags);
 int	fdalloc(struct thread *td, int minfd, int *result);
+int	fdallocn(struct thread *td, int minfd, int *fds, int n);
 int	fdavail(struct thread *td, int n);
 int	fdcheckstd(struct thread *td);
 void	fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306270227.r5R2RDTc056963>