--- old/usr/src/cmd/zfs/zfs_main.c	Tue Oct 15 13:59:52 2013
+++ new/usr/src/cmd/zfs/zfs_main.c	Tue Oct 15 13:59:52 2013
@@ -782,6 +782,8 @@
 		zfs_prop_t resv_prop;
 		char *strval;
 		char msg[1024];
+		uint64_t volblocksize;
+		int ncopies;
 
 		if (p = strchr(argv[0], '/'))
 			*p = '\0';
@@ -804,7 +806,18 @@
 		    props, 0, NULL, msg)) == NULL)
 			goto error;
 
-		volsize = zvol_volsize_to_reservation(volsize, real_props);
+		if (nvlist_lookup_string(real_props,
+		    zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
+			ncopies = atoi(strval);
+		else
+			ncopies = 1;
+		if (nvlist_lookup_uint64(real_props,
+		    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+		    &volblocksize) != 0)
+			volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
+
+		volsize = zvol_volsize_to_reservation_impl(volsize,
+		    volblocksize, ncopies);
 		nvlist_free(real_props);
 
 		if (nvlist_lookup_string(props, zfs_prop_to_name(resv_prop),
--- old/usr/src/lib/libzfs/common/libzfs.h	Tue Oct 15 13:59:52 2013
+++ new/usr/src/lib/libzfs/common/libzfs.h	Tue Oct 15 13:59:52 2013
@@ -25,6 +25,7 @@
  * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright 2013 DEY Storage Systems, Inc.
  */
 
 #ifndef	_LIBZFS_H
@@ -600,6 +601,8 @@
 extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t);
 extern int zfs_get_holds(zfs_handle_t *, nvlist_t **);
 extern uint64_t zvol_volsize_to_reservation(uint64_t, nvlist_t *);
+extern uint64_t zvol_volsize_to_reservation_impl(uint64_t volsize,
+    uint64_t volblocksize, int ncopies);
 
 typedef int (*zfs_userspace_cb_t)(void *arg, const char *domain,
     uid_t rid, uint64_t space);
--- old/usr/src/lib/libzfs/common/libzfs_dataset.c	Tue Oct 15 13:59:52 2013
+++ new/usr/src/lib/libzfs/common/libzfs_dataset.c	Tue Oct 15 13:59:52 2013
@@ -22,7 +22,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
- * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
+ * Copyright 2013 DEY Storage Systems, Inc.
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2013 Martin Matuska. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
@@ -1209,12 +1209,15 @@
 			    ZFS_PROP_VOLSIZE);
 			uint64_t blocksize = zfs_prop_get_int(zhp,
 			    ZFS_PROP_VOLBLOCKSIZE);
+			int ncopies = zfs_prop_get_int(zhp, ZFS_PROP_COPIES);
 			char buf[64];
 
 			switch (prop) {
 			case ZFS_PROP_RESERVATION:
 			case ZFS_PROP_REFRESERVATION:
-				if (intval > volsize) {
+				if (intval >
+				    zvol_volsize_to_reservation_impl(volsize,
+				    blocksize, ncopies)) {
 					zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 					    "'%s' is greater than current "
 					    "volume size"), propname);
@@ -1285,7 +1288,8 @@
 	uint64_t old_reservation;
 	uint64_t new_reservation;
 	zfs_prop_t resv_prop;
-	nvlist_t *props;
+	uint64_t volblocksize;
+	int ncopies;
 
 	/*
 	 * If this is an existing volume, and someone is setting the volsize,
@@ -1295,24 +1299,18 @@
 	if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
 		return (-1);
 	old_reservation = zfs_prop_get_int(zhp, resv_prop);
+	volblocksize = zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE);
+	ncopies = zfs_prop_get_int(zhp, ZFS_PROP_COPIES);
 
-	props = fnvlist_alloc();
-	fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
-	    zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
-
-	if ((zvol_volsize_to_reservation(old_volsize, props) !=
-	    old_reservation) || nvlist_exists(nvl,
-	    zfs_prop_to_name(resv_prop))) {
-		fnvlist_free(props);
+	if ((zvol_volsize_to_reservation_impl(old_volsize, volblocksize,
+	    ncopies) != old_reservation) || nvlist_exists(nvl,
+	    zfs_prop_to_name(resv_prop)))
 		return (0);
-	}
 	if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
-	    &new_volsize) != 0) {
-		fnvlist_free(props);
+	    &new_volsize) != 0)
 		return (-1);
-	}
-	new_reservation = zvol_volsize_to_reservation(new_volsize, props);
-	fnvlist_free(props);
+	new_reservation = zvol_volsize_to_reservation_impl(new_volsize,
+	    volblocksize, ncopies);
 
 	if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
 	    new_reservation) != 0) {
@@ -4460,7 +4458,8 @@
 }
 
 /*
- * Convert the zvol's volume size to an appropriate reservation.
+ * Convert the zvol's volume size to an appropriate reservation. This is a
+ * convenience front-end to zvol_volsize_to_reservation_impl.
  * Note: If this routine is updated, it is necessary to update the ZFS test
  * suite's shell version in reservation.kshlib.
  */
@@ -4467,8 +4466,7 @@
 uint64_t
 zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
 {
-	uint64_t numdb;
-	uint64_t nblocks, volblocksize;
+	uint64_t volblocksize;
 	int ncopies;
 	char *strval;
 
@@ -4481,6 +4479,22 @@
 	    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
 	    &volblocksize) != 0)
 		volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
+
+	return (zvol_volsize_to_reservation_impl(volsize, volblocksize,
+	    ncopies));
+}
+
+/*
+ * Computes the required reservation to completely contain all blocks of a
+ * zvol at a given volsize.
+ */
+uint64_t
+zvol_volsize_to_reservation_impl(uint64_t volsize, uint64_t volblocksize,
+    int ncopies)
+{
+	uint64_t numdb;
+	uint64_t nblocks;
+
 	nblocks = volsize/volblocksize;
 	/* start with metadnode L0-L6 */
 	numdb = 7;
--- old/usr/src/lib/libzfs/common/mapfile-vers	Tue Oct 15 13:59:52 2013
+++ new/usr/src/lib/libzfs/common/mapfile-vers	Tue Oct 15 13:59:52 2013
@@ -242,6 +242,7 @@
 	zprop_width;
 	zvol_check_dump_config;
 	zvol_volsize_to_reservation;
+	zvol_volsize_to_reservation_impl;
     local:
 	*;
 };
