diff options
author | kib <kib@FreeBSD.org> | 2013-05-30 20:00:19 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-05-30 20:00:19 +0000 |
commit | 0c381861b05890dec1e89030d37c6dbea3c12ca5 (patch) | |
tree | cd232be5aa494d81ef875403216e779919449aed | |
parent | b77a98bb0bb774837efbd1e011d9215776cb0e90 (diff) | |
download | FreeBSD-src-0c381861b05890dec1e89030d37c6dbea3c12ca5.zip FreeBSD-src-0c381861b05890dec1e89030d37c6dbea3c12ca5.tar.gz |
After the object lock was dropped, the object' reference count could
change. Retest the ref_count and return from the function to not
execute the further code which assumes that ref_count == 1 if it is
not. Also, do not leak vnode lock if other thread cleared OBJ_TMPFS
flag meantime.
Reported by: bdrewery
Tested by: bdrewery, pho
Sponsored by: The FreeBSD Foundation
-rw-r--r-- | sys/vm/vm_object.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 258a8da..08e4e15 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -536,15 +536,15 @@ vm_object_deallocate(vm_object_t object) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vdrop(vp); VM_OBJECT_WLOCK(object); - if (object->type == OBJT_DEAD) { + if (object->type == OBJT_DEAD || + object->ref_count != 1) { VM_OBJECT_WUNLOCK(object); VOP_UNLOCK(vp, 0); return; - } else if ((object->flags & OBJ_TMPFS) != 0) { - if (object->ref_count == 1) - VOP_UNSET_TEXT(vp); - VOP_UNLOCK(vp, 0); } + if ((object->flags & OBJ_TMPFS) != 0) + VOP_UNSET_TEXT(vp); + VOP_UNLOCK(vp, 0); } if (object->shadow_count == 0 && object->handle == NULL && |