Skip to content

Commit 63dd016

Browse files
Re-initialize objsets when feature@project_quota is enabled
Addresses the issue of project quotas not being usable after pool upgrade coming from an older vesion which does not support project quotas to the one that does, analogously to how it was solved for user quotas back in the day -- when feature@project_quota is first enabled, re-initialize the pool's objsets. Signed-off-by: Dušan Gvozdenović <[email protected]> Closes #17955
1 parent 7f7d493 commit 63dd016

File tree

1 file changed

+101
-69
lines changed

1 file changed

+101
-69
lines changed

module/zfs/zfs_ioctl.c

Lines changed: 101 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,6 +3104,102 @@ zfs_ioc_inherit_prop(zfs_cmd_t *zc)
31043104
return (err);
31053105
}
31063106

3107+
static int
3108+
zfs_userspace_upgrade_impl(const char *filesystem)
3109+
{
3110+
int error = 0;
3111+
zfsvfs_t *zfsvfs;
3112+
3113+
if (getzfsvfs(filesystem, &zfsvfs) == 0) {
3114+
const boolean_t userused_enabled =
3115+
dmu_objset_userused_enabled(zfsvfs->z_os);
3116+
const boolean_t projectquota_enabled =
3117+
dmu_objset_projectquota_enabled(zfsvfs->z_os);
3118+
3119+
if (!userused_enabled || !projectquota_enabled) {
3120+
/*
3121+
* If userused/projectquota is not enabled, it may be
3122+
* because the objset needs to be closed & reopened (to
3123+
* grow the objset_phys_t). Suspend/resume the fs will
3124+
* do that.
3125+
*/
3126+
dsl_dataset_t *ds, *newds;
3127+
3128+
ds = dmu_objset_ds(zfsvfs->z_os);
3129+
error = zfs_suspend_fs(zfsvfs);
3130+
if (error == 0) {
3131+
dmu_objset_refresh_ownership(ds, &newds,
3132+
B_TRUE, zfsvfs);
3133+
error = zfs_resume_fs(zfsvfs, newds);
3134+
}
3135+
}
3136+
if (error == 0) {
3137+
mutex_enter(&zfsvfs->z_os->os_upgrade_lock);
3138+
if (zfsvfs->z_os->os_upgrade_id == 0) {
3139+
/* clear potential error code and retry */
3140+
zfsvfs->z_os->os_upgrade_status = 0;
3141+
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
3142+
3143+
dsl_pool_config_enter(
3144+
dmu_objset_pool(zfsvfs->z_os), FTAG);
3145+
if (!userused_enabled)
3146+
dmu_objset_userspace_upgrade(
3147+
zfsvfs->z_os);
3148+
if (!projectquota_enabled)
3149+
dmu_objset_id_quota_upgrade(
3150+
zfsvfs->z_os);
3151+
dsl_pool_config_exit(
3152+
dmu_objset_pool(zfsvfs->z_os), FTAG);
3153+
} else {
3154+
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
3155+
}
3156+
3157+
taskq_wait_id(zfsvfs->z_os->os_spa->spa_upgrade_taskq,
3158+
zfsvfs->z_os->os_upgrade_id);
3159+
error = zfsvfs->z_os->os_upgrade_status;
3160+
}
3161+
zfs_vfs_rele(zfsvfs);
3162+
} else {
3163+
objset_t *os;
3164+
3165+
/* XXX kind of reading contents without owning */
3166+
error = dmu_objset_hold_flags(filesystem, B_TRUE, FTAG, &os);
3167+
if (error != 0)
3168+
return (error);
3169+
3170+
mutex_enter(&os->os_upgrade_lock);
3171+
if (os->os_upgrade_id == 0) {
3172+
/* clear potential error code and retry */
3173+
os->os_upgrade_status = 0;
3174+
mutex_exit(&os->os_upgrade_lock);
3175+
3176+
dmu_objset_userspace_upgrade(os);
3177+
dmu_objset_id_quota_upgrade(os);
3178+
} else {
3179+
mutex_exit(&os->os_upgrade_lock);
3180+
}
3181+
3182+
dsl_pool_rele(dmu_objset_pool(os), FTAG);
3183+
3184+
taskq_wait_id(os->os_spa->spa_upgrade_taskq, os->os_upgrade_id);
3185+
error = os->os_upgrade_status;
3186+
3187+
dsl_dataset_rele_flags(dmu_objset_ds(os), DS_HOLD_FLAG_DECRYPT,
3188+
FTAG);
3189+
}
3190+
3191+
return (error);
3192+
}
3193+
3194+
3195+
3196+
static int
3197+
zfs_userspace_upgrade_cb(const char *dataset, void *arg)
3198+
{
3199+
(void) arg;
3200+
return (zfs_userspace_upgrade_impl(dataset));
3201+
}
3202+
31073203
static int
31083204
zfs_ioc_pool_set_props(zfs_cmd_t *zc)
31093205
{
@@ -3143,6 +3239,10 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)
31433239

