Skip to content

Commit 069fac4

Browse files
Separate from userspace upgrade
Signed-off-by: Dušan Gvozdenović <dusan.gvozdenovic.99@gmail.com>
1 parent 63dd016 commit 069fac4

File tree

1 file changed

+117
-78
lines changed

1 file changed

+117
-78
lines changed

module/zfs/zfs_ioctl.c

Lines changed: 117 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,99 +3105,64 @@ zfs_ioc_inherit_prop(zfs_cmd_t *zc)
31053105
}
31063106

31073107
static int
3108-
zfs_userspace_upgrade_impl(const char *filesystem)
3108+
zfs_projectquota_upgrade_cb(const char *dataset, void *arg)
31093109
{
3110-
int error = 0;
31113110
zfsvfs_t *zfsvfs;
3111+
int error;
31123112

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);
3113+
(void) arg;
31183114

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;
3115+
error = getzfsvfs(dataset, &zfsvfs);
31273116

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);
3117+
if (error != 0)
3118+
return (0);
31423119

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-
}
3120+
if (!dmu_objset_projectquota_enabled(zfsvfs->z_os)) {
3121+
/*
3122+
* If projectquota is not enabled, it may be because the objset
3123+
* needs to be closed & reopened (to grow the objset_phys_t).
3124+
* Suspend/resume the fs will do that.
3125+
*/
3126+
dsl_dataset_t *ds, *newds;
31563127

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;
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);
31603134
}
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);
3135+
}
31693136

3170-
mutex_enter(&os->os_upgrade_lock);
3171-
if (os->os_upgrade_id == 0) {
3137+
if (error == 0) {
3138+
mutex_enter(&zfsvfs->z_os->os_upgrade_lock);
3139+
if (zfsvfs->z_os->os_upgrade_id == 0) {
31723140
/* 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);
3141+
zfsvfs->z_os->os_upgrade_status = 0;
3142+
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
3143+
3144+
dsl_pool_config_enter(
3145+
dmu_objset_pool(zfsvfs->z_os), FTAG);
3146+
dmu_objset_id_quota_upgrade(zfsvfs->z_os);
3147+
dsl_pool_config_exit(
3148+
dmu_objset_pool(zfsvfs->z_os), FTAG);
31783149
} else {
3179-
mutex_exit(&os->os_upgrade_lock);
3150+
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
31803151
}
31813152

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);
3153+
taskq_wait_id(zfsvfs->z_os->os_spa->spa_upgrade_taskq,
3154+
zfsvfs->z_os->os_upgrade_id);
3155+
error = zfsvfs->z_os->os_upgrade_status;
31893156
}
31903157

3191-
return (error);
3192-
}
3193-
3158+
zfs_vfs_rele(zfsvfs);
31943159

3160+
if (error != 0)
3161+
cmn_err(CE_WARN,
3162+
"Failed to activate the project quota feature on dataset "
3163+
"%s (%d).", dataset, error);
31953164

3196-
static int
3197-
zfs_userspace_upgrade_cb(const char *dataset, void *arg)
3198-
{
3199-
(void) arg;
3200-
return (zfs_userspace_upgrade_impl(dataset));
3165+
return (0);
32013166
}
32023167

32033168
static int
@@ -3239,8 +3204,14 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)
32393204

32403205
error = spa_prop_set(spa, props);
32413206

3207+
/*
3208+
* If we are enabling the project quota feature, try to re-initialize
3209+
* the active file systems on that pool and activate the feature -- all
3210+
* in best effort.
3211+
*/
32423212
if ((error == 0) && nvlist_exists(props, "feature@project_quota"))
3243-
error = dmu_objset_find(spa_name(spa), zfs_userspace_upgrade_cb,
3213+
(void) dmu_objset_find(spa_name(spa),
3214+
zfs_projectquota_upgrade_cb,
32443215
NULL, DS_FIND_CHILDREN);
32453216

32463217
nvlist_free(props);
@@ -6504,7 +6475,75 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
65046475
static int
65056476
zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
65066477
{
6507-
return (zfs_userspace_upgrade_impl(zc->zc_name));
6478+
int error = 0;
6479+
zfsvfs_t *zfsvfs;
6480+
6481+
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
6482+
if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
6483+
/*
6484+
* If userused is not enabled, it may be because the
6485+
* objset needs to be closed & reopened (to grow the
6486+
* objset_phys_t). Suspend/resume the fs will do that.
6487+
*/
6488+
dsl_dataset_t *ds, *newds;
6489+
6490+
ds = dmu_objset_ds(zfsvfs->z_os);
6491+
error = zfs_suspend_fs(zfsvfs);
6492+
if (error == 0) {
6493+
dmu_objset_refresh_ownership(ds, &newds,
6494+
B_TRUE, zfsvfs);
6495+
error = zfs_resume_fs(zfsvfs, newds);
6496+
}
6497+
}
6498+
if (error == 0) {
6499+
mutex_enter(&zfsvfs->z_os->os_upgrade_lock);
6500+
if (zfsvfs->z_os->os_upgrade_id == 0) {
6501+
/* clear potential error code and retry */
6502+
zfsvfs->z_os->os_upgrade_status = 0;
6503+
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
6504+
6505+
dsl_pool_config_enter(
6506+
dmu_objset_pool(zfsvfs->z_os), FTAG);
6507+
dmu_objset_userspace_upgrade(zfsvfs->z_os);
6508+
dsl_pool_config_exit(
6509+
dmu_objset_pool(zfsvfs->z_os), FTAG);
6510+
} else {
6511+
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
6512+
}
6513+
6514+
taskq_wait_id(zfsvfs->z_os->os_spa->spa_upgrade_taskq,
6515+
zfsvfs->z_os->os_upgrade_id);
6516+
error = zfsvfs->z_os->os_upgrade_status;
6517+
}
6518+
zfs_vfs_rele(zfsvfs);
6519+
} else {
6520+
objset_t *os;
6521+
6522+
/* XXX kind of reading contents without owning */
6523+
error = dmu_objset_hold_flags(zc->zc_name, B_TRUE, FTAG, &os);
6524+
if (error != 0)
6525+
return (error);
6526+
6527+
mutex_enter(&os->os_upgrade_lock);
6528+
if (os->os_upgrade_id == 0) {
6529+
/* clear potential error code and retry */
6530+
os->os_upgrade_status = 0;
6531+
mutex_exit(&os->os_upgrade_lock);
6532+
6533+
dmu_objset_userspace_upgrade(os);
6534+
} else {
6535+
mutex_exit(&os->os_upgrade_lock);
6536+
}
6537+
6538+
dsl_pool_rele(dmu_objset_pool(os), FTAG);
6539+
6540+
taskq_wait_id(os->os_spa->spa_upgrade_taskq, os->os_upgrade_id);
6541+
error = os->os_upgrade_status;
6542+
6543+
dsl_dataset_rele_flags(dmu_objset_ds(os), DS_HOLD_FLAG_DECRYPT,
6544+
FTAG);
6545+
}
6546+
return (error);
65086547
}
65096548

65106549
/*

0 commit comments

Comments
 (0)