diff options
author | loli10K <[email protected]> | 2020-11-16 18:10:29 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-11-16 09:10:29 -0800 |
commit | 4072f465bc3630bbab50afccfd6c7baf41afcc4c (patch) | |
tree | 3eabc85191eb9d0fb9dd788fe1e1305596d2a728 /module/zfs/zfs_ioctl.c | |
parent | 2c210f68189c6f781be050bfdc890cd6dc231fea (diff) |
Fix 'zfs userspace' for received datasets in encrypted root
For encrypted receives, where user accounting is initially disabled on
creation, both 'zfs userspace' and 'zfs groupspace' fails with
EOPNOTSUPP: this is because dmu_objset_id_quota_upgrade_cb() forgets to
set OBJSET_FLAG_USERACCOUNTING_COMPLETE on the objset flags after a
successful dmu_objset_space_upgrade().
Reviewed-by: Brian Behlendorf <[email protected]>
Co-authored-by: Brian Behlendorf <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes #9501
Closes #9596
Diffstat (limited to 'module/zfs/zfs_ioctl.c')
-rw-r--r-- | module/zfs/zfs_ioctl.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 7f2cf2a75..33bd39aa2 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -5856,7 +5856,6 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc) static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) { - objset_t *os; int error = 0; zfsvfs_t *zfsvfs; @@ -5877,19 +5876,54 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) error = zfs_resume_fs(zfsvfs, newds); } } - if (error == 0) - error = dmu_objset_userspace_upgrade(zfsvfs->z_os); + if (error == 0) { + mutex_enter(&zfsvfs->z_os->os_upgrade_lock); + if (zfsvfs->z_os->os_upgrade_id == 0) { + /* clear potential error code and retry */ + zfsvfs->z_os->os_upgrade_status = 0; + mutex_exit(&zfsvfs->z_os->os_upgrade_lock); + + dsl_pool_config_enter( + dmu_objset_pool(zfsvfs->z_os), FTAG); + dmu_objset_userspace_upgrade(zfsvfs->z_os); + dsl_pool_config_exit( + dmu_objset_pool(zfsvfs->z_os), FTAG); + } else { + mutex_exit(&zfsvfs->z_os->os_upgrade_lock); + } + + taskq_wait_id(zfsvfs->z_os->os_spa->spa_upgrade_taskq, + zfsvfs->z_os->os_upgrade_id); + error = zfsvfs->z_os->os_upgrade_status; + } zfs_vfs_rele(zfsvfs); } else { + objset_t *os; + /* XXX kind of reading contents without owning */ error = dmu_objset_hold_flags(zc->zc_name, B_TRUE, FTAG, &os); if (error != 0) return (error); - error = dmu_objset_userspace_upgrade(os); - dmu_objset_rele_flags(os, B_TRUE, FTAG); - } + mutex_enter(&os->os_upgrade_lock); + if (os->os_upgrade_id == 0) { + /* clear potential error code and retry */ + os->os_upgrade_status = 0; + mutex_exit(&os->os_upgrade_lock); + + dmu_objset_userspace_upgrade(os); + } else { + mutex_exit(&os->os_upgrade_lock); + } + dsl_pool_rele(dmu_objset_pool(os), FTAG); + + taskq_wait_id(os->os_spa->spa_upgrade_taskq, os->os_upgrade_id); + error = os->os_upgrade_status; + + dsl_dataset_rele_flags(dmu_objset_ds(os), DS_HOLD_FLAG_DECRYPT, + FTAG); + } return (error); } |