summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2012-06-11 20:00:44 +0000
committerpjd <pjd@FreeBSD.org>2012-06-11 20:00:44 +0000
commitd698b8f8521a6e0f34b5a9c499cf45941387d178 (patch)
tree65dc3862e2eab76487b4df4719330f4be00d6487 /sys/kern/kern_descrip.c
parentc8465e01a12c87cc250fef1a3c3e50a9c5f8b8d5 (diff)
downloadFreeBSD-src-d698b8f8521a6e0f34b5a9c499cf45941387d178.zip
FreeBSD-src-d698b8f8521a6e0f34b5a9c499cf45941387d178.tar.gz
Remove code duplicated in kern_close() and do_dup() and use closefp() function
introduced a minute ago. This code duplication was responsible for the bug fixed in r236853. Discussed with: kib Tested by: pho MFC after: 1 month
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c96
1 files changed, 7 insertions, 89 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 2e34e09..8f27e12 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -801,7 +801,7 @@ do_dup(struct thread *td, int flags, int old, int new,
struct proc *p;
struct file *fp;
struct file *delfp;
- int error, holdleaders, maxfd;
+ int error, maxfd;
p = td->td_proc;
fdp = p->p_fd;
@@ -877,7 +877,6 @@ do_dup(struct thread *td, int flags, int old, int new,
KASSERT(old != new, ("new fd is same as old"));
delfp = fdp->fd_ofiles[new];
-
/*
* Duplicate the source descriptor.
*/
@@ -887,55 +886,13 @@ do_dup(struct thread *td, int flags, int old, int new,
fdp->fd_lastfile = new;
*retval = new;
- /*
- * Save info on the descriptor being overwritten. We cannot close
- * it without introducing an ownership race for the slot, since we
- * need to drop the filedesc lock to call closef().
- *
- * XXX this duplicates parts of close().
- */
if (delfp != NULL) {
- if (td->td_proc->p_fdtol != NULL) {
- /*
- * Ask fdfree() to sleep to ensure that all relevant
- * process leaders can be traversed in closef().
- */
- fdp->fd_holdleaderscount++;
- holdleaders = 1;
- } else {
- holdleaders = 0;
- }
-
- /*
- * If we dup'd over a valid file, we now own the reference to it
- * and must dispose of it using closef() semantics (as if a
- * close() were performed on it).
- *
- * XXX this duplicates parts of close().
- */
- knote_fdclose(td, new);
- /*
- * When we're closing an fd with a capability, we need to
- * notify mqueue if the underlying object is of type mqueue.
- */
- (void)cap_funwrap(delfp, 0, &fp);
- if (fp->f_type == DTYPE_MQUEUE)
- mq_fdclose(td, new, fp);
- FILEDESC_XUNLOCK(fdp);
- (void) closef(delfp, td);
- if (holdleaders) {
- FILEDESC_XLOCK(fdp);
- fdp->fd_holdleaderscount--;
- if (fdp->fd_holdleaderscount == 0 &&
- fdp->fd_holdleaderswakeup != 0) {
- fdp->fd_holdleaderswakeup = 0;
- wakeup(&fdp->fd_holdleaderscount);
- }
- FILEDESC_XUNLOCK(fdp);
- }
+ (void) closefp(fdp, new, delfp, td);
+ /* closefp() drops the FILEDESC lock for us. */
} else {
FILEDESC_XUNLOCK(fdp);
}
+
return (0);
}
@@ -1235,12 +1192,8 @@ kern_close(td, fd)
int fd;
{
struct filedesc *fdp;
- struct file *fp, *fp_object;
- int error;
- int holdleaders;
+ struct file *fp;
- error = 0;
- holdleaders = 0;
fdp = td->td_proc->p_fd;
AUDIT_SYSCLOSE(td, fd);
@@ -1254,44 +1207,9 @@ kern_close(td, fd)
fdp->fd_ofiles[fd] = NULL;
fdp->fd_ofileflags[fd] = 0;
fdunused(fdp, fd);
- if (td->td_proc->p_fdtol != NULL) {
- /*
- * Ask fdfree() to sleep to ensure that all relevant
- * process leaders can be traversed in closef().
- */
- fdp->fd_holdleaderscount++;
- holdleaders = 1;
- }
-
- /*
- * We now hold the fp reference that used to be owned by the
- * descriptor array. We have to unlock the FILEDESC *AFTER*
- * knote_fdclose to prevent a race of the fd getting opened, a knote
- * added, and deleteing a knote for the new fd.
- */
- knote_fdclose(td, fd);
-
- /*
- * When we're closing an fd with a capability, we need to notify
- * mqueue if the underlying object is of type mqueue.
- */
- (void)cap_funwrap(fp, 0, &fp_object);
- if (fp_object->f_type == DTYPE_MQUEUE)
- mq_fdclose(td, fd, fp_object);
- FILEDESC_XUNLOCK(fdp);
- error = closef(fp, td);
- if (holdleaders) {
- FILEDESC_XLOCK(fdp);
- fdp->fd_holdleaderscount--;
- if (fdp->fd_holdleaderscount == 0 &&
- fdp->fd_holdleaderswakeup != 0) {
- fdp->fd_holdleaderswakeup = 0;
- wakeup(&fdp->fd_holdleaderscount);
- }
- FILEDESC_XUNLOCK(fdp);
- }
- return (error);
+ /* closefp() drops the FILEDESC lock for us. */
+ return (closefp(fdp, fd, fp, td));
}
/*
OpenPOWER on IntegriCloud