]> granicus.if.org Git - zfs/commitdiff
Illumos #3699, #3739
authorMartin Matuska <mm@FreeBSD.org>
Thu, 23 May 2013 17:07:25 +0000 (13:07 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 4 Nov 2013 18:55:25 +0000 (10:55 -0800)
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>
Approved by: Dan McDonald <danmcd@nexenta.com>

References:
  https://www.illumos.org/issues/3699
  https://www.illumos.org/issues/3739
  illumos/illumos-gate@013023d4ed2f6d0cf75380ec686a4aac392b4e43

Ported-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #1775

lib/libzfs/libzfs_dataset.c
module/zfs/dsl_dir.c
module/zfs/dsl_prop.c

index e2808638ef3412b403e3c3106b3eda65282de22b..be23382b54e225954c30568a031d4de9c66e20ec 100644 (file)
@@ -25,6 +25,7 @@
  * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
  * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska. All rights reserved.
  */
 
 #include <ctype.h>
@@ -4455,6 +4456,20 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
        ha.tag = tag;
        ha.recursive = recursive;
        (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
+
+       if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+               fnvlist_free(ha.nvl);
+               ret = ENOENT;
+               if (!enoent_ok) {
+                       (void) snprintf(errbuf, sizeof (errbuf),
+                           dgettext(TEXT_DOMAIN,
+                           "cannot hold snapshot '%s@%s'"),
+                           zhp->zfs_name, snapname);
+                       (void) zfs_standard_error(hdl, ret, errbuf);
+               }
+               return (ret);
+       }
+
        ret = lzc_hold(ha.nvl, cleanup_fd, &errors);
        fnvlist_free(ha.nvl);
 
@@ -4556,12 +4571,25 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
        nvlist_t *errors;
        nvpair_t *elem;
        libzfs_handle_t *hdl = zhp->zfs_hdl;
+       char errbuf[1024];
 
        ha.nvl = fnvlist_alloc();
        ha.snapname = snapname;
        ha.tag = tag;
        ha.recursive = recursive;
        (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
+
+       if (nvlist_next_nvpair(ha.nvl, NULL) == NULL) {
+               fnvlist_free(ha.nvl);
+               ret = ENOENT;
+               (void) snprintf(errbuf, sizeof (errbuf),
+                   dgettext(TEXT_DOMAIN,
+                   "cannot release hold from snapshot '%s@%s'"),
+                   zhp->zfs_name, snapname);
+               (void) zfs_standard_error(hdl, ret, errbuf);
+               return (ret);
+       }
+
        ret = lzc_release(ha.nvl, &errors);
        fnvlist_free(ha.nvl);
 
@@ -4570,8 +4598,6 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
 
        if (nvlist_next_nvpair(errors, NULL) == NULL) {
                /* no hold-specific errors */
-               char errbuf[1024];
-
                (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
                    "cannot release"));
                switch (errno) {
@@ -4588,8 +4614,6 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
        for (elem = nvlist_next_nvpair(errors, NULL);
            elem != NULL;
            elem = nvlist_next_nvpair(errors, elem)) {
-               char errbuf[1024];
-
                (void) snprintf(errbuf, sizeof (errbuf),
                    dgettext(TEXT_DOMAIN,
                    "cannot release hold from snapshot '%s'"),
index 51a78f9024d8097afd76da3e9368add37f0aa8d4..c1b5182415134a51a7c24e6f82cc5495fac502df 100644 (file)
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska. All rights reserved.
  */
 
 #include <sys/dmu.h>
@@ -974,12 +975,18 @@ dsl_dir_set_quota_sync(void *arg, dmu_tx_t *tx)
 
        VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
 
-       dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_QUOTA),
-           ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
-           &ddsqra->ddsqra_value, tx);
+       if (spa_version(dp->dp_spa) >= SPA_VERSION_RECVD_PROPS) {
+               dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_QUOTA),
+                   ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
+                   &ddsqra->ddsqra_value, tx);
 
-       VERIFY0(dsl_prop_get_int_ds(ds,
-           zfs_prop_to_name(ZFS_PROP_QUOTA), &newval));
+               VERIFY0(dsl_prop_get_int_ds(ds,
+                   zfs_prop_to_name(ZFS_PROP_QUOTA), &newval));
+       } else {
+               newval = ddsqra->ddsqra_value;
+               spa_history_log_internal_ds(ds, "set", tx, "%s=%lld",
+                   zfs_prop_to_name(ZFS_PROP_QUOTA), (longlong_t)newval);
+       }
 
        dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
        mutex_enter(&ds->ds_dir->dd_lock);
@@ -1089,13 +1096,21 @@ dsl_dir_set_reservation_sync(void *arg, dmu_tx_t *tx)
 
        VERIFY0(dsl_dataset_hold(dp, ddsqra->ddsqra_name, FTAG, &ds));
 
-       dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_RESERVATION),
-           ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
-           &ddsqra->ddsqra_value, tx);
-
-       VERIFY0(dsl_prop_get_int_ds(ds,
-           zfs_prop_to_name(ZFS_PROP_RESERVATION), &newval));
+       if (spa_version(dp->dp_spa) >= SPA_VERSION_RECVD_PROPS) {
+               dsl_prop_set_sync_impl(ds,
+                   zfs_prop_to_name(ZFS_PROP_RESERVATION),
+                   ddsqra->ddsqra_source, sizeof (ddsqra->ddsqra_value), 1,
+                   &ddsqra->ddsqra_value, tx);
  
+               VERIFY0(dsl_prop_get_int_ds(ds,
+                   zfs_prop_to_name(ZFS_PROP_RESERVATION), &newval));
+       } else {
+               newval = ddsqra->ddsqra_value;
+               spa_history_log_internal_ds(ds, "set", tx, "%s=%lld",
+                   zfs_prop_to_name(ZFS_PROP_RESERVATION),
+                   (longlong_t)newval);
+       }
+
        dsl_dir_set_reservation_sync_impl(ds->ds_dir, newval, tx);
        dsl_dataset_rele(ds, FTAG);
  }
index 62ca26ddd9897d2afd63095ba89f5e9b8c4f3e1c..cfd8dd433e2fc2245f304e6b1159bf044db57468 100644 (file)
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -557,10 +558,6 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
        }
 
        if (version < SPA_VERSION_RECVD_PROPS) {
-               zfs_prop_t prop = zfs_name_to_prop(propname);
-               if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION)
-                       return;
-
                if (source & ZPROP_SRC_NONE)
                        source = ZPROP_SRC_NONE;
                else if (source & ZPROP_SRC_RECEIVED)