From owner-svn-src-all@FreeBSD.ORG Mon Jun 11 19:57:32 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9705A1065672; Mon, 11 Jun 2012 19:57:32 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 693968FC1E; Mon, 11 Jun 2012 19:57:32 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5BJvWmW006772; Mon, 11 Jun 2012 19:57:32 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5BJvWP3006770; Mon, 11 Jun 2012 19:57:32 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201206111957.q5BJvWP3006770@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Mon, 11 Jun 2012 19:57:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r236913 - head/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jun 2012 19:57:32 -0000 Author: pjd Date: Mon Jun 11 19:57:31 2012 New Revision: 236913 URL: http://svn.freebsd.org/changeset/base/236913 Log: Introduce closefp() function that we will be able to use to eliminate code duplication in kern_close() and do_dup(). This is committed separately from the actual removal of the duplicated code, as the combined diff was very hard to read. 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:53:41 2012 (r236912) +++ head/sys/kern/kern_descrip.c Mon Jun 11 19:57:31 2012 (r236913) @@ -114,6 +114,8 @@ static uma_zone_t file_zone; #define DUP_FIXED 0x1 /* Force fixed allocation */ #define DUP_FCNTL 0x2 /* fcntl()-style errors */ +static int closefp(struct filedesc *fdp, int fd, struct file *fp, + struct thread *td); static int do_dup(struct thread *td, int flags, int old, int new, register_t *retval); static int fd_first_free(struct filedesc *, int, int); @@ -1157,6 +1159,59 @@ fgetown(sigiop) } /* + * Function drops the filedesc lock on return. + */ +static int +closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td) +{ + struct file *fp_object; + int error, holdleaders; + + FILEDESC_XLOCK_ASSERT(fdp); + + 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; + } + + /* + * 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); +} + +/* * Close a file descriptor. */ #ifndef _SYS_SYSPROTO_H_