]> git.proxmox.com Git - mirror_zfs.git/commit - module/zfs/spa.c
Fix deadlock between zpool export and zfs list
authorIsaac Huang <he.huang@intel.com>
Fri, 27 Feb 2015 05:46:45 +0000 (22:46 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 2 Mar 2015 19:50:06 +0000 (11:50 -0800)
commitd14cfd83dae0b1a261667acd416dba17a98d15fa
treeb5052cb4d9fcd75ef873fbe767222774ae183b43
parent87a63dd702370c00322e8d1d84102075c775324b
Fix deadlock between zpool export and zfs list

Pool reference count is NOT checked in spa_export_common()
if the pool has been imported readonly=on, i.e. spa->spa_sync_on
is FALSE. Then zpool export and zfs list may deadlock:

1. Pool A is imported readonly.
2. zpool export A and zfs list are run concurrently.
3. zfs command gets reference on the spa, which holds a dbuf on
   on the MOS meta dnode.
4. zpool command grabs spa_namespace_lock, and tries to evict dbufs
   of the MOS meta dnode. The dbuf held by zfs command can't be
   evicted as its reference count is not 0.
5. zpool command blocks in dnode_special_close() waiting for the
   MOS meta dnode reference count to drop to 0, with
   spa_namespace_lock held.
6. zfs command tries to get the spa_namespace_lock with a reference
   on the spa held, which holds a dbuf on the MOS meta dnode.
7. Now zpool command and zfs command deadlock each other.

Also any further zfs/zpool command will block on spa_namespace_lock
forever.

The fix is to always check pool reference count in spa_export_common(),
no matter whether the pool was imported readonly or not.

Signed-off-by: Isaac Huang <he.huang@intel.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2034
module/zfs/spa.c