Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jun 2012 20:00:44 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r236914 - head/sys/kern
Message-ID:  <201206112000.q5BK0iqi006948@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Mon Jun 11 20:00:44 2012
New Revision: 236914
URL: http://svn.freebsd.org/changeset/base/236914

Log:
  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

Modified:
  head/sys/kern/kern_descrip.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Mon Jun 11 19:57:31 2012	(r236913)
+++ head/sys/kern/kern_descrip.c	Mon Jun 11 20:00:44 2012	(r236914)
@@ -801,7 +801,7 @@ do_dup(struct thread *td, int flags, int
 	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
 	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
 		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));
 }
 
 /*



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