[cifs-protocol] SMB3 ODX Block Aligment: Rounding Up vs Down

Ralph Boehme slow at samba.org
Thu Jul 8 18:03:59 UTC 2021


Hello dochelp,

I'm trying to implement SMB3 ODX in Samba, but I'm having a hard time 
understanding 2.1.5.9.20 FSCTL_OFFLOAD_READ.

Following the spec by the letter to me it seems the client will not be 
able to do a full file copy.

The problem is this clause:

If the sum of InputBuffer.FileOffset and InputBuffer.CopyLength is 
greater than ValidDataLength:

- Set InputBuffer.CopyLength to ValidDataLength-InputBuffer.FileOffset.

- If VdlSameAsEof is TRUE:

   - Set InputBuffer.CopyLength to
     BlockAlignTruncate(InputBuffer.CopyLength,...LogicalBytesPerSector).

   - Set VdlTrimmedCopyLength to InputBuffer.CopyLength.

   - Set OutputBuffer.Flags to
     OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE.

- EndIf

EndIf

I've implemented this as is which results in an incomplete copy. The 
attached pcap ODX-bad-block-align-truncate.pcapng.gz contains an ODX 
copy of a file of size 1 MB + 2 bytes.

In this example VdlSameAsEof will be TRUE and LogicalBytesPerSector is 4096.

Due to the

     Set InputBuffer.CopyLength to
     BlockAlignTruncate(InputBuffer.CopyLength,...LogicalBytesPerSector).

the first ODX READ is block aligned rounded down to 1 MB (p.122, 
TransferLength=1Mb). The subsequent ODX WRITE writes this 1 MB.

Now the client sends another ODX READ with Offset=1MB and CopyLenght=1MB 
and this time gets rounded down to 0 as per

     Set InputBuffer.CopyLength to
     BlockAlignTruncate(InputBuffer.CopyLength,...LogicalBytesPerSector).

The ODX READ response in p.126 therefor contains TransferLength=0. 
Subsequently the client doesn't issue further ODX WRITEs to write the 
remaining range.

Now, as soon as I change the algorithm from

     Set InputBuffer.CopyLength to
     BlockAlignTruncate(InputBuffer.CopyLength,...LogicalBytesPerSector).

to

     Set InputBuffer.CopyLength to
     BlockAlign(InputBuffer.CopyLength,...LogicalBytesPerSector).

ie use BlockAlign() instead of BlockAlignTruncate(), iow rounding up 
instead of down I see a complete copy. ODX-good-block-align.pcapng.gz 
contains a trace of a copy of the same file (1MB + 2 bytes).

I've also looked at the sources of the ODX implementation in the Illumos 
kernel SMB server and indeed it uses "rounding up" instead of down 
approach too:

<https://github.com/Nexenta/illumos-nexenta/blob/release-5.3/usr/src/uts/common/fs/smbsrv/smb2_fsctl_odx.c#L285>

   src_rnd_size = (src_size + OFFMASK) & ~OFFMASK;

Can you please verify my findings if either MS-FSA has a bug here or if 
possible misunderstanding something in the spec?

Thanks a lot!

Cheers!
-slow

-- 
Ralph Boehme, Samba Team                 https://samba.org/
SerNet Samba Team       https://www.sernet.de/en/team-samba
Samba Development and Support, SerNet Professional Services
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ODX-good-block-align.pcapng.gz
Type: application/gzip
Size: 351504 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/cifs-protocol/attachments/20210708/0e80dbfd/ODX-good-block-align.pcapng.gz>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ODX-bad-block-align-truncate.pcapng.gz
Type: application/gzip
Size: 106928 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/cifs-protocol/attachments/20210708/0e80dbfd/ODX-bad-block-align-truncate.pcapng.gz>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/cifs-protocol/attachments/20210708/0e80dbfd/OpenPGP_signature.sig>


More information about the cifs-protocol mailing list