Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Nov 2014 13:43:04 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r273968 - head/sys/kern
Message-ID:  <201411021343.sA2Dh4hb019420@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



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