From owner-svn-src-all@FreeBSD.ORG Sun Nov 2 13:43:05 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0D1EC7B6; Sun, 2 Nov 2014 13:43:05 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E25E37F7; Sun, 2 Nov 2014 13:43:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sA2Dh4nL019421; Sun, 2 Nov 2014 13:43:04 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sA2Dh4hb019420; Sun, 2 Nov 2014 13:43:04 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <201411021343.sA2Dh4hb019420@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Sun, 2 Nov 2014 13:43:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273968 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 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: Sun, 02 Nov 2014 13:43:05 -0000 Author: mjg Date: Sun Nov 2 13:43:04 2014 New Revision: 273968 URL: https://svnweb.freebsd.org/changeset/base/273968 Log: filedesc: factor out some code out of fdescfree Previously it had a huge self-contained chunk dedicated to dealing with shared tables. No functional changes. Modified: head/sys/kern/kern_descrip.c Modified: head/sys/kern/kern_descrip.c ============================================================================== --- head/sys/kern/kern_descrip.c Sun Nov 2 13:14:55 2014 (r273967) +++ head/sys/kern/kern_descrip.c Sun Nov 2 13:43:04 2014 (r273968) @@ -1946,18 +1946,97 @@ fdcopy(struct filedesc *fdp) } /* + * Clear POSIX style locks. This is only used when fdp looses a reference (i.e. + * one of processes using it exits) and the table used to be shared. + */ +static void +fdclearlocks(struct thread *td) +{ + struct filedesc *fdp; + struct filedesc_to_leader *fdtol; + struct flock lf; + struct file *fp; + struct proc *p; + struct vnode *vp; + int i; + + p = td->td_proc; + fdp = p->p_fd; + fdtol = p->p_fdtol; + MPASS(fdtol != NULL); + + FILEDESC_XLOCK(fdp); + KASSERT(fdtol->fdl_refcount > 0, + ("filedesc_to_refcount botch: fdl_refcount=%d", + fdtol->fdl_refcount)); + if (fdtol->fdl_refcount == 1 && + (p->p_leader->p_flag & P_ADVLOCK) != 0) { + for (i = 0; i <= fdp->fd_lastfile; i++) { + fp = fdp->fd_ofiles[i].fde_file; + if (fp == NULL || fp->f_type != DTYPE_VNODE) + continue; + fhold(fp); + FILEDESC_XUNLOCK(fdp); + lf.l_whence = SEEK_SET; + lf.l_start = 0; + lf.l_len = 0; + lf.l_type = F_UNLCK; + vp = fp->f_vnode; + (void) VOP_ADVLOCK(vp, + (caddr_t)p->p_leader, F_UNLCK, + &lf, F_POSIX); + FILEDESC_XLOCK(fdp); + fdrop(fp, td); + } + } +retry: + if (fdtol->fdl_refcount == 1) { + if (fdp->fd_holdleaderscount > 0 && + (p->p_leader->p_flag & P_ADVLOCK) != 0) { + /* + * close() or do_dup() has cleared a reference + * in a shared file descriptor table. + */ + fdp->fd_holdleaderswakeup = 1; + sx_sleep(&fdp->fd_holdleaderscount, + FILEDESC_LOCK(fdp), PLOCK, "fdlhold", 0); + goto retry; + } + if (fdtol->fdl_holdcount > 0) { + /* + * Ensure that fdtol->fdl_leader remains + * valid in closef(). + */ + fdtol->fdl_wakeup = 1; + sx_sleep(fdtol, FILEDESC_LOCK(fdp), PLOCK, + "fdlhold", 0); + goto retry; + } + } + fdtol->fdl_refcount--; + if (fdtol->fdl_refcount == 0 && + fdtol->fdl_holdcount == 0) { + fdtol->fdl_next->fdl_prev = fdtol->fdl_prev; + fdtol->fdl_prev->fdl_next = fdtol->fdl_next; + } else + fdtol = NULL; + p->p_fdtol = NULL; + FILEDESC_XUNLOCK(fdp); + if (fdtol != NULL) + free(fdtol, M_FILEDESC_TO_LEADER); +} + +/* * Release a filedesc structure. */ void fdescfree(struct thread *td) { struct filedesc *fdp; - int i; - struct filedesc_to_leader *fdtol; struct filedescent *fde; struct file *fp; - struct vnode *cdir, *jdir, *rdir, *vp; - struct flock lf; + struct vnode *cdir, *jdir, *rdir; + int i; /* Certain daemons might not have file descriptors. */ fdp = td->td_proc->p_fd; @@ -1970,69 +2049,8 @@ fdescfree(struct thread *td) PROC_UNLOCK(td->td_proc); #endif - /* Check for special need to clear POSIX style locks */ - fdtol = td->td_proc->p_fdtol; - if (fdtol != NULL) { - FILEDESC_XLOCK(fdp); - KASSERT(fdtol->fdl_refcount > 0, - ("filedesc_to_refcount botch: fdl_refcount=%d", - fdtol->fdl_refcount)); - if (fdtol->fdl_refcount == 1 && - (td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) { - for (i = 0; i <= fdp->fd_lastfile; i++) { - fp = fdp->fd_ofiles[i].fde_file; - if (fp == NULL || fp->f_type != DTYPE_VNODE) - continue; - fhold(fp); - FILEDESC_XUNLOCK(fdp); - lf.l_whence = SEEK_SET; - lf.l_start = 0; - lf.l_len = 0; - lf.l_type = F_UNLCK; - vp = fp->f_vnode; - (void) VOP_ADVLOCK(vp, - (caddr_t)td->td_proc->p_leader, F_UNLCK, - &lf, F_POSIX); - FILEDESC_XLOCK(fdp); - fdrop(fp, td); - } - } - retry: - if (fdtol->fdl_refcount == 1) { - if (fdp->fd_holdleaderscount > 0 && - (td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) { - /* - * close() or do_dup() has cleared a reference - * in a shared file descriptor table. - */ - fdp->fd_holdleaderswakeup = 1; - sx_sleep(&fdp->fd_holdleaderscount, - FILEDESC_LOCK(fdp), PLOCK, "fdlhold", 0); - goto retry; - } - if (fdtol->fdl_holdcount > 0) { - /* - * Ensure that fdtol->fdl_leader remains - * valid in closef(). - */ - fdtol->fdl_wakeup = 1; - sx_sleep(fdtol, FILEDESC_LOCK(fdp), PLOCK, - "fdlhold", 0); - goto retry; - } - } - fdtol->fdl_refcount--; - if (fdtol->fdl_refcount == 0 && - fdtol->fdl_holdcount == 0) { - fdtol->fdl_next->fdl_prev = fdtol->fdl_prev; - fdtol->fdl_prev->fdl_next = fdtol->fdl_next; - } else - fdtol = NULL; - td->td_proc->p_fdtol = NULL; - FILEDESC_XUNLOCK(fdp); - if (fdtol != NULL) - free(fdtol, M_FILEDESC_TO_LEADER); - } + if (td->td_proc->p_fdtol != NULL) + fdclearlocks(td); mtx_lock(&fdesc_mtx); td->td_proc->p_fd = NULL;