svn commit: r249480 - in head/sys: kern sys
Mateusz Guzik
mjg at FreeBSD.org
Sun Apr 14 17:08:35 UTC 2013
Author: mjg
Date: Sun Apr 14 17:08:34 2013
New Revision: 249480
URL: http://svnweb.freebsd.org/changeset/base/249480
Log:
Add fdallocn function and use it when passing fds over unix socket.
This gets rid of "unp_externalize fdalloc failed" panic.
Reviewed by: pjd
MFC after: 1 week
Modified:
head/sys/kern/kern_descrip.c
head/sys/kern/uipc_usrreq.c
head/sys/sys/filedesc.h
Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c Sun Apr 14 16:49:27 2013 (r249479)
+++ head/sys/kern/kern_descrip.c Sun Apr 14 17:08:34 2013 (r249480)
@@ -1582,6 +1582,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: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c Sun Apr 14 16:49:27 2013 (r249479)
+++ head/sys/kern/uipc_usrreq.c Sun Apr 14 17:08:34 2013 (r249480)
@@ -1706,7 +1706,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();
@@ -1732,13 +1731,6 @@ unp_externalize(struct mbuf *control, st
goto next;
}
FILEDESC_XLOCK(fdesc);
- /* if the new FD's will not fit free them. */
- if (!fdavail(td, newfds)) {
- FILEDESC_XUNLOCK(fdesc);
- error = EMSGSIZE;
- unp_freerights(fdep, newfds);
- goto next;
- }
/*
* Now change each pointer to an fd in the global
@@ -1758,17 +1750,22 @@ 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(fdep, newfds);
+ m_freem(*controlp);
+ *controlp = NULL;
+ goto next;
+ }
for (i = 0; i < newfds; i++, fdp++) {
- if (fdalloc(td, 0, &f))
- panic("unp_externalize fdalloc failed");
- fde = &fdesc->fd_ofiles[f];
+ fde = &fdesc->fd_ofiles[*fdp];
fde->fde_file = fdep[0]->fde_file;
filecaps_move(&fdep[0]->fde_caps,
&fde->fde_caps);
if ((flags & MSG_CMSG_CLOEXEC) != 0)
fde->fde_flags |= UF_EXCLOSE;
unp_externalize_fp(fde->fde_file);
- *fdp = f;
}
FILEDESC_XUNLOCK(fdesc);
free(fdep[0], M_FILECAPS);
Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h Sun Apr 14 16:49:27 2013 (r249479)
+++ head/sys/sys/filedesc.h Sun Apr 14 17:08:34 2013 (r249480)
@@ -150,6 +150,7 @@ int falloc_noinstall(struct thread *td,
int finstall(struct thread *td, struct file *fp, int *resultfp, int flags,
struct filecaps *fcaps);
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);
More information about the svn-src-all
mailing list