Skip to content

Commit

Permalink
Remove incorrect ASSERT in zfs_sb_teardown()
Browse files Browse the repository at this point in the history
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 openzfs#1417
Closes openzfs#1536
  • Loading branch information
behlendorf authored and ryao committed Apr 9, 2014
1 parent fa7be04 commit 2ce0771
Showing 1 changed file with 1 addition and 3 deletions.
4 changes: 1 addition & 3 deletions module/zfs/zfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,10 +1099,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);

Expand Down

0 comments on commit 2ce0771

Please sign in to comment.