Export (0) Print
Expand All

2.1.5.3 Server Requests a Write

The server provides:

  • Open: The Open of the DataFile to write to.

  • InputBuffer: An array of bytes to write.

  • ByteOffset: The absolute byte offset in the stream where data should be written. ByteOffset could be negative, which means the write should occur at the end of the stream.

  • ByteCount: The number of bytes in InputBuffer to write.

On completion, the object store MUST return:

  • Status: An NTSTATUS code that specifies the result.

  • BytesWritten: The number of bytes written.

Pseudocode for the operation is as follows:

  • If Open.Mode.FILE_NO_INTERMEDIATE_BUFFERING is TRUE and (ByteOffset >= 0), the operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:

    • If (ByteOffset % Open.File.Volume.LogicalBytesPerSector) is not zero.

    • If (ByteCount % Open.File.Volume.LogicalBytesPerSector) is not zero.

  • If ByteOffset equals -2, then set ByteOffset to Open.CurrentByteOffset.

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

  • If ((ByteOffset + ByteCount) > MAXLONGLONG (0x7fffffffffffffff) and (ByteOffset >= 0), the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If ByteCount is zero, the object store MUST return:

    • BytesWritten set to 0.

    • Status set to STATUS_SUCCESS.

  • If ((ByteOffset < 0) and (Open.Stream.Size +ByteCount)) > MAXLONGLONG (0x7fffffffffffffff), the operation MUST fail with STATUS_INVALID_PARAMETER.

  • If (ByteOffset < 0), set ByteOffset to Open.Stream.Size.

  • If (ByteOffset + ByteCount) > MAXFILESIZE (0xfffffff0000), the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • Initialize UsnReason to zero.

  • If (ByteOffset + ByteCount) > Open.Stream.Size, set UsnReason.USN_REASON_DATA_EXTEND to TRUE.

  • If ByteOffset < Open.Stream.Size, set UsnReason.USN_REASON_DATA_OVERWRITE to TRUE.

  • If Open.Stream.Oplock is not empty, the object store MUST check for an oplock break according to the algorithm in section 2.1.4.12, with input values as follows:

    • Open equal to this operation's Open

    • Oplock equal to Open.Stream.Oplock

    • Operation equal to "WRITE"

    • OpParams empty

  • Determine if the write is in conflict with an existing byte range lock on Open.Stream using the algorithm described in section 2.1.4.10 (with ByteOffset set to ByteOffset, Length set to ByteCount, IsExclusive set to TRUE, LockIntent set to FALSE and Open set to Open). If the algorithm returns TRUE, the operation MUST be failed with STATUS_FILE_LOCK_CONFLICT.

  • The object store MUST post a USN change as per section 2.1.4.11 with File equal to File, Reason equal to UsnReason, and FileName equal to Open.Link.Name.

  • If ((ByteOffset + ByteCount) > Open.Stream.ValidDataLength), then set DoingIoAtEof to TRUE.

  • If ((ByteOffset + ByteCount) > Open.Stream.AllocationSize), the object store MUST increase Open.Stream.AllocationSize to BlockAlign(ByteOffset + ByteCount, Open.File.Volume.ClusterSize). If there is not enough disk space, the operation MUST be failed with STATUS_DISK_FULL.

  • If Open.Mode.FILE_NO_INTERMEDIATE_BUFFERING is TRUE:

    • The object store MUST write any unwritten cached data for this range of the stream to disk.

    • The object store MUST remove from the cache any cached data for this range of the stream.

    • If DoingIoAtEof is TRUE, and (Open.Stream.ValidDataLength < ByteOffset) , write zeroes to the location on disk corresponding to the range between Open.Stream.ValidDataLength and ByteOffset in the stream, and then write the first ByteCount bytes of InputBuffer to the location on disk corresponding to the range starting at offset ByteOffset in the stream. If either write to the disk failed, the operation MUST be failed with the corresponding error status.

  • EndIf

  • If Open.Mode.FILE_NO_INTERMEDIATE_BUFFERING is FALSE, DoingIoAtEof is TRUE, and (Open.Stream.ValidDataLength < ByteOffset), zero out the range between Open.Stream.ValidDataLength and ByteOffset in the cache for this stream and then write the first ByteCount bytes of InputBuffer into the cache for this stream at offset ByteOffset. If there would not be enough disk space to flush the cache, the operation MUST be failed with STATUS_DISK_FULL. If Open.Mode.FILE_WRITE_THROUGH is TRUE, the cache write will also trigger a flush of the cache for that range to the disk.

  • If Open.Mode.FILE_SYNCHRONOUS_IO_ALERT is TRUE or Open.Mode.FILE_SYNCHRONOUS_IO_NONALERT is TRUE, the object store MUST set Open.CurrentByteOffset to (ByteOffset + ByteCount).

  • The object store MUST note that the file has been modified as specified in section 2.1.4.17 with Open equal to Open.

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

    • Open.Stream.Size to the maximum of Open.Stream.Size or (ByteOffset + ByteCount).

    • Open.Stream.ValidDataLength to the maximum of Open.Stream.ValidDataLength or (ByteOffset + ByteCount).

    • BytesWritten to ByteCount.

    • Status to STATUS_SUCCESS.

 
Show:
© 2014 Microsoft