#ifdef _KERNEL
extern int zvol_check_volsize(uint64_t volsize, uint64_t blocksize);
-extern int zvol_check_volblocksize(uint64_t volblocksize);
+extern int zvol_check_volblocksize(const char *name, uint64_t volblocksize);
extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
extern boolean_t zvol_is_zvol(const char *);
extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
case ZFS_PROP_RECORDSIZE:
{
int maxbs = SPA_MAXBLOCKSIZE;
+ char buf[64];
+
if (zhp != NULL) {
maxbs = zpool_get_prop_int(zhp->zpool_hdl,
ZPOOL_PROP_MAXBLOCKSIZE, NULL);
*/
if (intval < SPA_MINBLOCKSIZE ||
intval > maxbs || !ISP2(intval)) {
+ zfs_nicenum(maxbs, buf, sizeof (buf));
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be power of 2 from 512B "
- "to %uKB"), propname, maxbs >> 10);
+ "to %s"), propname, buf);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
/* check for failure */
if (ret != 0) {
char parent[ZFS_MAXNAMELEN];
+ char buf[64];
+
(void) parent_name(path, parent, sizeof (parent));
switch (errno) {
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
case EDOM:
+ zfs_nicenum(SPA_MAXBLOCKSIZE, buf, sizeof (buf));
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"volume block size must be power of 2 from "
- "512B to %uKB"), zfs_max_recordsize >> 10);
+ "512B to %s"), buf);
return (zfs_error(hdl, EZFS_BADPROP, errbuf));
volblocksize = zfs_prop_default_numeric(
ZFS_PROP_VOLBLOCKSIZE);
- if ((error = zvol_check_volblocksize(
+ if ((error = zvol_check_volblocksize(fsname,
volblocksize)) != 0 ||
(error = zvol_check_volsize(volsize,
volblocksize)) != 0)
return (SET_ERROR(ENOTSUP));
break;
+ case ZFS_PROP_VOLBLOCKSIZE:
case ZFS_PROP_RECORDSIZE:
/* Record sizes above 128k need the feature to be enabled */
if (nvpair_value_uint64(pair, &intval) == 0 &&
#include <sys/dsl_dataset.h>
#include <sys/dsl_prop.h>
#include <sys/zap.h>
+#include <sys/zfeature.h>
#include <sys/zil_impl.h>
#include <sys/zio.h>
#include <sys/zfs_rlock.h>
* Sanity check volume block size.
*/
int
-zvol_check_volblocksize(uint64_t volblocksize)
+zvol_check_volblocksize(const char *name, uint64_t volblocksize)
{
+ /* Record sizes above 128k need the feature to be enabled */
+ if (volblocksize > SPA_OLD_MAXBLOCKSIZE) {
+ spa_t *spa;
+ int error;
+
+ if ((error = spa_open(name, &spa, FTAG)) != 0)
+ return (error);
+
+ if (!spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) {
+ spa_close(spa, FTAG);
+ return (SET_ERROR(ENOTSUP));
+ }
+
+ /*
+ * We don't allow setting the property above 1MB,
+ * unless the tunable has been changed.
+ */
+ if (volblocksize > zfs_max_recordsize)
+ return (SET_ERROR(EDOM));
+
+ spa_close(spa, FTAG);
+ }
+
if (volblocksize < SPA_MINBLOCKSIZE ||
volblocksize > SPA_MAXBLOCKSIZE ||
!ISP2(volblocksize))