]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: propagate CEPH_OSD_FLAG_FULL_TRY from IoCtx to IOContext 43207/head
authorIlya Dryomov <idryomov@gmail.com>
Fri, 17 Sep 2021 13:00:59 +0000 (15:00 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 17 Sep 2021 18:13:04 +0000 (20:13 +0200)
We use neorados on the I/O path so data_io_context needs to have
the same setting as data_ctx.

Fixes: https://tracker.ceph.com/issues/52648
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/include/rados/librados.hpp
src/librados/librados_cxx.cc
src/librbd/ImageCtx.cc
src/test/librbd/test_librbd.cc

index dc3ecefa7e5de67cf468ef3326407ef386940ed0..76fe6dfd0cd69181955d027de17bf90d4794188c 100644 (file)
@@ -1339,6 +1339,7 @@ inline namespace v14_2_0 {
     void unset_osdmap_full_try()
       __attribute__ ((deprecated));
 
+    bool get_pool_full_try();
     void set_pool_full_try();
     void unset_pool_full_try();
 
index 85f3b92137f56644884ad59976b4af04a77d6117..75e3e797a9aff6544a8ce3668bb7a46b64ae91e3 100644 (file)
@@ -2318,6 +2318,11 @@ void librados::IoCtx::unset_osdmap_full_try()
   io_ctx_impl->extra_op_flags &= ~CEPH_OSD_FLAG_FULL_TRY;
 }
 
+bool librados::IoCtx::get_pool_full_try()
+{
+  return (io_ctx_impl->extra_op_flags & CEPH_OSD_FLAG_FULL_TRY) != 0;
+}
+
 void librados::IoCtx::set_pool_full_try()
 {
   io_ctx_impl->extra_op_flags |= CEPH_OSD_FLAG_FULL_TRY;
index 0e3d40e7008923b728d3ae44e6b78eecb88ee95c..8a8e87a33625d7c50e4f415986d85df0194888b7 100644 (file)
@@ -939,6 +939,9 @@ librados::IoCtx duplicate_io_ctx(librados::IoCtx& io_ctx) {
       ctx->write_snap_context(
         {{snapc.seq, {snapc.snaps.begin(), snapc.snaps.end()}}});
     }
+    if (data_ctx.get_pool_full_try()) {
+      ctx->full_try(true);
+    }
 
     // atomically reset the data IOContext to new version
     atomic_store(&data_io_context, ctx);
index e1a6800b03788391306d2b089ab5f8943fdf4d38..53bee26f70160557695b925a3ecd70e2d7e3750b 100644 (file)
@@ -2118,6 +2118,62 @@ TEST_F(TestLibRBD, ConcurrentCreatesUnvalidatedPool)
   rados_ioctx_destroy(ioctx);
 }
 
+TEST_F(TestLibRBD, CreateThickRemoveFullTry)
+{
+  REQUIRE(!is_librados_test_stub(_rados));
+
+  rados_ioctx_t ioctx;
+  auto pool_name = create_pool(true);
+  ASSERT_EQ(0, rados_ioctx_create(_cluster, pool_name.c_str(), &ioctx));
+
+  int order = 0;
+  auto image_name = get_temp_image_name();
+  uint64_t quota = 10 << 20;
+  uint64_t size = 5 * quota;
+  ASSERT_EQ(0, create_image(ioctx, image_name.c_str(), size, &order));
+
+  // FIXME: this is a workaround for rbd_trash object being created
+  // on the first remove -- pre-create it to avoid bumping into quota
+  ASSERT_EQ(0, rbd_remove(ioctx, image_name.c_str()));
+  ASSERT_EQ(0, create_image(ioctx, image_name.c_str(), size, &order));
+
+  std::string cmdstr = "{\"prefix\": \"osd pool set-quota\", \"pool\": \"" +
+      pool_name + "\", \"field\": \"max_bytes\", \"val\": \"" +
+      std::to_string(quota) + "\"}";
+  char *cmd[1];
+  cmd[0] = (char *)cmdstr.c_str();
+  ASSERT_EQ(0, rados_mon_command(_cluster, (const char **)cmd, 1, "", 0,
+                                 nullptr, 0, nullptr, 0));
+
+  rados_set_pool_full_try(ioctx);
+
+  rbd_image_t image;
+  ASSERT_EQ(0, rbd_open(ioctx, image_name.c_str(), &image, nullptr));
+
+  uint64_t off;
+  size_t len = 1 << 20;
+  ssize_t ret;
+  for (off = 0; off < size; off += len) {
+    ret = rbd_write_zeroes(image, off, len,
+                           RBD_WRITE_ZEROES_FLAG_THICK_PROVISION, 0);
+    if (ret < 0) {
+      break;
+    }
+    ASSERT_EQ(ret, len);
+    sleep(1);
+  }
+  ASSERT_TRUE(off >= quota && off < size);
+  ASSERT_EQ(ret, -EDQUOT);
+
+  ASSERT_EQ(0, rbd_close(image));
+
+  // make sure we have latest map that marked the pool full
+  ASSERT_EQ(0, rados_wait_for_latest_osdmap(_cluster));
+  ASSERT_EQ(0, rbd_remove(ioctx, image_name.c_str()));
+
+  rados_ioctx_destroy(ioctx);
+}
+
 TEST_F(TestLibRBD, TestIO)
 {
   rados_ioctx_t ioctx;