diff -ru sys_clean/kern/kern_descrip.c sys/kern/kern_descrip.c
--- sys_clean/kern/kern_descrip.c	Fri Jul 21 23:24:00 2006
+++ sys/kern/kern_descrip.c	Sat Sep 30 21:16:16 2006
@@ -382,10 +382,25 @@
 	flg = F_POSIX;
 	p = td->td_proc;
 	fdp = p->p_fd;
-	FILEDESC_LOCK(fdp);
+	
+	/* some calles require exclusive lock some need only shared */
+        switch (cmd) {
+	case F_DUPFD:
+	case F_GETFD:
+	case F_GETFL:
+	case F_SETFL:
+	case F_GETOWN:
+	case F_SETOWN:
+		FILEDESC_SLOCK(fdp);
+		break;
+	default:
+		FILEDESC_LOCK(fdp);
+		break;
+	}
+
 	if ((unsigned)fd >= fdp->fd_nfiles ||
 	    (fp = fdp->fd_ofiles[fd]) == NULL) {
-		FILEDESC_UNLOCK(fdp);
+		sx_unlock(&fdp->fd_sx); /* FIXME: use macro */
 		error = EBADF;
 		goto done2;
 	}
@@ -394,7 +409,7 @@
 	switch (cmd) {
 	case F_DUPFD:
 		/* mtx_assert(&Giant, MA_NOTOWNED); */
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		newmin = arg;
 		PROC_LOCK(p);
 		if (newmin >= lim_cur(p, RLIMIT_NOFILE) ||
@@ -410,7 +425,7 @@
 	case F_GETFD:
 		/* mtx_assert(&Giant, MA_NOTOWNED); */
 		td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0;
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		break;
 
 	case F_SETFD:
@@ -425,7 +440,7 @@
 		FILE_LOCK(fp);
 		td->td_retval[0] = OFLAGS(fp->f_flag);
 		FILE_UNLOCK(fp);
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		break;
 
 	case F_SETFL:
@@ -435,7 +450,7 @@
 		fp->f_flag &= ~FCNTLFLAGS;
 		fp->f_flag |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS;
 		FILE_UNLOCK(fp);
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		tmp = fp->f_flag & FNONBLOCK;
 		error = fo_ioctl(fp, FIONBIO, &tmp, td->td_ucred, td);
 		if (error) {
@@ -459,7 +474,7 @@
 	case F_GETOWN:
 		mtx_assert(&Giant, MA_OWNED);
 		fhold(fp);
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		error = fo_ioctl(fp, FIOGETOWN, &tmp, td->td_ucred, td);
 		if (error == 0)
 			td->td_retval[0] = tmp;
@@ -469,7 +484,7 @@
 	case F_SETOWN:
 		mtx_assert(&Giant, MA_OWNED);
 		fhold(fp);
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		tmp = arg;
 		error = fo_ioctl(fp, FIOSETOWN, &tmp, td->td_ucred, td);
 		fdrop(fp, td);
@@ -1409,7 +1424,7 @@
 	struct filedesc0 *newfdp;
 
 	newfdp = malloc(sizeof *newfdp, M_FILEDESC, M_WAITOK | M_ZERO);
-	mtx_init(&newfdp->fd_fd.fd_mtx, FILEDESC_LOCK_DESC, NULL, MTX_DEF);
+	sx_init(&newfdp->fd_fd.fd_sx, FILEDESC_LOCK_DESC);
 	if (fdp != NULL) {
 		FILEDESC_LOCK(fdp);
 		newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
@@ -1460,7 +1475,7 @@
 	if (i > 0)
 		return;
 
-	mtx_destroy(&fdp->fd_mtx);
+	sx_destroy(&fdp->fd_sx);
 	FREE(fdp, M_FILEDESC);
 }
 
@@ -1611,8 +1626,12 @@
 				 * in a shared file descriptor table.
 				 */
 				fdp->fd_holdleaderswakeup = 1;
-				msleep(&fdp->fd_holdleaderscount, &fdp->fd_mtx,
+                                FILEDESC_UNLOCK(fdp);
+				tsleep(&fdp->fd_sx, PLOCK, "fdhold", 0);
+				FILEDESC_LOCK(fdp);
+				/* msleep(&fdp->fd_holdleaderscount, &fdp->fd_mtx,
 				       PLOCK, "fdlhold", 0);
+				*/
 				goto retry;
 			}
 			if (fdtol->fdl_holdcount > 0) {
@@ -1621,8 +1640,12 @@
 				 * remains valid in closef().
 				 */
 				fdtol->fdl_wakeup = 1;
-				msleep(fdtol, &fdp->fd_mtx,
+				FILEDESC_UNLOCK(fdp);
+				tsleep(&fdp->fd_sx, PLOCK, "fdlhold", 0);
+				FILEDESC_LOCK(fdp);
+				/* msleep(fdtol, &fdp->fd_mtx,
 				       PLOCK, "fdlhold", 0);
+				*/
 				goto retry;
 			}
 		}
@@ -2005,9 +2028,9 @@
 	*fpp = NULL;
 	if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
 		return (EBADF);
-	FILEDESC_LOCK(fdp);
+	FILEDESC_SLOCK(fdp);
 	if ((fp = fget_locked(fdp, fd)) == NULL || fp->f_ops == &badfileops) {
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		return (EBADF);
 	}
 
@@ -2017,16 +2040,16 @@
 	 * Only one flag, or 0, may be specified.
 	 */
 	if (flags == FREAD && (fp->f_flag & FREAD) == 0) {
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		return (EBADF);
 	}
 	if (flags == FWRITE && (fp->f_flag & FWRITE) == 0) {
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		return (EBADF);
 	}
 	if (hold) {
 		fhold(fp);
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 	}
 	*fpp = fp;
 	return (0);
@@ -2075,7 +2098,7 @@
 		*vpp = fp->f_vnode;
 		vref(*vpp);
 	}
-	FILEDESC_UNLOCK(td->td_proc->p_fd);
+	FILEDESC_SUNLOCK(td->td_proc->p_fd);
 	return (error);
 }
 
@@ -2136,7 +2159,7 @@
 		soref(*spp);
 		SOCK_UNLOCK(*spp);
 	}
