Skip to content

Commit fb2b9c3

Browse files
committed
Relax special_small_blocks restrictions
special_small_blocks is applied to blocks after compression, so it makes no sense to demand its values to be power of 2. At most they could be multiple of 512, but that would still buy us nothing, so lets allow them be any within SPA_MAXBLOCKSIZE. Also special_small_blocks does not really need to depend on the set recordsize, enabled pool features or presence of special vdev. At worst in any of those cases it will just do nothing, so we should not complicate users lives by artificial limitations. While there, polish comments for recordsize and volblocksize. Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc.
1 parent dee62e0 commit fb2b9c3

File tree

12 files changed

+27
-180
lines changed

12 files changed

+27
-180
lines changed

include/sys/dmu_objset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ struct objset {
152152
* The largest zpl file block allowed in special class.
153153
* cached here instead of zfsvfs for easier access.
154154
*/
155-
int os_zpl_special_smallblock;
155+
uint64_t os_zpl_special_smallblock;
156156

157157
/*
158158
* Pointer is constant; the blkptr it points to is protected by

lib/libzfs/libzfs_dataset.c

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,6 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
10391039
nvlist_t *ret;
10401040
int chosen_normal = -1;
10411041
int chosen_utf = -1;
1042-
int set_maxbs = 0;
10431042

10441043
if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
10451044
(void) no_memory(hdl);
@@ -1258,46 +1257,20 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
12581257
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
12591258
goto error;
12601259
}
1261-
/* save the ZFS_PROP_RECORDSIZE during create op */
1262-
if (zpool_hdl == NULL && prop == ZFS_PROP_RECORDSIZE) {
1263-
set_maxbs = intval;
1264-
}
12651260
break;
12661261
}
12671262

12681263
case ZFS_PROP_SPECIAL_SMALL_BLOCKS:
12691264
{
1270-
int maxbs =
1271-
set_maxbs == 0 ? SPA_OLD_MAXBLOCKSIZE : set_maxbs;
1265+
int maxbs = SPA_MAXBLOCKSIZE;
12721266
char buf[64];
12731267

1274-
if (zpool_hdl != NULL) {
1275-
char state[64] = "";
1276-
1277-
maxbs = zpool_get_prop_int(zpool_hdl,
1278-
ZPOOL_PROP_MAXBLOCKSIZE, NULL);
1279-
1280-
/*
1281-
* Issue a warning but do not fail so that
1282-
* tests for settable properties succeed.
1283-
*/
1284-
if (zpool_prop_get_feature(zpool_hdl,
1285-
"feature@allocation_classes", state,
1286-
sizeof (state)) != 0 ||
1287-
strcmp(state, ZFS_FEATURE_ACTIVE) != 0) {
1288-
(void) fprintf(stderr, gettext(
1289-
"%s: property requires a special "
1290-
"device in the pool\n"), propname);
1291-
}
1292-
}
1293-
if (intval != 0 &&
1294-
(intval < SPA_MINBLOCKSIZE ||
1295-
intval > maxbs || !ISP2(intval))) {
1268+
if (intval > SPA_MAXBLOCKSIZE) {
12961269
zfs_nicebytes(maxbs, buf, sizeof (buf));
12971270
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1298-
"invalid '%s=%llu' property: must be zero "
1299-
"or a power of 2 from 512B to %s"),
1300-
propname, (unsigned long long)intval, buf);
1271+
"invalid '%s' property: must be between "
1272+
"zero and %s"),
1273+
propname, buf);
13011274
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
13021275
goto error;
13031276
}

lib/libzfs/libzfs_pool.c

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,30 +1421,6 @@ zpool_get_state(zpool_handle_t *zhp)
14211421
return (zhp->zpool_state);
14221422
}
14231423

1424-
/*
1425-
* Check if vdev list contains a special vdev
1426-
*/
1427-
static boolean_t
1428-
zpool_has_special_vdev(nvlist_t *nvroot)
1429-
{
1430-
nvlist_t **child;
1431-
uint_t children;
1432-
1433-
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child,
1434-
&children) == 0) {
1435-
for (uint_t c = 0; c < children; c++) {
1436-
const char *bias;
1437-
1438-
if (nvlist_lookup_string(child[c],
1439-
ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0 &&
1440-
strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) {
1441-
return (B_TRUE);
1442-
}
1443-
}
1444-
}
1445-
return (B_FALSE);
1446-
}
1447-
14481424
/*
14491425
* Check if vdev list contains a dRAID vdev
14501426
*/
@@ -1548,16 +1524,6 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
15481524
goto create_failed;
15491525
}
15501526

