Skip to content

Commit 82f6f6e

Browse files
Joe Steinbehlendorf
authored andcommitted
Illumos 6298 - zfs_create_008_neg and zpool_create_023_neg
6298 zfs_create_008_neg and zpool_create_023_neg need to be updated for large block support Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: John Kennedy <john.kennedy@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> References: https://www.illumos.org/issues/6298 illumos/illumos-gate@e9316f7 Ported-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #4217
1 parent 59d4c71 commit 82f6f6e

File tree

4 files changed

+59
-24
lines changed

4 files changed

+59
-24
lines changed

cmd/zfs/zfs_main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,6 @@ zfs_do_create(int argc, char **argv)
849849
goto error;
850850
spa_version = zpool_get_prop_int(zpool_handle,
851851
ZPOOL_PROP_VERSION, NULL);
852-
zpool_close(zpool_handle);
853852
if (spa_version >= SPA_VERSION_REFRESERVATION)
854853
resv_prop = ZFS_PROP_REFRESERVATION;
855854
else
@@ -858,8 +857,11 @@ zfs_do_create(int argc, char **argv)
858857
(void) snprintf(msg, sizeof (msg),
859858
gettext("cannot create '%s'"), argv[0]);
860859
if (props && (real_props = zfs_valid_proplist(g_zfs, type,
861-
props, 0, NULL, msg)) == NULL)
860+
props, 0, NULL, zpool_handle, msg)) == NULL) {
861+
zpool_close(zpool_handle);
862862
goto error;
863+
}
864+
zpool_close(zpool_handle);
863865

864866
volsize = zvol_volsize_to_reservation(volsize, real_props);
865867
nvlist_free(real_props);

include/libzfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
/*
2323
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24-
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
24+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2525
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
2626
* Copyright (c) 2013 Steven Hartland. All rights reserved.
2727
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
@@ -448,7 +448,7 @@ extern const char *zfs_prop_column_name(zfs_prop_t);
448448
extern boolean_t zfs_prop_align_right(zfs_prop_t);
449449

450450
extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
451-
nvlist_t *, uint64_t, zfs_handle_t *, const char *);
451+
nvlist_t *, uint64_t, zfs_handle_t *, zpool_handle_t *, const char *);
452452

453453
extern const char *zfs_prop_to_name(zfs_prop_t);
454454
extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);

lib/libzfs/libzfs_dataset.c

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
/*
2323
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2424
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
25-
* Copyright (c) 2013 by Delphix. All rights reserved.
25+
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
2626
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
2727
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
2828
* Copyright (c) 2013 Martin Matuska. All rights reserved.
@@ -865,7 +865,8 @@ zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
865865
*/
866866
nvlist_t *
867867
zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
868-
uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
868+
uint64_t zoned, zfs_handle_t *zhp, zpool_handle_t *zpool_hdl,
869+
const char *errbuf)
869870
{
870871
nvpair_t *elem;
871872
uint64_t intval;
@@ -1061,8 +1062,8 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
10611062
int maxbs = SPA_MAXBLOCKSIZE;
10621063
char buf[64];
10631064

1064-
if (zhp != NULL) {
1065-
maxbs = zpool_get_prop_int(zhp->zpool_hdl,
1065+
if (zpool_hdl != NULL) {
1066+
maxbs = zpool_get_prop_int(zpool_hdl,
10661067
ZPOOL_PROP_MAXBLOCKSIZE, NULL);
10671068
}
10681069
/*
@@ -1581,7 +1582,8 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
15811582
zhp->zfs_name);
15821583

15831584
if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
1584-
zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
1585+
zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, zhp->zpool_hdl,
1586+
errbuf)) == NULL)
15851587
goto error;
15861588

15871589
/*
@@ -3241,9 +3243,23 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
32413243
else
32423244
ost = DMU_OST_ZFS;
32433245

3246+
/* open zpool handle for prop validation */
3247+
char pool_path[MAXNAMELEN];
3248+
(void) strlcpy(pool_path, path, sizeof (pool_path));
3249+
3250+
/* truncate pool_path at first slash */
3251+
char *p = strchr(pool_path, '/');
3252+
if (p != NULL)
3253+
*p = '\0';
3254+
3255+
zpool_handle_t *zpool_handle = zpool_open(hdl, pool_path);
3256+
32443257
if (props && (props = zfs_valid_proplist(hdl, type, props,
3245-
zoned, NULL, errbuf)) == 0)
3258+
zoned, NULL, zpool_handle, errbuf)) == 0) {
3259+
zpool_close(zpool_handle);
32463260
return (-1);
3261+
}
3262+
zpool_close(zpool_handle);
32473263

