freebsd-skq/sys/cddl
Andriy Gapon 0f7dcde977 fix deadlock-prone code in getzfsvfs()
getzfsvfs() called vfs_busy() in the waiting mode while having a hold on
a pool (via a call to dmu_objset_hold).  In other words,
dp_config_rwlock was held in the shared mode while a thread could be
sleeping in vfs_busy().
The pool's txg sync thread needs to take dp_config_rwlock in the
exclusive mode for some actions, e.g., for executing sync tasks.  If the
sync thread gets blocked, then any thread waiting for its sync task to
get executed is also blocked.  Which, in turn, could mean that
vfs_busy() will keep waiting indefinitely.

The solution is to use vfs_ref() in the locked section and to call
vfs_busy() only after dropping other locks.
Note that a reference on a struct mount object does not prevent an
associated zfsvfs_t object from being destroyed.  So, we have to be
careful to operate only on the struct mount object until we successfully
vfs_busy it.

Approved by:	re (gjb)
MFC after:	2 weeks
2016-06-23 07:01:54 +00:00
..
boot/zfs Use netinet/in.h to avoid include/arpa dependency for DIRDEPS_BUILD. 2016-05-26 23:20:17 +00:00
compat/opensolaris Use vnlru_free(9) to implement dnlc_reduce_cache(). 2016-06-17 17:34:28 +00:00
contrib/opensolaris fix deadlock-prone code in getzfsvfs() 2016-06-23 07:01:54 +00:00
dev Set oldfp so the check for fp == oldfp works as expected. 2016-05-31 11:32:09 +00:00