diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-08-11 01:27:53 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-08-11 01:27:53 +0000 |
commit | 371cf09cf75eb31267e0d4f07e35e6fba755d416 (patch) | |
tree | cce42dfa808ef7915aedf3062ffebef6e141683f /sys/kern/vfs_subr.c | |
parent | 5846466bff4d5d09196a4bd46915d2c3e8d83032 (diff) | |
download | FreeBSD-src-371cf09cf75eb31267e0d4f07e35e6fba755d416.zip FreeBSD-src-371cf09cf75eb31267e0d4f07e35e6fba755d416.tar.gz |
In v_addpollinfo(), we allocate storage to back vp->v_pollinfo. However,
we may sleep when doing so; check that we didn't race with another thread
allocating storage for the vnode after allocation is made to a local
pointer, and only update the vnode pointer if it's still NULL. Otherwise,
accept that another thread got there first, and release the local storage.
Discussed with: jmg
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r-- | sys/kern/vfs_subr.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 72d41c9..aa234be 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3247,8 +3247,14 @@ vbusy(vp) void v_addpollinfo(struct vnode *vp) { + struct vpollinfo *vi; - vp->v_pollinfo = uma_zalloc(vnodepoll_zone, M_WAITOK); + vi = uma_zalloc(vnodepoll_zone, M_WAITOK); + if (vp->v_pollinfo != NULL) { + uma_zfree(vnodepoll_zone, vi); + return; + } + vp->v_pollinfo = vi; mtx_init(&vp->v_pollinfo->vpi_lock, "vnode pollinfo", NULL, MTX_DEF); } |