Expand Minimize
This topic has not yet been rated - Rate this topic

2.1.5.9.17 FSCTL_OFFLOAD_WRITE

The server provides:

  • Open: An Open of a DataFile.

  • InputBuffer: An array of bytes containing a single FSCTL_OFFLOAD_WRITE_INPUT structure, as specified in [MS-FSCC] section 2.3.76, indicating the Token to use as the source, and the range of the file to be offload written to, as specified in [MS-FSCC] section 2.3.75.

  • InputBufferSize: The number of bytes in InputBuffer.

  • OutputBufferSize: The number of bytes in OutputBuffer.

Upon completion, the object store MUST return:

  • Status: An NTSTATUS code that specifies the result.

  • OutputBuffer: An array of bytes that contains a single FSCTL_OFFLOAD_WRITE_OUTPUT structure, as specified in [MS-FSCC] section 2.3.77.

  • BytesReturned: The number of bytes written to OutputBuffer.

This operation also uses the following local variables:

  • 32-bit unsigned integers (initialized to zero): OutputBufferLength

  • 64-bit unsigned integers (initialized to zero): NewValidDataLength, ValidDataLength, FileSize, and StorageOffloadBytesWritten.

  • A list of EXTENTS (initialized to empty): OffloadLCNList

  • An NTSTATUS code: StorageOffloadWriteStatus

Support for this write operation is optional. If the object store does not implement this functionality, the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.<67>

Pseudocode for the operation is as follows:

  • If Open.Volume.IsReadOnly is TRUE, the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.

  • If Open.Volume.IsOffloadWriteSupported is FALSE, the operation MUST be failed with STATUS_NOT_SUPPORTED.

  • If InputBufferSize is less than the size of the FSCTL_OFFLOAD_WRITE_INPUT structure size, the operation MUST be failed with STATUS_BUFFER_TOO_SMALL.

  • If OutputBufferSize is less than the size of the FSCTL_OFFLOAD_WRITE_OUTPUT structure size, the operation MUST be failed with STATUS_BUFFER_TOO_SMALL.

  • If InputBuffer.FileOffset is NOT a multiple of Open.Volume.BytesPerLogicalSector, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If InputBuffer.CopyLength is NOT a multiple of Open.Volume.BytesPerLogicalSector, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If InputBuffer.TransferOffset is NOT a multiple of Open.Volume.BytesPerLogicalSector, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If InputBuffer.Size is not equal to the size of the FSCTL_OFFLOAD_WRITE_INPUT structure size, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If the sum of InputBuffer.FileOffset and InputBuffer.CopyLength overflows 64 bits, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If InputBuffer.CopyLength is equal to 0, the operation SHOULD return immediately with STATUS_SUCCESS.

  • If Open.Stream.StreamType != DataStream, the operation MUST be failed with STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED.

  • If Open.Stream.IsSparse is TRUE, the operation MUST be failed with STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED.

  • If Open.Stream.IsEncrypted is TRUE, the operation MUST be failed with STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED.

  • If Open.Stream.IsCompressed is TRUE, the operation MUST be failed with STATUS_OFFLOAD_WRITE_FILE_NOT_SUPPORTED.

  • If Open.Stream.IsDeleted is TRUE, the operation MUST be failed with STATUS_FILE_DELETED.

  • If InputBuffer.FileOffset / Open.Volume.BytesPerCluster is less than 0, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If (InputBuffer.FileOffset + InputBuffer.CopyLength) is greater than Open.Volume.MaxFileSize, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If Open.Volume.IsUsnJournalActive is TRUE, the object store MUST post a USN change as per section 2.1.4.11 with File equal to File, Reason equal to USN_REASON_DATA_OVERWRITE, and FileName equal to Open.File.Name.

  • Set FileSize to Open.Stream.Size.

  • Set ValidDataLength to Open.Stream.ValidDataLength.

  • If InputBuffer.FileOffset is greater than or equal to Open.Stream.FileSize, the operation MUST be failed with STATUS_END_OF_FILE.

  • If InputBuffer.FileOffset is greater than ValidDataLength, the operation MUST be failed with STATUS_BEYOND_VDL.

  • For Each Extent in Open.Stream.ExtentList spanned by the range defined by InputBuffer.FileOffset and InputBuffer.CopyLength:

    • Append the partial or full Extent to OffloadLCNList.

  • EndFor

  • Construct the offload write command with the OffloadLCNList as the ranges, Token from InputBuffer.Token, token offset from InputBuffer.TransferOffset, and write length from InputBuffer.CopyLength as defined in [INCITS-T10/11-059] and send it to the underlying storage subsystem. Store the status from the operation in StorageOffloadWriteStatus, and the number of bytes written in StorageOffloadBytesWritten.

  • If the operation was successful:

    • Set NewValidDataLength to InputBuffer.FileOffset + StorageOffloadBytesWritten.

    • If NewValidDataLength is greater than ValidDataLength:

      • Set Open.Stream.VDL to NewValidDataLength.

    • EndIf

    • Set OutputBuffer.LengthWritten to StorageOffloadBytesWritten.

    • Set OutputBuffer.Size to the size of the FSCTL_OFFLOAD_WRITE_OUTPUT structure.

    • Set OutputBuffer.Flags to 0.

  • Else:

    • If StorageOffloadWriteStatus is equal to STATUS_NOT_SUPPORTED or if OffloadWriteStatus is equal to STATUS_DEVICE_FEATURE_NOT_SUPPORTED, then set Open.Volume.IsOffloadWriteSupported to FALSE.

  • EndIf

  • Upon successful completion of the operation, the object store MUST return:

    • BytesReturned set to OutputBufferLength.

    • Status set to STATUS_SUCCESS.

 
Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.