@@ -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+
31073203static int
31083204zfs_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)
64046504static int
64056505zfs_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