32483264
if (type == ZFS_TYPE_VOLUME) {
32493265
/*
@@ -3298,8 +3314,6 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
32983314
/* check for failure */
32993315
if (ret != 0) {
33003316
char parent[ZFS_MAXNAMELEN];
3301-
char buf[64];
3302-
33033317
(void) parent_name(path, parent, sizeof (parent));
33043318

33053319
switch (errno) {
@@ -3313,14 +3327,6 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
33133327
"parent '%s' is not a filesystem"), parent);
33143328
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
33153329

3316-
case EDOM:
3317-
zfs_nicenum(SPA_MAXBLOCKSIZE, buf, sizeof (buf));
3318-
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3319-
"volume block size must be power of 2 from "
3320-
"512B to %s"), buf);
3321-
3322-
return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3323-
33243330
case ENOTSUP:
33253331
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
33263332
"pool must be upgraded to set this "
@@ -3516,7 +3522,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
35163522
type = ZFS_TYPE_FILESYSTEM;
35173523
}
35183524
if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3519-
zhp, errbuf)) == NULL)
3525+
zhp, zhp->zpool_hdl, errbuf)) == NULL)
35203526
return (-1);
35213527
}
35223528

@@ -3660,11 +3666,23 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
36603666
}
36613667
}
36623668

3669+
/*
3670+
* get pool handle for prop validation. assumes all snaps are in the
3671+
* same pool, as does lzc_snapshot (below).
3672+
*/
3673+
char pool[MAXNAMELEN];
3674+
elem = nvlist_next_nvpair(snaps, NULL);
3675+
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
3676+
pool[strcspn(pool, "/@")] = '\0';
3677+
zpool_handle_t *zpool_hdl = zpool_open(hdl, pool);
3678+
36633679
if (props != NULL &&
36643680
(props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3665-
props, B_FALSE, NULL, errbuf)) == NULL) {
3681+
props, B_FALSE, NULL, zpool_hdl, errbuf)) == NULL) {
3682+
zpool_close(zpool_hdl);
36663683
return (-1);
36673684
}
3685+
zpool_close(zpool_hdl);
36683686

36693687
ret = lzc_snapshot(snaps, props, &errors);
36703688

lib/libzfs/libzfs_pool.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,8 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
12151215
zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
12161216
strcmp(zonestr, "on") == 0);
12171217

1218-
if ((zc_fsprops = zfs_valid_proplist(hdl,
1219-
ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
1218+
if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM,
1219+
fsprops, zoned, NULL, NULL, msg)) == NULL) {
12201220
goto create_failed;
12211221
}
12221222
if (!zc_props &&
@@ -1255,6 +1255,21 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
12551255
"lvm device"));
12561256
return (zfs_error(hdl, EZFS_BADDEV, msg));
12571257

1258+
case ERANGE:
1259+
/*
1260+
* This happens if the record size is smaller or larger
1261+
* than the allowed size range, or not a power of 2.
1262+
*
1263+
* NOTE: although zfs_valid_proplist is called earlier,
1264+
* this case may have slipped through since the
1265+
* pool does not exist yet and it is therefore
1266+
* impossible to read properties e.g. max blocksize
1267+
* from the pool.
1268+
*/
1269+
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1270+
"record size invalid"));
1271+
return (zfs_error(hdl, EZFS_BADPROP, msg));
1272+
12581273
case EOVERFLOW:
12591274
/*
12601275
* This occurs when one of the devices is below

0 commit comments

Comments
 (0)