Print this page
4171 clean up spa_feature_*() interfaces
4172 implement extensible_dataset feature for use by other zpool features
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>


 225 } zfs_ioc_vec_t;
 226 
 227 /* This array is indexed by zfs_userquota_prop_t */
 228 static const char *userquota_perms[] = {
 229         ZFS_DELEG_PERM_USERUSED,
 230         ZFS_DELEG_PERM_USERQUOTA,
 231         ZFS_DELEG_PERM_GROUPUSED,
 232         ZFS_DELEG_PERM_GROUPQUOTA,
 233 };
 234 
 235 static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
 236 static int zfs_check_settable(const char *name, nvpair_t *property,
 237     cred_t *cr);
 238 static int zfs_check_clearable(char *dataset, nvlist_t *props,
 239     nvlist_t **errors);
 240 static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
 241     boolean_t *);
 242 int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
 243 static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
 244 
 245 static int zfs_prop_activate_feature(spa_t *spa, zfeature_info_t *feature);
 246 
 247 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
 248 void
 249 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
 250 {
 251         const char *newfile;
 252         char buf[512];
 253         va_list adx;
 254 
 255         /*
 256          * Get rid of annoying "../common/" prefix to filename.
 257          */
 258         newfile = strrchr(file, '/');
 259         if (newfile != NULL) {
 260                 newfile = newfile + 1; /* Get rid of leading / */
 261         } else {
 262                 newfile = file;
 263         }
 264 
 265         va_start(adx, fmt);


2365 
2366                 if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
2367                         break;
2368 
2369                 err = zfs_set_version(zfsvfs, intval);
2370                 zfsvfs_rele(zfsvfs, FTAG);
2371 
2372                 if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
2373                         zfs_cmd_t *zc;
2374 
2375                         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
2376                         (void) strcpy(zc->zc_name, dsname);
2377                         (void) zfs_ioc_userspace_upgrade(zc);
2378                         kmem_free(zc, sizeof (zfs_cmd_t));
2379                 }
2380                 break;
2381         }
2382         case ZFS_PROP_COMPRESSION:
2383         {
2384                 if (intval == ZIO_COMPRESS_LZ4) {
2385                         zfeature_info_t *feature =
2386                             &spa_feature_table[SPA_FEATURE_LZ4_COMPRESS];
2387                         spa_t *spa;
2388 
2389                         if ((err = spa_open(dsname, &spa, FTAG)) != 0)
2390                                 return (err);
2391 
2392                         /*
2393                          * Setting the LZ4 compression algorithm activates
2394                          * the feature.
2395                          */
2396                         if (!spa_feature_is_active(spa, feature)) {

2397                                 if ((err = zfs_prop_activate_feature(spa,
2398                                     feature)) != 0) {
2399                                         spa_close(spa, FTAG);
2400                                         return (err);
2401                                 }
2402                         }
2403 
2404                         spa_close(spa, FTAG);
2405                 }
2406                 /*
2407                  * We still want the default set action to be performed in the
2408                  * caller, we only performed zfeature settings here.
2409                  */
2410                 err = -1;
2411                 break;
2412         }
2413 
2414         default:
2415                 err = -1;
2416         }
2417 
2418         return (err);


3646                 /*
3647                  * If the user specified gzip compression, make sure
3648                  * the SPA supports it. We ignore any errors here since
3649                  * we'll catch them later.
3650                  */
3651                 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
3652                     nvpair_value_uint64(pair, &intval) == 0) {
3653                         if (intval >= ZIO_COMPRESS_GZIP_1 &&
3654                             intval <= ZIO_COMPRESS_GZIP_9 &&
3655                             zfs_earlier_version(dsname,
3656                             SPA_VERSION_GZIP_COMPRESSION)) {
3657                                 return (SET_ERROR(ENOTSUP));
3658                         }
3659 
3660                         if (intval == ZIO_COMPRESS_ZLE &&
3661                             zfs_earlier_version(dsname,
3662                             SPA_VERSION_ZLE_COMPRESSION))
3663                                 return (SET_ERROR(ENOTSUP));
3664 
3665                         if (intval == ZIO_COMPRESS_LZ4) {
3666                                 zfeature_info_t *feature =
3667                                     &spa_feature_table[
3668                                     SPA_FEATURE_LZ4_COMPRESS];
3669                                 spa_t *spa;
3670 
3671                                 if ((err = spa_open(dsname, &spa, FTAG)) != 0)
3672                                         return (err);
3673 
3674                                 if (!spa_feature_is_enabled(spa, feature)) {

3675                                         spa_close(spa, FTAG);
3676                                         return (SET_ERROR(ENOTSUP));
3677                                 }
3678                                 spa_close(spa, FTAG);
3679                         }
3680 
3681                         /*
3682                          * If this is a bootable dataset then
3683                          * verify that the compression algorithm
3684                          * is supported for booting. We must return
3685                          * something other than ENOTSUP since it
3686                          * implies a downrev pool version.
3687                          */
3688                         if (zfs_is_bootfs(dsname) &&
3689                             !BOOTFS_COMPRESS_VALID(intval)) {
3690                                 return (SET_ERROR(ERANGE));
3691                         }
3692                 }
3693                 break;
3694 


