From 2e40f094109c2b345447351f07b0b525f44988d2 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 2 Dec 2013 10:26:21 -0800 Subject: [PATCH] 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 Signed-off-by: Chris Dunlop Signed-off-by: Tim Chase Closes #1417 Closes #1536 --- module/zfs/zfs_vfsops.c | 4 +--- 1 file changed, 1 insertion(+), 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); -- 2.40.0