31443240
error = spa_prop_set(spa, props);
31453241

3242+
if ((error == 0) && nvlist_exists(props, "feature@project_quota"))
3243+
error = dmu_objset_find(spa_name(spa), zfs_userspace_upgrade_cb,
3244+
NULL, DS_FIND_CHILDREN);
3245+
31463246
nvlist_free(props);
31473247
spa_close(spa, FTAG);
31483248

@@ -6404,75 +6504,7 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
64046504
static int
64056505
zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
64066506
{
6407-
int error = 0;
6408-
zfsvfs_t *zfsvfs;
6409-
6410-
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
6411-
if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
6412-
/*
6413-
* If userused is not enabled, it may be because the
6414-
* objset needs to be closed & reopened (to grow the
6415-
* objset_phys_t). Suspend/resume the fs will do that.
6416-
*/
6417-
dsl_dataset_t *ds, *newds;
6418-
6419-
ds = dmu_objset_ds(zfsvfs->z_os);
6420-
error = zfs_suspend_fs(zfsvfs);
6421-
if (error == 0) {
6422-
dmu_objset_refresh_ownership(ds, &newds,
6423-
B_TRUE, zfsvfs);
6424-
error = zfs_resume_fs(zfsvfs, newds);
6425-
}
6426-
}
6427-
if (error == 0) {
6428-
mutex_enter(&zfsvfs->z_os->os_upgrade_lock);
6429-
if (zfsvfs->z_os->os_upgrade_id == 0) {
6430-
/* clear potential error code and retry */
6431-
zfsvfs->z_os->os_upgrade_status = 0;
6432-
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
6433-
6434-
dsl_pool_config_enter(
6435-
dmu_objset_pool(zfsvfs->z_os), FTAG);
6436-
dmu_objset_userspace_upgrade(zfsvfs->z_os);
6437-
dsl_pool_config_exit(
6438-
dmu_objset_pool(zfsvfs->z_os), FTAG);
6439-
} else {
6440-
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
6441-
}
6442-
6443-
taskq_wait_id(zfsvfs->z_os->os_spa->spa_upgrade_taskq,
6444-
zfsvfs->z_os->os_upgrade_id);
6445-
error = zfsvfs->z_os->os_upgrade_status;
6446-
}
6447-
zfs_vfs_rele(zfsvfs);
6448-
} else {
6449-
objset_t *os;
6450-
6451-
/* XXX kind of reading contents without owning */
6452-
error = dmu_objset_hold_flags(zc->zc_name, B_TRUE, FTAG, &os);
6453-
if (error != 0)
6454-
return (error);
6455-
6456-
mutex_enter(&os->os_upgrade_lock);
6457-
if (os->os_upgrade_id == 0) {
6458-
/* clear potential error code and retry */
6459-
os->os_upgrade_status = 0;
6460-
mutex_exit(&os->os_upgrade_lock);
6461-
6462-
dmu_objset_userspace_upgrade(os);
6463-
} else {
6464-
mutex_exit(&os->os_upgrade_lock);
6465-
}
6466-
6467-
dsl_pool_rele(dmu_objset_pool(os), FTAG);
6468-
6469-
taskq_wait_id(os->os_spa->spa_upgrade_taskq, os->os_upgrade_id);
6470-
error = os->os_upgrade_status;
6471-
6472-
dsl_dataset_rele_flags(dmu_objset_ds(os), DS_HOLD_FLAG_DECRYPT,
6473-
FTAG);
6474-
}
6475-
return (error);
6507+
return (zfs_userspace_upgrade_impl(zc->zc_name));
64766508
}
64776509

64786510
/*

0 commit comments

Comments
 (0)