diff options
author | Brian Behlendorf <[email protected]> | 2013-12-02 10:26:21 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2013-12-02 15:58:58 -0800 |
commit | 2e40f094109c2b345447351f07b0b525f44988d2 (patch) | |
tree | 3309b1fbe4f84b8d1b4d391321aa34690148e68f /module/zfs/zfs_vfsops.c | |
parent | c8c8d1e7e5dd156ac0c268895edcd9e552a3adea (diff) |
Remove incorrect ASSERT in zfs_sb_teardown()
As part of zfs_sb_teardown() there is an assertion that all inodes
which are part of the zsb->z_all_znodes list have at least one
reference on them. This is always true for the standard unmount
case but there are two other cases where it is not strictly true.
* zfs_ioc_rollback() - This is the most common case and it results
from the fact that we aren't unmounting the filesystem. During a
normal unmount the MS_ACTIVE flag will be cleared on the super block
causing iput_final() to evict the inode when its reference count
drops to zero. However, during a rollback MS_ACTIVE remains set
since we're rolling back a live filesystem and need to preserve the
existing super block. This allows inodes with a zero reference count
to stay in the cache thereby violating the assertion.
* destroy_inode() / zfs_sb_teardown() - There exists a small race
between dropping the last reference on an inode and removing it from
the zsb->z_all_znodes list. This is unlikely to occur but could also
trigger the assertion which is incorrect. The inode may safely have
a zero reference count in this case.
Since allowing a zero reference count on the inode is expected and
safe for both of these cases the simplest thing to do is remove the
ASSERT. This code is only enabled for default builds so removing
this entirely is a very safe change.
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Chris Dunlop <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Closes #1417
Closes #1536
Diffstat (limited to 'module/zfs/zfs_vfsops.c')
-rw-r--r-- | module/zfs/zfs_vfsops.c | 4 |
1 files changed, 1 insertions, 3 deletions
diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 5c65b964a..2c0e923dc 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1144,10 +1144,8 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting) mutex_enter(&zsb->z_znodes_lock); for (zp = list_head(&zsb->z_all_znodes); zp != NULL; zp = list_next(&zsb->z_all_znodes, zp)) { - if (zp->z_sa_hdl) { - ASSERT(atomic_read(&ZTOI(zp)->i_count) > 0); + if (zp->z_sa_hdl) zfs_znode_dmu_fini(zp); - } } mutex_exit(&zsb->z_znodes_lock); |