zfs icon indicating copy to clipboard operation
zfs copied to clipboard

Allow configuration of zvol logical blocksize

Open kaazoo opened this issue 9 years ago • 8 comments

The logical blocksize of a zvol seems to always be 512 byte, despite the fact that volblocksize is set to 4 KB:

# zfs get volblocksize data/iscsi 
NAME        PROPERTY      VALUE     SOURCE
data/vol1   volblocksize  4K        -
# lsblk -o name,min-io,opt-io,phy-sec,log-sec,rq-size
NAME    MIN-IO OPT-IO PHY-SEC LOG-SEC RQ-SIZE
zd0       4096   4096    4096     512     128

Is there any way to set logical blocksize = physical blocksize?

kaazoo avatar Jan 11 '16 08:01 kaazoo

@kaazoo there isn't currently but there definitely could be. Why do you need to do this?

behlendorf avatar Jan 22 '16 19:01 behlendorf

@behlendorf I was testing ZFS on iSCSI disk based on ZFS with different parameters (see #4211) I wanted to check if performance changes when using 4 KB blocksize for the iSCSI disk, as the harddisks on the storage server are 4KB advance format.

The standard Linux iSCSI target (LIO) seems to have issues with setting the logical blocksize higher than 512 when the reported blocksize of the used disk (zvol in my case) is 512.

kaazoo avatar Jan 23 '16 19:01 kaazoo

This should do the trick for testing.

diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
index 57d3646..40098f9 100644
--- a/module/zfs/zvol.c
+++ b/module/zfs/zvol.c
@@ -1361,6 +1361,7 @@ __zvol_create_minor(const char *name, boolean_t ignore_sna
        blk_queue_max_segments(zv->zv_queue, UINT16_MAX);
        blk_queue_max_segment_size(zv->zv_queue, UINT_MAX);
        blk_queue_physical_block_size(zv->zv_queue, zv->zv_volblocksize);
+       blk_queue_logical_block_size(zv->zv_queue, zv->zv_volblocksize);
        blk_queue_io_opt(zv->zv_queue, zv->zv_volblocksize);
        blk_queue_max_discard_sectors(zv->zv_queue,
            (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);

behlendorf avatar Jan 23 '16 23:01 behlendorf

I know this is old but is it still the case that logical block size cannot be set through ZFS?

I have zvols that I use as drives for qemu/vms. I like the option of mounting the zvol from within the host for recovery/test reasons. Quickly verify partition schemes, extract data from vols etc...

Would be nice if there was a property on the zvol to either match logical to physical sector size or provide a value for the desired size.

jose-pr avatar May 10 '24 23:05 jose-pr

This should do the trick for testing.

diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
index 57d3646..40098f9 100644
--- a/module/zfs/zvol.c
+++ b/module/zfs/zvol.c
@@ -1361,6 +1361,7 @@ __zvol_create_minor(const char *name, boolean_t ignore_sna
        blk_queue_max_segments(zv->zv_queue, UINT16_MAX);
        blk_queue_max_segment_size(zv->zv_queue, UINT_MAX);
        blk_queue_physical_block_size(zv->zv_queue, zv->zv_volblocksize);
+       blk_queue_logical_block_size(zv->zv_queue, zv->zv_volblocksize);
        blk_queue_io_opt(zv->zv_queue, zv->zv_volblocksize);
        blk_queue_max_discard_sectors(zv->zv_queue,
            (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);

Could you re-create this for the latest ZFS?

owenthewizard avatar Aug 20 '24 19:08 owenthewizard

diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c
index e95aca097..c9bee5b97 100644
--- a/module/os/linux/zfs/zvol_os.c
+++ b/module/os/linux/zfs/zvol_os.c
@@ -1212,6 +1212,7 @@ zvol_queue_limits_convert(zvol_queue_limits_t *limits,
        qlimits->max_segment_size = limits->zql_max_segment_size;
        qlimits->io_opt = limits->zql_io_opt;
        qlimits->physical_block_size = limits->zql_physical_block_size;
+       qlimits->logical_block_size = limits->zql_physical_block_size;
        qlimits->max_discard_sectors = limits->zql_max_discard_sectors;
        qlimits->discard_granularity = limits->zql_discard_granularity;
 #ifdef HAVE_BLKDEV_QUEUE_LIMITS_FEATURES
@@ -1231,6 +1232,7 @@ zvol_queue_limits_apply(zvol_queue_limits_t *limits,
        blk_queue_max_segment_size(queue, limits->zql_max_segment_size);
        blk_queue_io_opt(queue, limits->zql_io_opt);
        blk_queue_physical_block_size(queue, limits->zql_physical_block_size);
+       blk_queue_logical_block_size(queue, limits->zql_physical_block_size);
        blk_queue_max_discard_sectors(queue, limits->zql_max_discard_sectors);
        blk_queue_discard_granularity(queue, limits->zql_discard_granularity);
 #endif

@owenthewizard - For ZFS on Linux, it should be like this. I haven’t tested it myself, though.

ixhamza avatar Aug 20 '24 20:08 ixhamza

@owenthewizard - For ZFS on Linux, it should be like this. I haven’t tested it myself, though.

Thank you iX!

owenthewizard avatar Aug 20 '24 20:08 owenthewizard

For anyone on 2.2.5:

diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c
index 41a9b1c53a2..19faaf7139b 100644
--- a/module/os/linux/zfs/zvol_os.c
+++ b/module/os/linux/zfs/zvol_os.c
@@ -1476,6 +1476,8 @@ zvol_os_create_minor(const char *name)

        blk_queue_physical_block_size(zv->zv_zso->zvo_queue,
            zv->zv_volblocksize);
+       blk_queue_logical_block_size(zv->zv_zso->zvo_queue,
+           zv->zv_volblocksize);
        blk_queue_io_opt(zv->zv_zso->zvo_queue, zv->zv_volblocksize);
        blk_queue_max_discard_sectors(zv->zv_zso->zvo_queue,
            (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);

owenthewizard avatar Aug 25 '24 16:08 owenthewizard