public void Smb2OverRdmaChannel_ReadWriteMultipleBufferDescriptorList() { InitSmbdConnectionForTestCases(smbdAdapter.TestConfig.TestFileName_LargeFile); uint size = smbdAdapter.Smb2MaxReadSize; if (size > smbdAdapter.Smb2MaxWriteSize) { size = smbdAdapter.Smb2MaxWriteSize; } int bufferCount = ushort.MaxValue / SmbdBufferDescriptorV1.SIZE; // SMB2 max support channel info size uint bufferLength = (uint)(size / bufferCount + 1); // buffer length of each buffer descriptor byte[] channelInfo = new byte[SmbdBufferDescriptorV1.SIZE * bufferCount]; byte[] writeContent = Encoding.ASCII.GetBytes(Smb2Utility.CreateRandomStringInByte((int)size)); byte[] readContent = new byte[size]; NtStatus status; #region SMB2 Write file BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1[] writeDescp = new SmbdBufferDescriptorV1[bufferCount]; for (int i = 0; i < bufferCount; ++i) { smbdAdapter.SmbdRegisterBuffer( bufferLength, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, out writeDescp[i]); byte[] channelInfoBlock = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(writeDescp[i]); Array.Copy( channelInfoBlock, 0, channelInfo, SmbdBufferDescriptorV1.SIZE * i, SmbdBufferDescriptorV1.SIZE); } // copy write content for (int index = 0, writeOffset = 0; index < bufferCount && writeOffset < writeContent.Length; ++index, writeOffset += (int)bufferLength) { int length = (int)bufferLength; if (length + writeOffset > writeContent.Length) { length = writeContent.Length - writeOffset; } byte[] buffer = new byte[length]; Array.Copy(writeContent, writeOffset, buffer, 0, length); smbdAdapter.SmbdWriteRegisteredBuffer(buffer, writeDescp[index]); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Write content to file over RDMA."); WRITE_Response writeResponse; status = (NtStatus)smbdAdapter.Smb2WriteOverRdmaChannel( 0, channelInfo, size, out writeResponse ); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "Status of SMB2 Write File is {0}", status); BaseTestSite.Assert.AreEqual <uint>( (uint)size, writeResponse.Count, "DataLength in WRITE response is {0}", writeResponse.Count); #endregion #region Read file from server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register memory and get buffer descriptor for SMB2 WRITE"); SmbdBufferDescriptorV1[] readDescp = new SmbdBufferDescriptorV1[bufferCount]; for (int i = 0; i < bufferCount; ++i) { smbdAdapter.SmbdRegisterBuffer( bufferLength, SmbdBufferReadWrite.RDMA_WRITE_PERMISSION_FOR_READ_FILE, out readDescp[i]); byte[] channelInfoBlock = TypeMarshal.ToBytes <SmbdBufferDescriptorV1>(readDescp[i]); Array.Copy( channelInfoBlock, 0, channelInfo, SmbdBufferDescriptorV1.SIZE * i, SmbdBufferDescriptorV1.SIZE); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Read content from file over RDMA."); READ_Response readResponse; byte[] readData; status = (NtStatus)smbdAdapter.Smb2ReadOverRdmaChannel( 0, size, channelInfo, out readResponse, out readData ); BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, status, "Status of SMB2 Read File is {0}", status); BaseTestSite.Assert.AreEqual <uint>( 0, readResponse.DataLength, "DataLength in READ response is {0}", readResponse.DataLength); BaseTestSite.Assert.AreEqual <int>( 0, readData.Length, "Data length of content in response is {0}", readData.Length); BaseTestSite.Assert.AreEqual <byte>( 80, readResponse.DataOffset, "DataOffset in response is {0}", readResponse.DataOffset); BaseTestSite.Assert.AreEqual <uint>( size, readResponse.DataRemaining, "DataRemaining in response is {0}", readResponse.DataRemaining); // read content for (int index = 0, readOffset = 0; index < bufferCount && readOffset < readContent.Length; ++index, readOffset += (int)bufferLength) { int length = (int)bufferLength; if (length + readOffset > readContent.Length) { length = writeContent.Length - readOffset; } byte[] buffer = new byte[length]; smbdAdapter.SmbdReadRegisteredBuffer(buffer, readDescp[index]); Array.Copy(buffer, 0, readContent, readOffset, length); } #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check the read content is same as the one written into the file."); BaseTestSite.Assert.IsTrue( SmbdUtilities.CompareByteArray(writeContent, readContent), "Check content of file"); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Close file."); smbdAdapter.Smb2CloseFile(); }