svn commit: r223694 - in head/sys: kern sys
Jonathan Anderson
jonathan at FreeBSD.org
Thu Jun 30 15:22:49 UTC 2011
Author: jonathan
Date: Thu Jun 30 15:22:49 2011
New Revision: 223694
URL: http://svn.freebsd.org/changeset/base/223694
Log:
When Capsicum starts creating capabilities to wrap existing file
descriptors, we will want to allocate a new descriptor without installing
it in the FD array.
Split falloc() into falloc_noinstall() and finstall(), and rewrite
falloc() to call them with appropriate atomicity.
Approved by: mentor (rwatson), re (bz)
Modified:
head/sys/kern/kern_descrip.c
head/sys/sys/filedesc.h
Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c Thu Jun 30 14:10:49 2011 (r223693)
+++ head/sys/kern/kern_descrip.c Thu Jun 30 15:22:49 2011 (r223694)
@@ -1561,54 +1561,85 @@ fdavail(struct thread *td, int n)
int
falloc(struct thread *td, struct file **resultfp, int *resultfd, int flags)
{
- struct proc *p = td->td_proc;
struct file *fp;
- int error, i;
+ int error, fd;
+
+ error = falloc_noinstall(td, &fp);
+ if (error)
+ return (error); /* no reference held on error */
+
+ error = finstall(td, fp, &fd, flags);
+ if (error) {
+ fdrop(fp, td); /* one reference (fp only) */
+ return (error);
+ }
+
+ if (resultfp != NULL)
+ *resultfp = fp; /* copy out result */
+ else
+ fdrop(fp, td); /* release local reference */
+
+ if (resultfd != NULL)
+ *resultfd = fd;
+
+ return (0);
+}
+
+/*
+ * Create a new open file structure without allocating a file descriptor.
+ */
+int
+falloc_noinstall(struct thread *td, struct file **resultfp)
+{
+ struct file *fp;
int maxuserfiles = maxfiles - (maxfiles / 20);
static struct timeval lastfail;
static int curfail;
- fp = uma_zalloc(file_zone, M_WAITOK | M_ZERO);
+ KASSERT(resultfp != NULL, ("%s: resultfp == NULL", __func__));
+
if ((openfiles >= maxuserfiles &&
priv_check(td, PRIV_MAXFILES) != 0) ||
openfiles >= maxfiles) {
if (ppsratecheck(&lastfail, &curfail, 1)) {
- printf("kern.maxfiles limit exceeded by uid %i, please see tuning(7).\n",
- td->td_ucred->cr_ruid);
+ printf("kern.maxfiles limit exceeded by uid %i, "
+ "please see tuning(7).\n", td->td_ucred->cr_ruid);
}
- uma_zfree(file_zone, fp);
return (ENFILE);
}
atomic_add_int(&openfiles, 1);
-
- /*
- * If the process has file descriptor zero open, add the new file
- * descriptor to the list of open files at that point, otherwise
- * put it at the front of the list of open files.
- */
+ fp = uma_zalloc(file_zone, M_WAITOK | M_ZERO);
refcount_init(&fp->f_count, 1);
- if (resultfp)
- fhold(fp);
fp->f_cred = crhold(td->td_ucred);
fp->f_ops = &badfileops;
fp->f_data = NULL;
fp->f_vnode = NULL;
- FILEDESC_XLOCK(p->p_fd);
- if ((error = fdalloc(td, 0, &i))) {
- FILEDESC_XUNLOCK(p->p_fd);
- fdrop(fp, td);
- if (resultfp)
- fdrop(fp, td);
+ *resultfp = fp;
+ return (0);
+}
+
+/*
+ * Install a file in a file descriptor table.
+ */
+int
+finstall(struct thread *td, struct file *fp, int *fd, int flags)
+{
+ struct filedesc *fdp = td->td_proc->p_fd;
+ int error;
+
+ KASSERT(fd != NULL, ("%s: fd == NULL", __func__));
+ KASSERT(fp != NULL, ("%s: fp == NULL", __func__));
+
+ FILEDESC_XLOCK(fdp);
+ if ((error = fdalloc(td, 0, fd))) {
+ FILEDESC_XUNLOCK(fdp);
return (error);
}
- p->p_fd->fd_ofiles[i] = fp;
+ fhold(fp);
+ fdp->fd_ofiles[*fd] = fp;
if ((flags & O_CLOEXEC) != 0)
- p->p_fd->fd_ofileflags[i] |= UF_EXCLOSE;
- FILEDESC_XUNLOCK(p->p_fd);
- if (resultfp)
- *resultfp = fp;
- if (resultfd)
- *resultfd = i;
+ fdp->fd_ofileflags[*fd] |= UF_EXCLOSE;
+ FILEDESC_XUNLOCK(fdp);
return (0);
}
Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h Thu Jun 30 14:10:49 2011 (r223693)
+++ head/sys/sys/filedesc.h Thu Jun 30 15:22:49 2011 (r223694)
@@ -113,6 +113,8 @@ int dupfdopen(struct thread *td, struct
int mode, int error);
int falloc(struct thread *td, struct file **resultfp, int *resultfd,
int flags);
+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 fdavail(struct thread *td, int n);
int fdcheckstd(struct thread *td);
More information about the svn-src-head
mailing list