Introduce an alias for FILEDESC_{UN}LOCK() with the suffix _FAST.

Use this in all the places where sleeping with the lock held is not
an issue.

The distinction will become significant once we finalize the exact
lock-type to use for this kind of case.
This commit is contained in:
Poul-Henning Kamp 2004-11-13 11:53:02 +00:00
parent 5512dc5460
commit 124e4c3be8
16 changed files with 90 additions and 87 deletions

View File

@ -211,15 +211,15 @@ svr4_fil_ioctl(fp, td, retval, fd, cmd, data)
switch (cmd) {
case SVR4_FIOCLEX:
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
return 0;
case SVR4_FIONCLEX:
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
return 0;
case SVR4_FIOGETOWN:

View File

@ -618,10 +618,10 @@ svr4_sys_fchroot(td, uap)
return error;
}
VREF(vp);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
vpold = fdp->fd_rdir;
fdp->fd_rdir = vp;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
if (vpold != NULL)
vrele(vpold);
fdrop(fp, td);

View File

@ -256,26 +256,26 @@ streamsopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
if ((error = socreate(family, &so, type, protocol,
td->td_ucred, td)) != 0) {
FILEDESC_LOCK(p->p_fd);
FILEDESC_LOCK_FAST(p->p_fd);
/* Check the fd table entry hasn't changed since we made it. */
extraref = 0;
if (p->p_fd->fd_ofiles[fd] == fp) {
p->p_fd->fd_ofiles[fd] = NULL;
extraref = 1;
}
FILEDESC_UNLOCK(p->p_fd);
FILEDESC_UNLOCK_FAST(p->p_fd);
if (extraref)
fdrop(fp, td);
fdrop(fp, td);
return error;
}
FILEDESC_LOCK(p->p_fd);
FILEDESC_LOCK_FAST(p->p_fd);
fp->f_data = so;
fp->f_flag = FREAD|FWRITE;
fp->f_ops = &svr4_netops;
fp->f_type = DTYPE_SOCKET;
FILEDESC_UNLOCK(p->p_fd);
FILEDESC_UNLOCK_FAST(p->p_fd);
(void)svr4_stream_get(fp);
fdrop(fp, td);

View File

@ -166,7 +166,7 @@ fdesc_statfs(mp, sbp, td)
lim = lim_cur(td->td_proc, RLIMIT_NOFILE);
PROC_UNLOCK(td->td_proc);
fdp = td->td_proc->p_fd;
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
last = min(fdp->fd_nfiles, lim);
freefd = 0;
for (i = fdp->fd_freefile; i < last; i++)
@ -179,7 +179,7 @@ fdesc_statfs(mp, sbp, td)
*/
if (fdp->fd_nfiles < lim)
freefd += (lim - fdp->fd_nfiles);
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
sbp->f_flags = 0;
sbp->f_bsize = DEV_BSIZE;

View File

@ -440,7 +440,7 @@ fdesc_readdir(ap)
fcnt = i - 2; /* The first two nodes are `.' and `..' */
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
while (i < fdp->fd_nfiles + 2 && uio->uio_resid >= UIO_MX) {
switch (i) {
case 0: /* `.' */
@ -456,7 +456,7 @@ fdesc_readdir(ap)
break;
default:
if (fdp->fd_ofiles[fcnt] == NULL) {
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
goto done;
}
@ -470,15 +470,15 @@ fdesc_readdir(ap)
/*
* And ship to userland
*/
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
error = uiomove(dp, UIO_MX, uio);
if (error)
goto done;
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
i++;
fcnt++;
}
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
done:
uio->uio_offset = i * UIO_MX;

View File

@ -1053,9 +1053,9 @@ union_vn_create(vpp, un, td)
struct componentname cn;
*vpp = NULLVP;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
cmode = UN_FILEMODE & ~td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
/*
* Build a new componentname structure (for the same

View File

@ -247,9 +247,9 @@ union_mount(mp, td)
}
um->um_cred = crhold(td->td_ucred);
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
um->um_cmode = UN_DIRMODE &~ td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
/*
* Depending on what you think the MNT_LOCAL flag might mean,

View File

@ -549,10 +549,10 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
break;
}
/* Check for race with close */
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
if ((unsigned) fd >= fdp->fd_nfiles ||
fp != fdp->fd_ofiles[fd]) {
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
flp->l_whence = SEEK_SET;
flp->l_start = 0;
flp->l_len = 0;
@ -560,7 +560,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
(void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader,
F_UNLCK, flp, F_POSIX);
} else
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
fdrop(fp, td);
break;
@ -736,14 +736,14 @@ do_dup(td, type, old, new, retval)
(void) closef(delfp, td);
mtx_unlock(&Giant);
if (holdleaders) {
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_holdleaderscount--;
if (fdp->fd_holdleaderscount == 0 &&
fdp->fd_holdleaderswakeup != 0) {
fdp->fd_holdleaderswakeup = 0;
wakeup(&fdp->fd_holdleaderscount);
}
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
}
} else {
FILEDESC_UNLOCK(fdp);
@ -1033,14 +1033,14 @@ close(td, uap)
error = closef(fp, td);
mtx_unlock(&Giant);
if (holdleaders) {
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_holdleaderscount--;
if (fdp->fd_holdleaderscount == 0 &&
fdp->fd_holdleaderswakeup != 0) {
fdp->fd_holdleaderswakeup = 0;
wakeup(&fdp->fd_holdleaderscount);
}
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
}
return (error);
}
@ -1472,9 +1472,9 @@ struct filedesc *
fdshare(fdp)
struct filedesc *fdp;
{
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_refcnt++;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
return (fdp);
}
@ -1495,13 +1495,13 @@ fdcopy(fdp)
return (NULL);
newfdp = fdinit(fdp);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
while (fdp->fd_lastfile >= newfdp->fd_nfiles) {
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
FILEDESC_LOCK(newfdp);
fdgrowtable(newfdp, fdp->fd_lastfile + 1);
FILEDESC_UNLOCK(newfdp);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
}
/* copy everything except kqueue descriptors */
newfdp->fd_freefile = -1;
@ -1517,17 +1517,17 @@ fdcopy(fdp)
newfdp->fd_freefile = i;
}
}
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
FILEDESC_LOCK(newfdp);
for (i = 0; i <= newfdp->fd_lastfile; ++i)
if (newfdp->fd_ofiles[i] != NULL)
fdused(newfdp, i);
FILEDESC_UNLOCK(newfdp);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
if (newfdp->fd_freefile == -1)
newfdp->fd_freefile = i;
newfdp->fd_cmask = fdp->fd_cmask;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
return (newfdp);
}

