Print this page
3699 zfs hold or release of a non-existent snapshot does not output error
3739 cannot set zfs quota or reservation on pool version < 22
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Eric Shrock <eric.schrock@delphix.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.

  24  */
  25 
  26 #include <sys/dmu.h>
  27 #include <sys/dmu_objset.h>
  28 #include <sys/dmu_tx.h>
  29 #include <sys/dsl_dataset.h>
  30 #include <sys/dsl_dir.h>
  31 #include <sys/dsl_prop.h>
  32 #include <sys/dsl_synctask.h>
  33 #include <sys/dsl_deleg.h>
  34 #include <sys/spa.h>
  35 #include <sys/metaslab.h>
  36 #include <sys/zap.h>
  37 #include <sys/zio.h>
  38 #include <sys/arc.h>
  39 #include <sys/sunddi.h>
  40 #include "zfs_namecheck.h"
  41 
  42 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
  43 


 950         if ((dmu_tx_is_syncing(tx) || towrite == 0) &&
 951             (newval < ds->ds_dir->dd_phys->dd_reserved ||
 952             newval < ds->ds_dir->dd_phys->dd_used_bytes + towrite)) {
 953                 error = SET_ERROR(ENOSPC);
 954         }
 955         mutex_exit(&ds->ds_dir->dd_lock);
 956         dsl_dataset_rele(ds, FTAG);
 957         return (error);
 958 }
 959 
 960 static void
 961 dsl_dir_set_quota_sync(void *arg, dmu_tx_t *tx)
 962 {
 963         dsl_dir_set_qr_arg_t *ddsqra = arg;
 964         dsl_pool_t *dp = dmu_tx_pool(tx);
 965         dsl_dataset_t *ds;
 966         uint64_t newval;
 967 
 968         VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
 969 

 970         dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_QUOTA),
 971             ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
 972             &ddsqra->ddsqra_value, tx);
 973 
 974         VERIFY0(dsl_prop_get_int_ds(ds,
 975             zfs_prop_to_name(ZFS_PROP_QUOTA), &newval));





 976 
 977         dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
 978         mutex_enter(&ds->ds_dir->dd_lock);
 979         ds->ds_dir->dd_phys->dd_quota = newval;
 980         mutex_exit(&ds->ds_dir->dd_lock);
 981         dsl_dataset_rele(ds, FTAG);
 982 }
 983 
 984 int
 985 dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota)
 986 {
 987         dsl_dir_set_qr_arg_t ddsqra;
 988 
 989         ddsqra.ddsqra_name = ddname;
 990         ddsqra.ddsqra_source = source;
 991         ddsqra.ddsqra_value = quota;
 992 
 993         return (dsl_sync_task(ddname, dsl_dir_set_quota_check,
 994             dsl_dir_set_quota_sync, &ddsqra, 0));
 995 }


1066 
1067         if (dd->dd_parent != NULL) {
1068                 /* Roll up this additional usage into our ancestors */
1069                 dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV,
1070                     delta, 0, 0, tx);
1071         }
1072         mutex_exit(&dd->dd_lock);
1073 }
1074 
1075 
1076 static void
1077 dsl_dir_set_reservation_sync(void *arg, dmu_tx_t *tx)
1078 {
1079         dsl_dir_set_qr_arg_t *ddsqra = arg;
1080         dsl_pool_t *dp = dmu_tx_pool(tx);
1081         dsl_dataset_t *ds;
1082         uint64_t newval;
1083 
1084         VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
1085 
1086         dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_RESERVATION),


1087             ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
1088             &ddsqra->ddsqra_value, tx);
1089 
1090         VERIFY0(dsl_prop_get_int_ds(ds,
1091             zfs_prop_to_name(ZFS_PROP_RESERVATION), &newval));






