mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-28 20:09:35 +03:00
Do not hash unlinked inodes
In zfs_znode_alloc we always hash inodes. If the znode is unlinked, we do not need to hash it. This fixes the problem where zfs_suspend_fs is doing zrele (iput) in an async fashion, and zfs_resume_fs unlinked drain processing will try to hash an inode that could still be hashed, resulting in a panic. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alan Somers <asomers@gmail.com> Signed-off-by: Paul Zuchowski <pzuchowski@datto.com> Closes #9741 Closes #11223 Closes #11648 Closes #12210
This commit is contained in:
parent
cd2bb9ca44
commit
bd197378e7
@ -610,17 +610,24 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
|||||||
* number is already hashed for this super block. This can never
|
* number is already hashed for this super block. This can never
|
||||||
* happen because the inode numbers map 1:1 with the object numbers.
|
* happen because the inode numbers map 1:1 with the object numbers.
|
||||||
*
|
*
|
||||||
* The one exception is rolling back a mounted file system, but in
|
* Exceptions include rolling back a mounted file system, either
|
||||||
* this case all the active inode are unhashed during the rollback.
|
* from the zfs rollback or zfs recv command.
|
||||||
|
*
|
||||||
|
* Active inodes are unhashed during the rollback, but since zrele
|
||||||
|
* can happen asynchronously, we can't guarantee they've been
|
||||||
|
* unhashed. This can cause hash collisions in unlinked drain
|
||||||
|
* processing so do not hash unlinked znodes.
|
||||||
*/
|
*/
|
||||||
VERIFY3S(insert_inode_locked(ip), ==, 0);
|
if (links > 0)
|
||||||
|
VERIFY3S(insert_inode_locked(ip), ==, 0);
|
||||||
|
|
||||||
mutex_enter(&zfsvfs->z_znodes_lock);
|
mutex_enter(&zfsvfs->z_znodes_lock);
|
||||||
list_insert_tail(&zfsvfs->z_all_znodes, zp);
|
list_insert_tail(&zfsvfs->z_all_znodes, zp);
|
||||||
zfsvfs->z_nr_znodes++;
|
zfsvfs->z_nr_znodes++;
|
||||||
mutex_exit(&zfsvfs->z_znodes_lock);
|
mutex_exit(&zfsvfs->z_znodes_lock);
|
||||||
|
|
||||||
unlock_new_inode(ip);
|
if (links > 0)
|
||||||
|
unlock_new_inode(ip);
|
||||||
return (zp);
|
return (zp);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
Loading…
Reference in New Issue
Block a user