@@ -3105,99 +3105,64 @@ zfs_ioc_inherit_prop(zfs_cmd_t *zc)
31053105}
31063106
31073107static 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
32033168static 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)
65046475static int
65056476zfs_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