1092 
1093         dsl_dir_set_reservation_sync_impl(ds->ds_dir, newval, tx);
1094         dsl_dataset_rele(ds, FTAG);
1095 }
1096 
1097 int
1098 dsl_dir_set_reservation(const char *ddname, zprop_source_t source,
1099     uint64_t reservation)
1100 {
1101         dsl_dir_set_qr_arg_t ddsqra;
1102 
1103         ddsqra.ddsqra_name = ddname;
1104         ddsqra.ddsqra_source = source;
1105         ddsqra.ddsqra_value = reservation;
1106 
1107         return (dsl_sync_task(ddname, dsl_dir_set_reservation_check,
1108             dsl_dir_set_reservation_sync, &ddsqra, 0));
1109 }
1110 
1111 static dsl_dir_t *




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.
  24  * Copyright (c) 2013 Martin Matuska. All rights reserved.
  25  */
  26 
  27 #include <sys/dmu.h>
  28 #include <sys/dmu_objset.h>
  29 #include <sys/dmu_tx.h>
  30 #include <sys/dsl_dataset.h>
  31 #include <sys/dsl_dir.h>
  32 #include <sys/dsl_prop.h>
  33 #include <sys/dsl_synctask.h>
  34 #include <sys/dsl_deleg.h>
  35 #include <sys/spa.h>
  36 #include <sys/metaslab.h>
  37 #include <sys/zap.h>
  38 #include <sys/zio.h>
  39 #include <sys/arc.h>
  40 #include <sys/sunddi.h>
  41 #include "zfs_namecheck.h"
  42 
  43 static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd);
  44 


 951         if ((dmu_tx_is_syncing(tx) || towrite == 0) &&
 952             (newval < ds->ds_dir->dd_phys->dd_reserved ||
 953             newval < ds->ds_dir->dd_phys->dd_used_bytes + towrite)) {
 954                 error = SET_ERROR(ENOSPC);
 955         }
 956         mutex_exit(&ds->ds_dir->dd_lock);
 957         dsl_dataset_rele(ds, FTAG);
 958         return (error);
 959 }
 960 
 961 static void
 962 dsl_dir_set_quota_sync(void *arg, dmu_tx_t *tx)
 963 {
 964         dsl_dir_set_qr_arg_t *ddsqra = arg;
 965         dsl_pool_t *dp = dmu_tx_pool(tx);
 966         dsl_dataset_t *ds;
 967         uint64_t newval;
 968 
 969         VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
 970 
 971         if (spa_version(dp->dp_spa) >= SPA_VERSION_RECVD_PROPS) {
 972                 dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_QUOTA),
 973                     ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
 974                     &ddsqra->ddsqra_value, tx);
 975 
 976                 VERIFY0(dsl_prop_get_int_ds(ds,
 977                     zfs_prop_to_name(ZFS_PROP_QUOTA), &newval));
 978         } else {
 979                 newval = ddsqra->ddsqra_value;
 980                 spa_history_log_internal_ds(ds, "set", tx, "%s=%lld",
 981                     zfs_prop_to_name(ZFS_PROP_QUOTA), (longlong_t)newval);
 982         }
 983 
 984         dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
 985         mutex_enter(&ds->ds_dir->dd_lock);
 986         ds->ds_dir->dd_phys->dd_quota = newval;
 987         mutex_exit(&ds->ds_dir->dd_lock);
 988         dsl_dataset_rele(ds, FTAG);
 989 }
 990 
 991 int
 992 dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota)
 993 {
 994         dsl_dir_set_qr_arg_t ddsqra;
 995 
 996         ddsqra.ddsqra_name = ddname;
 997         ddsqra.ddsqra_source = source;
 998         ddsqra.ddsqra_value = quota;
 999 
1000         return (dsl_sync_task(ddname, dsl_dir_set_quota_check,
1001             dsl_dir_set_quota_sync, &ddsqra, 0));
1002 }


1073 
1074         if (dd->dd_parent != NULL) {
1075                 /* Roll up this additional usage into our ancestors */
1076                 dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV,
1077                     delta, 0, 0, tx);
1078         }
1079         mutex_exit(&dd->dd_lock);
1080 }
1081 
1082 
1083 static void
1084 dsl_dir_set_reservation_sync(void *arg, dmu_tx_t *tx)
1085 {
1086         dsl_dir_set_qr_arg_t *ddsqra = arg;
1087         dsl_pool_t *dp = dmu_tx_pool(tx);
1088         dsl_dataset_t *ds;
1089         uint64_t newval;
1090 
1091         VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
1092 
1093         if (spa_version(dp->dp_spa) >= SPA_VERSION_RECVD_PROPS) {
1094                 dsl_prop_set_sync_impl(ds,
1095                     zfs_prop_to_name(ZFS_PROP_RESERVATION),
1096                     ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
1097                     &ddsqra->ddsqra_value, tx);
1098 
1099                 VERIFY0(dsl_prop_get_int_ds(ds,
1100                     zfs_prop_to_name(ZFS_PROP_RESERVATION), &newval));
1101         } else {
1102                 newval = ddsqra->ddsqra_value;
1103                 spa_history_log_internal_ds(ds, "set", tx, "%s=%lld",
1104                     zfs_prop_to_name(ZFS_PROP_RESERVATION),
1105                     (longlong_t)newval);
1106         }
1107 
1108         dsl_dir_set_reservation_sync_impl(ds->ds_dir, newval, tx);
1109         dsl_dataset_rele(ds, FTAG);
1110 }
1111 
1112 int
1113 dsl_dir_set_reservation(const char *ddname, zprop_source_t source,
1114     uint64_t reservation)
1115 {
1116         dsl_dir_set_qr_arg_t ddsqra;
1117 
1118         ddsqra.ddsqra_name = ddname;
1119         ddsqra.ddsqra_source = source;
1120         ddsqra.ddsqra_value = reservation;
1121 
1122         return (dsl_sync_task(ddname, dsl_dir_set_reservation_check,
1123             dsl_dir_set_reservation_sync, &ddsqra, 0));
1124 }
1125 
1126 static dsl_dir_t *