View File

@ -497,9 +497,9 @@ kqueue(struct thread *td, struct kqueue_args *uap)
knlist_init(&kq->kq_sel.si_note, &kq->kq_lock);
TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
SLIST_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
FILE_LOCK(fp);
fp->f_flag = FREAD | FWRITE;
@ -1391,9 +1391,9 @@ kqueue_close(struct file *fp, struct thread *td)
KQ_UNLOCK(kq);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
SLIST_REMOVE(&fdp->fd_kqlist, kq, kqueue, kq_list);
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
knlist_destroy(&kq->kq_sel.si_note);
mtx_destroy(&kq->kq_lock);

View File

@ -465,16 +465,16 @@ do_execve(td, fname, argv, envv, mac_p)
* For security and other reasons, the file descriptor table cannot
* be shared after an exec.
*/
FILEDESC_LOCK(p->p_fd);
FILEDESC_LOCK_FAST(p->p_fd);
if (p->p_fd->fd_refcnt > 1) {
struct filedesc *tmp;
FILEDESC_UNLOCK(p->p_fd);
FILEDESC_UNLOCK_FAST(p->p_fd);
tmp = fdcopy(p->p_fd);
fdfree(td);
p->p_fd = tmp;
} else
FILEDESC_UNLOCK(p->p_fd);
FILEDESC_UNLOCK_FAST(p->p_fd);
/*
* Malloc things before we need locks.

View File

@ -234,16 +234,16 @@ fork1(td, flags, pages, procp)
* Unshare file descriptors (from parent).
*/
if (flags & RFFDG) {
FILEDESC_LOCK(p1->p_fd);
FILEDESC_LOCK_FAST(p1->p_fd);
if (p1->p_fd->fd_refcnt > 1) {
struct filedesc *newfd;
FILEDESC_UNLOCK(p1->p_fd);
FILEDESC_UNLOCK_FAST(p1->p_fd);
newfd = fdcopy(p1->p_fd);
fdfree(td);
p1->p_fd = newfd;
} else
FILEDESC_UNLOCK(p1->p_fd);
FILEDESC_UNLOCK_FAST(p1->p_fd);
}
*procp = NULL;
return (0);
@ -439,9 +439,9 @@ fork1(td, flags, pages, procp)
* shared process leaders.
*/
fdtol = p1->p_fdtol;
FILEDESC_LOCK(p1->p_fd);
FILEDESC_LOCK_FAST(p1->p_fd);
fdtol->fdl_refcount++;
FILEDESC_UNLOCK(p1->p_fd);
FILEDESC_UNLOCK_FAST(p1->p_fd);
} else {
/*
* Shared file descriptor table, and

View File

@ -490,16 +490,16 @@ ioctl(td, uap)
fdp = td->td_proc->p_fd;
switch (com = uap->com) {
case FIONCLEX:
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
fdrop(fp, td);
mtx_unlock(&Giant);
return (0);
case FIOCLEX:
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
fdrop(fp, td);
mtx_unlock(&Giant);
return (0);
@ -650,11 +650,11 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
* even if none of the file descriptors we poll requires Giant.
*/
mtx_lock(&Giant);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
if (nd > td->td_proc->p_fd->fd_nfiles)
nd = td->td_proc->p_fd->fd_nfiles; /* forgiving; slightly wrong */
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
/*
* Allocate just enough bits for the non-null fd_sets. Use the

View File

@ -117,9 +117,9 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp)
if (fdp == NULL)
error = EBADF;
else {
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fp = fget_locked(fdp, fd);
if(fp == NULL)
if (fp == NULL)
error = EBADF;
else if (fp->f_type != DTYPE_SOCKET) {
fp = NULL;
@ -128,7 +128,7 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp)
fhold(fp);
error = 0;
}
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
}
*fpp = fp;
return (error);
@ -170,12 +170,12 @@ socket(td, uap)
if (error) {
fdclose(fdp, fp, fd, td);
} else {
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
fp->f_data = so; /* already has ref count */
fp->f_flag = FREAD|FWRITE;
fp->f_ops = &socketops;
fp->f_type = DTYPE_SOCKET;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
td->td_retval[0] = fd;
}
fdrop(fp, td);

