Problem Summary:
---------------
If an xattr directory inode and its xattr child inode are on the _same_
disposal list,
and the xattr directory inode is _before_ its xattr child inode in this
disposal list...
Then zfs_purgedir() of the xattr directory calls zfs_zget() for the xattr child
inode
and it loops forever -- it can only stop if the xattr child inode is
disposed/evicted,
but it could only occur _after_ in the disposal list and current list node is
looping...
Because zfs_zget() gets non-NULL from dmu_buf_get_user() (which could go NULL
only in
the ZFS evict path later in disposal list) so it goes to igrab() but that
returns NULL
(because the inode.i_state got I_FREEING), then 'goto again:', which repeats
that over.
Function path:
shrink_slab
- do_shrink_slab
- shrinker->scan_objects == super_cache_scan
- prune_icache_sb
- list_sru_shrink_walk
(creates disposal list with xattr dir&child inodes)
- inode_lru_isolate(inode)
- inode->i_state |= I_FREEING
(problem for igrab of xattr child inode, below)
- dispose_list
- evict(xattr dir inode)
- op->evict_inode == zpl_evict_inode
- zfs_inactive
- zfs_zinactive
- zfs_rmnode
- zfs_purgedir
- zfs_zget (xattr child nodes)
- dmu_buf_get_user (non-NULL)
- igrab (NULL)
- goto again;
... thus never reaching ...
- evict(xattr child inode)
- op->evict_inode == zpl_evict_inode
- zfs_inactive
- zfs_zinactive
- zfs_znode_dmu_fini
- sa_handle_destroy
- dmu_buf_remove_user
(not calling this yet is a problem for dmu_buf_get_user,
above)
(this would make it return NULL and not go into the igrab
call)
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1839521
Title:
Xenial: ZFS deadlock in shrinker path with xattrs
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/zfs-linux/+bug/1839521/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs