]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test/client: test contiguous read for a non-contiguous write
authorDhairya Parmar <dparmar@redhat.com>
Fri, 16 Feb 2024 07:42:40 +0000 (13:12 +0530)
committerDhairya Parmar <dparmar@redhat.com>
Mon, 6 May 2024 11:56:16 +0000 (17:26 +0530)
Fixes: https://tracker.ceph.com/issues/63896
Signed-off-by: Dhairya Parmar <dparmar@redhat.com>
src/test/client/nonblocking.cc

index 9b47291cff69e15785de8c54b5842dd37373fd08..d4aecb10ffcb4a21277e5e6df5b5f224c29d0958 100644 (file)
@@ -611,3 +611,104 @@ TEST_F(TestClient, LlreadvLlwritevInvalidFileHandle) {
   ASSERT_EQ(bytes_read, -CEPHFS_EBADF);
   ASSERT_EQ(bl.length(), 0);
 }
+
+TEST_F(TestClient, LlreadvContiguousLlwritevNonContiguous) {
+  /* Test writing at non-contiguous memory locations, and make sure
+  contiguous read returns bytes requested. */
+
+  int mypid = getpid();
+  char filename[256];
+
+  client->unmount();
+  TearDown();
+  SetUp();
+
+  sprintf(filename, "test_llreadvcontiguousllwritevnoncontiguousfile%u", mypid);
+
+  Inode *root, *file;
+  root = client->get_root();
+  ASSERT_NE(root, (Inode *)NULL);
+
+  Fh *fh;
+  struct ceph_statx stx;
+
+  ASSERT_EQ(0, client->ll_createx(root, filename, 0666,
+                                 O_RDWR | O_CREAT | O_TRUNC,
+                                 &file, &fh, &stx, 0, 0, myperm));
+
+  const int NUM_BUF = 5;
+  char out_buf_0[] = "hello ";
+  char out_buf_1[] = "world\n";
+  char out_buf_2[] = "Ceph - ";
+  char out_buf_3[] = "a scalable distributed ";
+  char out_buf_4[] = "storage system\n";
+
+  struct iovec iov_out_non_contiguous[NUM_BUF] = {
+    {out_buf_0, sizeof(out_buf_0)},
+    {out_buf_1, sizeof(out_buf_1)},
+    {out_buf_2, sizeof(out_buf_2)},
+    {out_buf_3, sizeof(out_buf_3)},
+    {out_buf_4, sizeof(out_buf_4)}
+  };
+
+  char in_buf_0[sizeof(out_buf_0)];
+  char in_buf_1[sizeof(out_buf_1)];
+  char in_buf_2[sizeof(out_buf_2)];
+  char in_buf_3[sizeof(out_buf_3)];
+  char in_buf_4[sizeof(out_buf_4)];
+
+  struct iovec iov_in_contiguous[NUM_BUF] = {
+    {in_buf_0, sizeof(in_buf_0)},
+    {in_buf_1, sizeof(in_buf_1)},
+    {in_buf_2, sizeof(in_buf_2)},
+    {in_buf_3, sizeof(in_buf_3)},
+    {in_buf_4, sizeof(in_buf_4)}
+  };
+
+  ssize_t bytes_to_write = 0, total_bytes_written = 0, total_bytes_read = 0;
+  for(int i = 0; i < NUM_BUF; ++i) {
+    bytes_to_write += iov_out_non_contiguous[i].iov_len;
+  }
+
+  std::unique_ptr<C_SaferCond> writefinish = nullptr;
+  std::unique_ptr<C_SaferCond> readfinish = nullptr;
+
+  int64_t rc;
+  bufferlist bl;
+
+  struct iovec *current_iov = iov_out_non_contiguous;
+
+  for(int i = 0; i < NUM_BUF; ++i) {
+    writefinish.reset(new C_SaferCond("test-nonblocking-writefinish-non-contiguous"));
+    rc = client->ll_preadv_pwritev(fh, current_iov++, 1, i * NUM_BUF * 100,
+                                   true, writefinish.get(), nullptr);
+    ASSERT_EQ(rc, 0);
+    total_bytes_written += writefinish->wait();
+  }
+  ASSERT_EQ(total_bytes_written, bytes_to_write);
+
+  readfinish.reset(new C_SaferCond("test-nonblocking-readfinish-contiguous"));
+  rc = client->ll_preadv_pwritev(fh, iov_in_contiguous, NUM_BUF, 0, false,
+                                 readfinish.get(), &bl);
+  ASSERT_EQ(rc, 0);
+  total_bytes_read = readfinish->wait();
+  ASSERT_EQ(total_bytes_read, bytes_to_write);
+  ASSERT_EQ(bl.length(), bytes_to_write);
+
+  copy_bufferlist_to_iovec(iov_in_contiguous, NUM_BUF, &bl,
+                           total_bytes_read);
+  /* since the iovec structures are written at gaps of 100, only the first
+  iovec structure content should match when reading contiguously while rest
+  of the read buffers should just be 0s(holes filled with zeros) */
+  ASSERT_EQ(0, strncmp((const char*)iov_in_contiguous[0].iov_base,
+                       (const char*)iov_out_non_contiguous[0].iov_base,
+                       iov_out_non_contiguous[0].iov_len));
+  for(int i = 1; i < NUM_BUF; ++i) {
+    ASSERT_NE(0, strncmp((const char*)iov_in_contiguous[i].iov_base,
+                         (const char*)iov_out_non_contiguous[i].iov_base,
+                         iov_out_non_contiguous[i].iov_len));
+  }
+
+  client->ll_release(fh);
+  ASSERT_EQ(0, client->ll_unlink(root, filename, myperm));        
+}