View File

@ -702,10 +702,10 @@ fchdir(td, uap)
return (error);
}
VOP_UNLOCK(vp, 0, td);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
vpold = fdp->fd_cdir;
fdp->fd_cdir = vp;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
vrele(vpold);
return (0);
}
@ -747,10 +747,10 @@ kern_chdir(struct thread *td, char *path, enum uio_seg pathseg)
}
VOP_UNLOCK(nd.ni_vp, 0, td);
NDFREE(&nd, NDF_ONLY_PNBUF);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
vp = fdp->fd_cdir;
fdp->fd_cdir = nd.ni_vp;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
vrele(vp);
return (0);
}
@ -1175,10 +1175,10 @@ kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
return (EEXIST);
} else {
VATTR_NULL(&vattr);
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = (mode & ALLPERMS) &
~td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
vattr.va_rdev = dev;
whiteout = 0;
@ -1283,9 +1283,9 @@ kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
}
VATTR_NULL(&vattr);
vattr.va_type = VFIFO;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
#ifdef MAC
error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
@ -1487,9 +1487,9 @@ kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg)
goto restart;
}
VATTR_NULL(&vattr);
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
#ifdef MAC
vattr.va_type = VLNK;
error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
@ -3254,9 +3254,9 @@ kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
}
VATTR_NULL(&vattr);
vattr.va_type = VDIR;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
#ifdef MAC
error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
@ -3658,11 +3658,11 @@ umask(td, uap)
{
register struct filedesc *fdp;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
fdp = td->td_proc->p_fd;
td->td_retval[0] = fdp->fd_cmask;
fdp->fd_cmask = uap->newmask & ALLPERMS;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
return (0);
}

View File

@ -702,10 +702,10 @@ fchdir(td, uap)
return (error);
}
VOP_UNLOCK(vp, 0, td);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
vpold = fdp->fd_cdir;
fdp->fd_cdir = vp;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
vrele(vpold);
return (0);
}
@ -747,10 +747,10 @@ kern_chdir(struct thread *td, char *path, enum uio_seg pathseg)
}
VOP_UNLOCK(nd.ni_vp, 0, td);
NDFREE(&nd, NDF_ONLY_PNBUF);
FILEDESC_LOCK(fdp);
FILEDESC_LOCK_FAST(fdp);
vp = fdp->fd_cdir;
fdp->fd_cdir = nd.ni_vp;
FILEDESC_UNLOCK(fdp);
FILEDESC_UNLOCK_FAST(fdp);
vrele(vp);
return (0);
}
@ -1175,10 +1175,10 @@ kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
return (EEXIST);
} else {
VATTR_NULL(&vattr);
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = (mode & ALLPERMS) &
~td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
vattr.va_rdev = dev;
whiteout = 0;
@ -1283,9 +1283,9 @@ kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
}
VATTR_NULL(&vattr);
vattr.va_type = VFIFO;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
#ifdef MAC
error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
@ -1487,9 +1487,9 @@ kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg)
goto restart;
}
VATTR_NULL(&vattr);
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
#ifdef MAC
vattr.va_type = VLNK;
error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
@ -3254,9 +3254,9 @@ kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
}
VATTR_NULL(&vattr);
vattr.va_type = VDIR;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
#ifdef MAC
error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
&vattr);
@ -3658,11 +3658,11 @@ umask(td, uap)
{
register struct filedesc *fdp;
FILEDESC_LOCK(td->td_proc->p_fd);
FILEDESC_LOCK_FAST(td->td_proc->p_fd);
fdp = td->td_proc->p_fd;
td->td_retval[0] = fdp->fd_cmask;
fdp->fd_cmask = uap->newmask & ALLPERMS;
FILEDESC_UNLOCK(td->td_proc->p_fd);
FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
return (0);
}

View File

@ -99,6 +99,9 @@ struct filedesc_to_leader {
#define FILEDESC_LOCK_ASSERT(fd, type) mtx_assert(&(fd)->fd_mtx, (type))
#define FILEDESC_LOCK_DESC "filedesc structure"
#define FILEDESC_LOCK_FAST(fd) FILEDESC_LOCK(fd);
#define FILEDESC_UNLOCK_FAST(fd) FILEDESC_UNLOCK(fd);
struct thread;
int closef(struct file *fp, struct thread *td);