-	FILEDESC_UNLOCK(td->td_proc->p_fd);
+	FILEDESC_SUNLOCK(td->td_proc->p_fd);
 	return (error);
 }
 
Only in sys_clean/sys: .filedesc.h.swp
diff -ru sys_clean/sys/filedesc.h sys/sys/filedesc.h
--- sys_clean/sys/filedesc.h	Fri Apr  7 08:16:02 2006
+++ sys/sys/filedesc.h	Sat Sep 30 03:28:21 2006
@@ -37,7 +37,8 @@
 #include <sys/event.h>
 #include <sys/priority.h>
 #include <sys/_lock.h>
-#include <sys/_mutex.h>
+#include <sys/_mutex.h> 
+#include <sys/sx.h>
 
 #include <machine/_limits.h>
 
@@ -61,9 +62,7 @@
 	u_short	fd_refcnt;		/* thread reference count */
 	u_short	fd_holdcnt;		/* hold count on structure + mutex */
 
-	struct	mtx fd_mtx;		/* protects members of this struct */
-	int	fd_locked;		/* long lock flag */
-	int	fd_wanted;		/* "" */
+	struct	sx fd_sx;		/* protects members of this struct */
 	struct	kqlist fd_kqlist;	/* list of kqueues on this filedesc */
 	int	fd_holdleaderscount;	/* block fdfree() for shared close() */
 	int	fd_holdleaderswakeup;	/* fdfree() needs wakeup */
@@ -76,7 +75,7 @@
  * table to be shared by processes having different "p_leader" pointers
  * and thus distinct POSIX style locks.
  *
- * fdl_refcount and fdl_holdcount are protected by struct filedesc mtx.
+ * fdl_refcount and fdl_holdcount are protected by struct filedesc sx.
  */
 struct filedesc_to_leader {
 	int		fdl_refcount;	/* references from struct proc */
@@ -95,60 +94,22 @@
 
 #ifdef _KERNEL
 
-/* Lock a file descriptor table. */
-#define	FILEDESC_LOCK(fd)								\
-	do {										\
-		mtx_lock(&(fd)->fd_mtx);						\
-		(fd)->fd_wanted++;							\
-		while ((fd)->fd_locked)							\
-			msleep(&(fd)->fd_locked, &(fd)->fd_mtx, PLOCK, "fdesc", 0);	\
-		(fd)->fd_locked = 2;							\
-		(fd)->fd_wanted--;							\
-		mtx_unlock(&(fd)->fd_mtx);						\
-	} while (0)
-
-#define	FILEDESC_UNLOCK(fd)								\
-	do {										\
-		mtx_lock(&(fd)->fd_mtx);						\
-		KASSERT((fd)->fd_locked == 2,						\
-		    ("fdesc locking mistake %d should be %d", (fd)->fd_locked, 2));	\
-		(fd)->fd_locked = 0;							\
-		if ((fd)->fd_wanted)							\
-			wakeup(&(fd)->fd_locked);					\
-		mtx_unlock(&(fd)->fd_mtx);						\
-	} while (0)
-
-#define	FILEDESC_LOCK_FAST(fd)								\
-	do {										\
-		mtx_lock(&(fd)->fd_mtx);						\
-		(fd)->fd_wanted++;							\
-		while ((fd)->fd_locked)							\
-			msleep(&(fd)->fd_locked, &(fd)->fd_mtx, PLOCK, "fdesc", 0);	\
-		(fd)->fd_locked = 1;							\
-		(fd)->fd_wanted--;							\
-	} while (0)
-
-#define	FILEDESC_UNLOCK_FAST(fd)							\
-	do {										\
-		KASSERT((fd)->fd_locked == 1,						\
-		    ("fdesc locking mistake %d should be %d", (fd)->fd_locked, 1));	\
-		(fd)->fd_locked = 0;							\
-		if ((fd)->fd_wanted)							\
-			wakeup(&(fd)->fd_locked);					\
-		mtx_unlock(&(fd)->fd_mtx);						\
-	} while (0)
-
-#ifdef INVARIANT_SUPPORT
-#define	FILEDESC_LOCK_ASSERT(fd, arg)							\
-	do {										\
-		if ((arg) == MA_OWNED)							\
-			KASSERT((fd)->fd_locked != 0, ("fdesc locking mistake"));	\
-		else									\
-			KASSERT((fd)->fd_locked == 0, ("fdesc locking mistake"));	\
-	} while (0)
-#else
+#define FILEDESC_LOCK(fd) \
+    sx_xlock(&(fd)->fd_sx)
+
+#define FILEDESC_SLOCK(fd) \
+    sx_slock(&(fd)->fd_sx)
+
+#define FILEDESC_UNLOCK(fd) \
+    sx_xunlock(&(fd)->fd_sx)
+
+#define FILEDESC_SUNLOCK(fd) \
+    sx_sunlock(&(fd)->fd_sx)
+
+#define FILEDESC_LOCK_FAST FILEDESC_LOCK
+#define FILEDESC_UNLOCK_FAST FILEDESC_UNLOCK
+
 #define	FILEDESC_LOCK_ASSERT(fd, arg)
-#endif
 
 #define	FILEDESC_LOCK_DESC	"filedesc structure"
 
