summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2014-07-06 22:56:34 +0000
committermjg <mjg@FreeBSD.org>2014-07-06 22:56:34 +0000
commitc9bb8da01167a7b5ceaa16259e6b6bab943b7ea9 (patch)
tree4aa49597bd2f7bcb0c343c74a2b0398a865addd7 /sys/kern
parent4ec4a6585547ae29000dc768cf108796f523d42a (diff)
downloadFreeBSD-src-c9bb8da01167a7b5ceaa16259e6b6bab943b7ea9.zip
FreeBSD-src-c9bb8da01167a7b5ceaa16259e6b6bab943b7ea9.tar.gz
MFC r267755:
Don't take filedesc lock in fdunshare(). We can read refcnt safely and only care if it is equal to 1. If it could suddenly change from 1 to something bigger the code would be buggy even in the previous form and transitions from > 1 to 1 are equally racy and harmless (we copy even though there is no need).
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_descrip.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 80a9c20..83873af 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1885,17 +1885,14 @@ fdshare(struct filedesc *fdp)
void
fdunshare(struct proc *p, struct thread *td)
{
+ struct filedesc *tmp;
- FILEDESC_XLOCK(p->p_fd);
- if (p->p_fd->fd_refcnt > 1) {
- struct filedesc *tmp;
+ if (p->p_fd->fd_refcnt == 1)
+ return;
- FILEDESC_XUNLOCK(p->p_fd);
- tmp = fdcopy(p->p_fd);
- fdescfree(td);
- p->p_fd = tmp;
- } else
- FILEDESC_XUNLOCK(p->p_fd);
+ tmp = fdcopy(p->p_fd);
+ fdescfree(td);
+ p->p_fd = tmp;
}
/*
OpenPOWER on IntegriCloud