3712                     nvpair_value_uint64(pair, &intval) == 0) {
3713                         if (intval == ZFS_ACL_PASSTHROUGH_X &&
3714                             zfs_earlier_version(dsname,
3715                             SPA_VERSION_PASSTHROUGH_X))
3716                                 return (SET_ERROR(ENOTSUP));
3717                 }
3718                 break;
3719         }
3720 
3721         return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
3722 }
3723 
3724 /*
3725  * Checks for a race condition to make sure we don't increment a feature flag
3726  * multiple times.
3727  */
3728 static int
3729 zfs_prop_activate_feature_check(void *arg, dmu_tx_t *tx)
3730 {
3731         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
3732         zfeature_info_t *feature = arg;
3733 
3734         if (!spa_feature_is_active(spa, feature))
3735                 return (0);
3736         else
3737                 return (SET_ERROR(EBUSY));
3738 }
3739 
3740 /*
3741  * The callback invoked on feature activation in the sync task caused by
3742  * zfs_prop_activate_feature.
3743  */
3744 static void
3745 zfs_prop_activate_feature_sync(void *arg, dmu_tx_t *tx)
3746 {
3747         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
3748         zfeature_info_t *feature = arg;
3749 
3750         spa_feature_incr(spa, feature, tx);
3751 }
3752 
3753 /*
3754  * Activates a feature on a pool in response to a property setting. This
3755  * creates a new sync task which modifies the pool to reflect the feature
3756  * as being active.
3757  */
3758 static int
3759 zfs_prop_activate_feature(spa_t *spa, zfeature_info_t *feature)
3760 {
3761         int err;
3762 
3763         /* EBUSY here indicates that the feature is already active */
3764         err = dsl_sync_task(spa_name(spa),
3765             zfs_prop_activate_feature_check, zfs_prop_activate_feature_sync,
3766             feature, 2);
3767 
3768         if (err != 0 && err != EBUSY)
3769                 return (err);
3770         else
3771                 return (0);
3772 }
3773 
3774 /*
3775  * Removes properties from the given props list that fail permission checks
3776  * needed to clear them and to restore them in case of a receive error. For each
3777  * property, make sure we have both set and inherit permissions.
3778  *
3779  * Returns the first error encountered if any permission checks fail. If the
3780  * caller provides a non-NULL errlist, it also gives the complete list of names
3781  * of all the properties that failed a permission check along with the
3782  * corresponding error numbers. The caller is responsible for freeing the
3783  * returned errlist.
3784  *
3785  * If every property checks out successfully, zero is returned and the list
3786  * pointed at by errlist is NULL.




 225 } zfs_ioc_vec_t;
 226 
 227 /* This array is indexed by zfs_userquota_prop_t */
 228 static const char *userquota_perms[] = {
 229         ZFS_DELEG_PERM_USERUSED,
 230         ZFS_DELEG_PERM_USERQUOTA,
 231         ZFS_DELEG_PERM_GROUPUSED,
 232         ZFS_DELEG_PERM_GROUPQUOTA,
 233 };
 234 
 235 static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
 236 static int zfs_check_settable(const char *name, nvpair_t *property,
 237     cred_t *cr);
 238 static int zfs_check_clearable(char *dataset, nvlist_t *props,
 239     nvlist_t **errors);
 240 static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
 241     boolean_t *);
 242 int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
 243 static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
 244 
 245 static int zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature);
 246 
 247 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
 248 void
 249 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
 250 {
 251         const char *newfile;
 252         char buf[512];
 253         va_list adx;
 254 
 255         /*
 256          * Get rid of annoying "../common/" prefix to filename.
 257          */
 258         newfile = strrchr(file, '/');
 259         if (newfile != NULL) {
 260                 newfile = newfile + 1; /* Get rid of leading / */
 261         } else {
 262                 newfile = file;
 263         }
 264 
 265         va_start(adx, fmt);


2365 
2366                 if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
2367                         break;
2368 
2369                 err = zfs_set_version(zfsvfs, intval);
2370                 zfsvfs_rele(zfsvfs, FTAG);
2371 
2372                 if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
2373                         zfs_cmd_t *zc;
2374 
2375                         zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
2376                         (void) strcpy(zc->zc_name, dsname);
2377                         (void) zfs_ioc_userspace_upgrade(zc);
2378                         kmem_free(zc, sizeof (zfs_cmd_t));
2379                 }
2380                 break;
2381         }
2382         case ZFS_PROP_COMPRESSION:
2383         {
2384                 if (intval == ZIO_COMPRESS_LZ4) {


2385                         spa_t *spa;
2386 
2387                         if ((err = spa_open(dsname, &spa, FTAG)) != 0)
2388                                 return (err);
2389 
2390                         /*
2391                          * Setting the LZ4 compression algorithm activates
2392                          * the feature.
2393                          */
2394                         if (!spa_feature_is_active(spa,
2395                             SPA_FEATURE_LZ4_COMPRESS)) {
2396                                 if ((err = zfs_prop_activate_feature(spa,
2397                                     SPA_FEATURE_LZ4_COMPRESS)) != 0) {
2398                                         spa_close(spa, FTAG);
2399                                         return (err);
2400                                 }
2401                         }
2402 
2403                         spa_close(spa, FTAG);
2404                 }
2405                 /*
2406                  * We still want the default set action to be performed in the
2407                  * caller, we only performed zfeature settings here.
2408                  */
2409                 err = -1;
2410                 break;
2411         }
2412 
2413         default:
2414                 err = -1;
2415         }
2416 
2417         return (err);


