From ae022b6e9c06154798209cd64cb202bff9e4cc76 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Thu, 19 Jun 2014 17:13:46 -0400 Subject: [PATCH] Revert "Revert "Revert "Fix unlink/xattr deadlock""" This reverts commit 7973e464de4f93b6e669f7f04a316e013767224e. That had been intended to workaround a deadlock issue involving zfs_zget(), which was fixed by 6f9548c487dbcf958f2f226c5f1eac2b85f8f78e. The workaround had the side effect of causing zfs_zinactive() to cause excessive cpu utilization in zfs_iput_taskq by queuing an iteration of all objects in a dataset on every unlink on a directory that had extended attributes. That resulted in many issue reports about iput_taskq spinning. Since the original rationale for the change is no longer valid, we can safely revert it to resolve all of those issue reports. Conflicts: module/zfs/zfs_dir.c Closes: zfsonlinux/zfs#457 zfsonlinux/zfs#2058 zfsonlinux/zfs#2128 zfsonlinux/zfs#2240 --- module/zfs/zfs_dir.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c index 448a8727ebbb..7b3dbcc053c9 100644 --- a/module/zfs/zfs_dir.c +++ b/module/zfs/zfs_dir.c @@ -623,7 +623,6 @@ zfs_rmnode(znode_t *zp) dmu_tx_t *tx; uint64_t acl_obj; uint64_t xattr_obj; - uint64_t count; int error; ASSERT(zp->z_links == 0); @@ -633,27 +632,13 @@ zfs_rmnode(znode_t *zp) * If this is an attribute directory, purge its contents. */ if (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_XATTR)) { - error = zap_count(os, zp->z_id, &count); - if (error) { - zfs_znode_dmu_fini(zp); - return; - } - - if (count > 0) { - taskq_t *taskq; - + if (zfs_purgedir(zp) != 0) { /* - * There are still directory entries in this xattr - * directory. Let zfs_unlinked_drain() deal with - * them to avoid deadlocking this process in the - * zfs_purgedir()->zfs_zget()->ilookup() callpath - * on the xattr inode's I_FREEING bit. + * Not enough space to delete some xattrs. + * Leave it in the unlinked set. */ - taskq = dsl_pool_iput_taskq(dmu_objset_pool(os)); - taskq_dispatch(taskq, (task_func_t *) - zfs_unlinked_drain, zsb, TQ_SLEEP); - zfs_znode_dmu_fini(zp); + return; } }