1551-
if (nvlist_exists(zc_fsprops,
1552-
zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)) &&
1553-
!zpool_has_special_vdev(nvroot)) {
1554-
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1555-
"%s property requires a special vdev"),
1556-
zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS));
1557-
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1558-
goto create_failed;
1559-
}
1560-
15611527
if (!zc_props &&
15621528
(nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
15631529
goto create_failed;

man/man7/zfsprops.7

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,16 @@ The
541541
.Sy blocksize
542542
cannot be changed once the volume has been written, so it should be set at
543543
volume creation time.
544-
The default
545-
.Sy blocksize
546-
for volumes is 16 KiB.
547-
Any power of 2 from 512 bytes to 128 KiB is valid.
544+
The size specified must be a power of two greater than or equal to
545+
.Ar 512 B
546+
and less than or equal to
547+
.Ar 128 KiB .
548+
If the
549+
.Sy large_blocks
550+
feature is enabled on the pool, the size may be up to
551+
.Ar 16 MiB .
552+
The default size is
553+
.Ar 16 KiB .
548554
.Pp
549555
This property can also be referred to by its shortened column name,
550556
.Sy volblock .
@@ -1285,7 +1291,9 @@ or zvol blocks into the special allocation class.
12851291
Blocks smaller than or equal to this
12861292
value will be assigned to the special allocation class while greater blocks
12871293
will be assigned to the regular class.
1288-
Valid values are zero or a power of two from 512 up to 1048576 (1 MiB).
1294+
Valid values are from 0 to maximum block size (
1295+
.Ar 16 MiB
1296+
).
12891297
The default size is 0 which means no small file or zvol blocks
12901298
will be allocated in the special class.
12911299
.Pp
@@ -1569,11 +1577,6 @@ See
15691577
.Xr zpool-features 7
15701578
for details on ZFS feature flags.
15711579
.Pp
1572-
However, blocks larger than
1573-
.Ar 1 MiB
1574-
can have an impact on i/o latency (e.g. tying up a spinning disk for
1575-
~300ms), and also potentially on the memory allocator.
1576-
.Pp
15771580
Note that maximum size is still limited by default to
15781581
.Ar 1 MiB
15791582
on x86_32, see

module/zcommon/zfs_prop.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ zfs_prop_init(void)
640640
"<1.00x or higher if compressed>", "REFRATIO", B_FALSE, sfeatures);
641641
zprop_register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize",
642642
ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME,
643-
ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK", B_FALSE,
643+
ZFS_TYPE_VOLUME, "512 to 16M, power of 2", "VOLBLOCK", B_FALSE,
644644
sfeatures);
645645
zprop_register_index(ZFS_PROP_VOLTHREADING, "volthreading",
646646
1, PROP_DEFAULT, ZFS_TYPE_VOLUME, "on | off", "zvol threading",
@@ -734,13 +734,12 @@ zfs_prop_init(void)
734734
/* inherit number properties */
735735
zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
736736
SPA_OLD_MAXBLOCKSIZE, PROP_INHERIT,
737-
ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE", B_FALSE,
738-
sfeatures);
737+
ZFS_TYPE_FILESYSTEM, "512 to 16M, power of 2",
738+
"RECSIZE", B_FALSE, sfeatures);
739739
zprop_register_number(ZFS_PROP_SPECIAL_SMALL_BLOCKS,
740740
"special_small_blocks", 0, PROP_INHERIT,
741-
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
742-
"zero or 512 to 1M, power of 2", "SPECIAL_SMALL_BLOCKS", B_FALSE,
743-
sfeatures);
741+
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "0 to 16M",
742+
"SPECIAL_SMALL_BLOCKS", B_FALSE, sfeatures);
744743

745744
/* hidden properties */
746745
zprop_register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,

module/zfs/dmu_objset.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,12 +345,6 @@ smallblk_changed_cb(void *arg, uint64_t newval)
345345
{
346346
objset_t *os = arg;
347347

348-
/*
349-
* Inheritance and range checking should have been done by now.
350-
*/
351-
ASSERT(newval <= SPA_MAXBLOCKSIZE);
352-
ASSERT(ISP2(newval));
353-
354348
os->os_zpl_special_smallblock = newval;
355349
}
356350

tests/runfiles/common.run

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ tests = ['alloc_class_001_pos', 'alloc_class_002_neg', 'alloc_class_003_pos',
3737
'alloc_class_004_pos', 'alloc_class_005_pos', 'alloc_class_006_pos',
3838
'alloc_class_007_pos', 'alloc_class_008_pos', 'alloc_class_009_pos',
3939
'alloc_class_010_pos', 'alloc_class_011_neg', 'alloc_class_012_pos',
40-
'alloc_class_013_pos', 'alloc_class_014_neg', 'alloc_class_015_pos',
41-
'alloc_class_016_pos']
40+
'alloc_class_013_pos', 'alloc_class_016_pos']
4241
tags = ['functional', 'alloc_class']
4342

4443
[tests/functional/append]

tests/zfs-tests/tests/Makefile.am

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,6 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
429429
functional/alloc_class/alloc_class_011_neg.ksh \
430430
functional/alloc_class/alloc_class_012_pos.ksh \
431431
functional/alloc_class/alloc_class_013_pos.ksh \
432-
functional/alloc_class/alloc_class_014_neg.ksh \
433-
functional/alloc_class/alloc_class_015_pos.ksh \
434432
functional/alloc_class/alloc_class_016_pos.ksh \
435433
functional/alloc_class/cleanup.ksh \
436434
functional/alloc_class/setup.ksh \

tests/zfs-tests/tests/functional/alloc_class/alloc_class_010_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ log_must disk_setup
3636
log_must zpool create $TESTPOOL raidz $ZPOOL_DISKS special mirror \
3737
$CLASS_DISK0 $CLASS_DISK1
3838

39-
for value in 0 512 1024 2048 4096 8192 16384 32768 65536 131072
39+
for value in 0 200 512 1300 4096 12345 131072 1572864 16777216
4040
do
4141
log_must zfs set special_small_blocks=$value $TESTPOOL
4242
ACTUAL=$(zfs get -p special_small_blocks $TESTPOOL | \

tests/zfs-tests/tests/functional/alloc_class/alloc_class_011_neg.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ log_must disk_setup
3636
log_must zpool create $TESTPOOL raidz $ZPOOL_DISKS special mirror \
3737
$CLASS_DISK0 $CLASS_DISK1
3838

39-
for value in 256 1025 33554432
39+
for value in 16777217 33554432 4294967296
4040
do
4141
log_mustnot zfs set special_small_blocks=$value $TESTPOOL
4242
done

tests/zfs-tests/tests/functional/alloc_class/alloc_class_014_neg.ksh

Lines changed: 0 additions & 39 deletions
This file was deleted.

tests/zfs-tests/tests/functional/alloc_class/alloc_class_015_pos.ksh

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)