3645                 /*
3646                  * If the user specified gzip compression, make sure
3647                  * the SPA supports it. We ignore any errors here since
3648                  * we'll catch them later.
3649                  */
3650                 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
3651                     nvpair_value_uint64(pair, &intval) == 0) {
3652                         if (intval >= ZIO_COMPRESS_GZIP_1 &&
3653                             intval <= ZIO_COMPRESS_GZIP_9 &&
3654                             zfs_earlier_version(dsname,
3655                             SPA_VERSION_GZIP_COMPRESSION)) {
3656                                 return (SET_ERROR(ENOTSUP));
3657                         }
3658 
3659                         if (intval == ZIO_COMPRESS_ZLE &&
3660                             zfs_earlier_version(dsname,
3661                             SPA_VERSION_ZLE_COMPRESSION))
3662                                 return (SET_ERROR(ENOTSUP));
3663 
3664                         if (intval == ZIO_COMPRESS_LZ4) {



3665                                 spa_t *spa;
3666 
3667                                 if ((err = spa_open(dsname, &spa, FTAG)) != 0)
3668                                         return (err);
3669 
3670                                 if (!spa_feature_is_enabled(spa,
3671                                     SPA_FEATURE_LZ4_COMPRESS)) {
3672                                         spa_close(spa, FTAG);
3673                                         return (SET_ERROR(ENOTSUP));
3674                                 }
3675                                 spa_close(spa, FTAG);
3676                         }
3677 
3678                         /*
3679                          * If this is a bootable dataset then
3680                          * verify that the compression algorithm
3681                          * is supported for booting. We must return
3682                          * something other than ENOTSUP since it
3683                          * implies a downrev pool version.
3684                          */
3685                         if (zfs_is_bootfs(dsname) &&
3686                             !BOOTFS_COMPRESS_VALID(intval)) {
3687                                 return (SET_ERROR(ERANGE));
3688                         }
3689                 }
3690                 break;
3691 


3709                     nvpair_value_uint64(pair, &intval) == 0) {
3710                         if (intval == ZFS_ACL_PASSTHROUGH_X &&
3711                             zfs_earlier_version(dsname,
3712                             SPA_VERSION_PASSTHROUGH_X))
3713                                 return (SET_ERROR(ENOTSUP));
3714                 }
3715                 break;
3716         }
3717 
3718         return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
3719 }
3720 
3721 /*
3722  * Checks for a race condition to make sure we don't increment a feature flag
3723  * multiple times.
3724  */
3725 static int
3726 zfs_prop_activate_feature_check(void *arg, dmu_tx_t *tx)
3727 {
3728         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
3729         spa_feature_t *featurep = arg;
3730 
3731         if (!spa_feature_is_active(spa, *featurep))
3732                 return (0);
3733         else
3734                 return (SET_ERROR(EBUSY));
3735 }
3736 
3737 /*
3738  * The callback invoked on feature activation in the sync task caused by
3739  * zfs_prop_activate_feature.
3740  */
3741 static void
3742 zfs_prop_activate_feature_sync(void *arg, dmu_tx_t *tx)
3743 {
3744         spa_t *spa = dmu_tx_pool(tx)->dp_spa;
3745         spa_feature_t *featurep = arg;
3746 
3747         spa_feature_incr(spa, *featurep, tx);
3748 }
3749 
3750 /*
3751  * Activates a feature on a pool in response to a property setting. This
3752  * creates a new sync task which modifies the pool to reflect the feature
3753  * as being active.
3754  */
3755 static int
3756 zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature)
3757 {
3758         int err;
3759 
3760         /* EBUSY here indicates that the feature is already active */
3761         err = dsl_sync_task(spa_name(spa),
3762             zfs_prop_activate_feature_check, zfs_prop_activate_feature_sync,
3763             &feature, 2);
3764 
3765         if (err != 0 && err != EBUSY)
3766                 return (err);
3767         else
3768                 return (0);
3769 }
3770 
3771 /*
3772  * Removes properties from the given props list that fail permission checks
3773  * needed to clear them and to restore them in case of a receive error. For each
3774  * property, make sure we have both set and inherit permissions.
3775  *
3776  * Returns the first error encountered if any permission checks fail. If the
3777  * caller provides a non-NULL errlist, it also gives the complete list of names
3778  * of all the properties that failed a permission check along with the
3779  * corresponding error numbers. The caller is responsible for freeing the
3780  * returned errlist.
3781  *
3782  * If every property checks out successfully, zero is returned and the list
3783  * pointed at by errlist is NULL.