]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: add options "fs:[logical|aligned|performance|effective aligned] bytes per sector"
authorRalph Boehme <slow@samba.org>
Fri, 5 Apr 2024 13:25:03 +0000 (15:25 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 20 Aug 2024 07:01:19 +0000 (07:01 +0000)
In order to support certain Windows applications that make use of copy reflink,
we need some way to allow configuring these values. According to testing, the
application somehow uses the value of phys_bytes_per_sector_atomic for some check
when requesting server-side reflink copies, eg for ZFS the following is needed

 block size = 131072
 fs:aligned bytes per sector = 131072

For some reason "block size" must also be set to the value of fs:aligned bytes
per sector, but fs:logical bytes per sector, which according to the spec should
match "block size", must stay at the default of 512, otherwise the application
does not work.

As the whole client behaviour could not be fully understood, I'm proposing to
introduce these options as undocumented parametric options, so we can at least
start testing with them.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Tue Aug 20 07:01:19 UTC 2024 on atb-devel-224

source3/smbd/smb2_trans2.c

index 1901b8b92981b02173d0d8b6e862c035755009df..8062cb05d28bbafec38ad3e4f9c908b895e9f0e5 100644 (file)
@@ -2040,7 +2040,7 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
        int snum = SNUM(conn);
        const char *fstype = lp_fstype(SNUM(conn));
        const char *filename = NULL;
-       const uint64_t bytes_per_sector = 512;
+       uint64_t bytes_per_sector = 512;
        struct smb_filename smb_fname;
        SMB_STRUCT_STAT st;
        NTSTATUS status = NT_STATUS_OK;
@@ -2417,6 +2417,23 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
 
                case SMB_FS_SECTOR_SIZE_INFORMATION:
                {
+                       uint32_t bps_logical = lp_parm_ulong(
+                               SNUM(conn),
+                               "fs", "logical bytes per sector",
+                               bytes_per_sector);
+                       uint32_t bps_aligned = lp_parm_ulong(
+                               SNUM(conn),
+                               "fs", "aligned bytes per sector",
+                               bytes_per_sector);
+                       uint32_t bps_performance = lp_parm_ulong(
+                               SNUM(conn),
+                               "fs", "performance bytes per sector",
+                               bytes_per_sector);
+                       uint32_t bps_effective = lp_parm_ulong(
+                               SNUM(conn),
+                               "fs", "effective aligned bytes per sector",
+                               bytes_per_sector);
+
                        data_len = 28;
                        /*
                         * These values match a physical Windows Server 2012
@@ -2424,13 +2441,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                         */
                        DEBUG(5, ("SMB_FS_SECTOR_SIZE_INFORMATION:"));
                        /* logical_bytes_per_sector */
-                       SIVAL(pdata, 0, bytes_per_sector);
+                       SIVAL(pdata, 0, bps_logical);
                        /* phys_bytes_per_sector_atomic */
-                       SIVAL(pdata, 4, bytes_per_sector);
+                       SIVAL(pdata, 4, bps_aligned);
                        /* phys_bytes_per_sector_perf */
-                       SIVAL(pdata, 8, bytes_per_sector);
+                       SIVAL(pdata, 8, bps_performance);
                        /* fs_effective_phys_bytes_per_sector_atomic */
-                       SIVAL(pdata, 12, bytes_per_sector);
+                       SIVAL(pdata, 12, bps_effective);
                        /* flags */
                        SIVAL(pdata, 16, SSINFO_FLAGS_ALIGNED_DEVICE
                                | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);