* [PATCH proxmox{-backup,} v3 0/3] partially fix #6933: add option to specify zfs recordsize
@ 2026-08-12 14:40 Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 1/3] partially fix #6933: ui: storage: " Shan Shaji
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Shan Shaji @ 2026-08-12 14:40 UTC (permalink / raw)
To: pbs-devel
The option to specify the `recordsize` was previously available neither
in the UI nor in the CLI. Users had to configure it manually using the
ZFS CLI. This series adds an option for specifying the `recordsize`
through both the UI and `proxmox-backup-manager` when creating storage.
Since adding support for editing this property at the dataset level
would require more changes, I am sending the creation related
changes first. Support for editing the property will be send
as a separate series.
changes since v2: Thanks @Nicolas Frey
* Patch [3/3] - Instead of `if let-else` use `let-else` to match the
pattern.
* add {Reviewed,Tested}-by trailers.
changes since v1: Thanks @Nicolas Frey
* Patch [3/3] - Add validation function identical to the one in
Javscript to verify if the passed recordsize is valid. If it's not
valid, then the backup manager exits without creating the pool.
Earlier, even though the recordsize format was wrong, the backup
manager allowed executing the zpool and zfs commands, which in turn
created the pool with the default(128k) recordsize, but the
`zfs set` command failed with an error.
References:
- https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Workload%20Tuning.html#dataset-recordsize
proxmox-backup:
Shan Shaji (2):
partially fix #6933: ui: storage: add option to specify zfs recordsize
partially fix #6933: bin: add option to specify ZFS recordsize
src/api2/node/disks/zfs.rs | 14 +++++++++++--
src/bin/proxmox_backup_manager/disk.rs | 8 ++++++--
www/Utils.js | 28 ++++++++++++++++++++++++++
www/window/ZFSCreate.js | 8 ++++++++
4 files changed, 54 insertions(+), 4 deletions(-)
proxmox:
Shan Shaji (1):
pbs-api-types: zfs: define schema for recordsize
pbs-api-types/src/zfs.rs | 68 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
Summary over all repositories:
5 files changed, 122 insertions(+), 4 deletions(-)
--
Generated by murpp 0.10.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH proxmox-backup v3 1/3] partially fix #6933: ui: storage: add option to specify zfs recordsize
2026-08-12 14:40 [PATCH proxmox{-backup,} v3 0/3] partially fix #6933: add option to specify zfs recordsize Shan Shaji
@ 2026-08-12 14:40 ` Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 2/3] partially fix #6933: bin: add option to specify ZFS recordsize Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox v3 3/3] pbs-api-types: zfs: define schema for recordsize Shan Shaji
2 siblings, 0 replies; 4+ messages in thread
From: Shan Shaji @ 2026-08-12 14:40 UTC (permalink / raw)
To: pbs-devel
Earlier, to change the recordsize of an zfs storage dataset the users
had to use the `zfs` cli. Improved this by adding an option to specify
the recordsize while creating the storage. By default the recordsize is
set at 128KB.
Reviewed-by: Nicolas Frey <n.frey@proxmox.com>
Tested-by: Nicolas Frey <n.frey@proxmox.com>
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
src/api2/node/disks/zfs.rs | 14 ++++++++++++--
www/Utils.js | 28 ++++++++++++++++++++++++++++
www/window/ZFSCreate.js | 8 ++++++++
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/src/api2/node/disks/zfs.rs b/src/api2/node/disks/zfs.rs
index 7a62e3f70..43d0ce259 100644
--- a/src/api2/node/disks/zfs.rs
+++ b/src/api2/node/disks/zfs.rs
@@ -7,8 +7,8 @@ use proxmox_schema::api;
use pbs_api_types::{
DATASTORE_SCHEMA, DISK_ARRAY_SCHEMA, DISK_LIST_SCHEMA, DataStoreConfig, NODE_SCHEMA,
- PRIV_SYS_AUDIT, PRIV_SYS_MODIFY, UPID_SCHEMA, ZFS_ASHIFT_SCHEMA, ZPOOL_NAME_SCHEMA,
- ZfsCompressionType, ZfsRaidLevel, ZpoolListItem,
+ PRIV_SYS_AUDIT, PRIV_SYS_MODIFY, UPID_SCHEMA, ZFS_ASHIFT_SCHEMA, ZFS_RECORD_SIZE_SCHEMA,
+ ZPOOL_NAME_SCHEMA, ZfsCompressionType, ZfsRaidLevel, ZpoolListItem,
};
use crate::tools::disks::{
@@ -138,6 +138,10 @@ pub fn zpool_details(name: String) -> Result<Value, Error> {
type: bool,
optional: true,
},
+ recordsize: {
+ schema: ZFS_RECORD_SIZE_SCHEMA,
+ optional: true,
+ }
},
},
returns: {
@@ -155,6 +159,7 @@ pub fn create_zpool(
compression: Option<String>,
ashift: Option<usize>,
add_datastore: Option<bool>,
+ recordsize: Option<String>,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<String, Error> {
let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
@@ -292,6 +297,11 @@ pub fn create_zpool(
if let Some(compression) = compression {
command.arg(format!("compression={compression}"));
}
+
+ if let Some(recordsize) = recordsize {
+ command.arg(format!("recordsize={recordsize}"));
+ }
+
command.args(["relatime=on", &name]);
info!("# {command:?}");
match proxmox_sys::command::run_command(command, None) {
diff --git a/www/Utils.js b/www/Utils.js
index d6bfd459e..1c96bd0b3 100644
--- a/www/Utils.js
+++ b/www/Utils.js
@@ -395,6 +395,34 @@ Ext.define('PBS.Utils', {
return cls;
},
+ validateZfsRecordSize: function (value) {
+ if (!value) {
+ return true;
+ }
+
+ let match = value.match(/^([1-9][0-9]*)([km])?$/i);
+ if (!match) {
+ return gettext(
+ 'Invalid format. Use numbers with optional k or m suffix (e.g., 16k).',
+ );
+ }
+
+ let bytes = parseInt(match[1], 10);
+ let suffix = match[2]?.toLowerCase();
+
+ if (suffix === 'k') {
+ bytes *= 1024;
+ } else if (suffix === 'm') {
+ bytes *= 1024 * 1024;
+ }
+
+ if (bytes < 512 || (bytes & (bytes - 1)) !== 0 || bytes > 16 * 1024 * 1024) {
+ return gettext('Value must be a power of 2 between 512 and 16m');
+ }
+
+ return true;
+ },
+
constructor: function () {
var me = this;
diff --git a/www/window/ZFSCreate.js b/www/window/ZFSCreate.js
index 9a32bd5f3..7dcffc1b8 100644
--- a/www/window/ZFSCreate.js
+++ b/www/window/ZFSCreate.js
@@ -72,6 +72,14 @@ Ext.define('PBS.window.CreateZFS', {
value: '12',
name: 'ashift',
},
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'recordsize',
+ fieldLabel: gettext('Record Size'),
+ allowBlank: true,
+ validator: PBS.Utils.validateZfsRecordSize,
+ emptyText: '128k'
+ },
],
columnB: [
{
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH proxmox-backup v3 2/3] partially fix #6933: bin: add option to specify ZFS recordsize
2026-08-12 14:40 [PATCH proxmox{-backup,} v3 0/3] partially fix #6933: add option to specify zfs recordsize Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 1/3] partially fix #6933: ui: storage: " Shan Shaji
@ 2026-08-12 14:40 ` Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox v3 3/3] pbs-api-types: zfs: define schema for recordsize Shan Shaji
2 siblings, 0 replies; 4+ messages in thread
From: Shan Shaji @ 2026-08-12 14:40 UTC (permalink / raw)
To: pbs-devel
Reviewed-by: Nicolas Frey <n.frey@proxmox.com>
Tested-by: Nicolas Frey <n.frey@proxmox.com>
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
src/bin/proxmox_backup_manager/disk.rs | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/bin/proxmox_backup_manager/disk.rs b/src/bin/proxmox_backup_manager/disk.rs
index 258c5dfbd..91f738783 100644
--- a/src/bin/proxmox_backup_manager/disk.rs
+++ b/src/bin/proxmox_backup_manager/disk.rs
@@ -6,8 +6,7 @@ use proxmox_schema::api;
use std::io::IsTerminal;
use pbs_api_types::{
- BLOCKDEVICE_DISK_AND_PARTITION_NAME_SCHEMA, BLOCKDEVICE_NAME_SCHEMA, DATASTORE_SCHEMA,
- DISK_LIST_SCHEMA, ZFS_ASHIFT_SCHEMA, ZfsCompressionType, ZfsRaidLevel,
+ BLOCKDEVICE_DISK_AND_PARTITION_NAME_SCHEMA, BLOCKDEVICE_NAME_SCHEMA, DATASTORE_SCHEMA, DISK_LIST_SCHEMA, ZFS_ASHIFT_SCHEMA, ZFS_RECORD_SIZE_SCHEMA, ZfsCompressionType, ZfsRaidLevel
};
use proxmox_backup::tools::disks::{
FileSystemType, SmartAttribute, complete_disk_name, complete_partition_name,
@@ -204,6 +203,11 @@ async fn wipe_disk(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<
type: bool,
optional: true,
},
+ recordsize: {
+ schema: ZFS_RECORD_SIZE_SCHEMA,
+ optional: true,
+ }
+
},
},
)]
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH proxmox v3 3/3] pbs-api-types: zfs: define schema for recordsize
2026-08-12 14:40 [PATCH proxmox{-backup,} v3 0/3] partially fix #6933: add option to specify zfs recordsize Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 1/3] partially fix #6933: ui: storage: " Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 2/3] partially fix #6933: bin: add option to specify ZFS recordsize Shan Shaji
@ 2026-08-12 14:40 ` Shan Shaji
2 siblings, 0 replies; 4+ messages in thread
From: Shan Shaji @ 2026-08-12 14:40 UTC (permalink / raw)
To: pbs-devel
add schema and verifcation function for recordsize to check against
allowed zfs constraints. Without the verification function the dataset
will be created using the default 128k recordsize.
Reviewed-by: Nicolas Frey <n.frey@proxmox.com>
Tested-by: Nicolas Frey <n.frey@proxmox.com>
Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
changes since v2:
* style nit: use let-else instead of if let-else.
pbs-api-types/src/zfs.rs | 68 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/pbs-api-types/src/zfs.rs b/pbs-api-types/src/zfs.rs
index 2cfbd403..b2e1baf6 100644
--- a/pbs-api-types/src/zfs.rs
+++ b/pbs-api-types/src/zfs.rs
@@ -1,3 +1,4 @@
+use anyhow::{Error, bail};
use serde::{Deserialize, Serialize};
#[cfg(feature = "enum-fallback")]
@@ -6,6 +7,7 @@ use proxmox_schema::*;
const_regex! {
pub ZPOOL_NAME_REGEX = r"^[a-zA-Z][a-z0-9A-Z\-_.:]+$";
+ ZFS_RECORD_SIZE_REGEX = r"^(?i)([1-9][0-9]*)([km])?$";
}
pub const ZFS_ASHIFT_SCHEMA: Schema = IntegerSchema::new("Pool sector size exponent.")
@@ -18,6 +20,39 @@ pub const ZPOOL_NAME_SCHEMA: Schema = StringSchema::new("ZFS Pool Name")
.format(&ApiStringFormat::Pattern(&ZPOOL_NAME_REGEX))
.schema();
+fn verify_zfs_recordsize(value: &str) -> Result<(), Error> {
+ let Some(caps) = ZFS_RECORD_SIZE_REGEX.captures(value) else {
+ bail!("Invalid format. Use numbers with optional k or m suffix (e.g., 16k).")
+ };
+
+ let range_error = "Value must be a power of 2 between 512 and 16m";
+
+ let Ok(number) = caps[1].parse::<u32>() else {
+ bail!(range_error);
+ };
+
+ let multiplier = match caps.get(2).map(|v| v.as_str()) {
+ Some(suffix) if suffix.eq_ignore_ascii_case("k") => 1024,
+ Some(suffix) if suffix.eq_ignore_ascii_case("m") => 1024 * 1024,
+ _ => 1,
+ };
+
+ let bytes = number
+ .checked_mul(multiplier)
+ .filter(|&b| b.is_power_of_two() && (512..=16 * 1024 * 1024).contains(&b));
+
+ if bytes.is_none() {
+ bail!(range_error);
+ }
+
+ Ok(())
+}
+
+pub const ZFS_RECORD_SIZE_SCHEMA: Schema =
+ StringSchema::new("ZFS Recordsize. Use numbers with optional k or m suffix (e.g., 128k).")
+ .format(&ApiStringFormat::VerifyFn(verify_zfs_recordsize))
+ .schema();
+
#[api(default: "On")]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
@@ -84,3 +119,36 @@ pub struct ZpoolListItem {
/// ZFS deduplication ratio
pub dedup: f64,
}
+
+#[cfg(test)]
+mod tests {
+
+ use super::verify_zfs_recordsize;
+
+ #[test]
+ fn test_zfs_record_size_verify_fn() {
+ let format_error = "Invalid format. Use numbers with optional k or m suffix (e.g., 16k).";
+ let range_error = "Value must be a power of 2 between 512 and 16m";
+
+ let valid_inputs = ["512", "1024", "16m", "16384k", "16777216"];
+ for input in valid_inputs {
+ assert!(verify_zfs_recordsize(input).is_ok());
+ }
+
+ let range_error_inputs = ["31m", "256", "31m", "32m", "4294967297"];
+ for input in range_error_inputs {
+ assert_eq!(
+ verify_zfs_recordsize(input).unwrap_err().to_string(),
+ range_error
+ );
+ }
+
+ let format_error_inputs = ["0", "k12", "16g", "1.5m", "-512", "0512"];
+ for input in format_error_inputs {
+ assert_eq!(
+ verify_zfs_recordsize(input).unwrap_err().to_string(),
+ format_error
+ );
+ }
+ }
+}
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-12 14:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 14:40 [PATCH proxmox{-backup,} v3 0/3] partially fix #6933: add option to specify zfs recordsize Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 1/3] partially fix #6933: ui: storage: " Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox-backup v3 2/3] partially fix #6933: bin: add option to specify ZFS recordsize Shan Shaji
2026-08-12 14:40 ` [PATCH proxmox v3 3/3] pbs-api-types: zfs: define schema for recordsize Shan Shaji
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.