template <typename I>
void ExclusiveLock<I>::handle_init_complete(uint64_t features) {
- ldout(m_image_ctx.cct, 10) << "features=" << features << dendl;
+ ldout(m_image_ctx.cct, 10) << ": features=" << features << dendl;
if ((features & RBD_FEATURE_JOURNALING) != 0) {
m_image_ctx.io_work_queue->set_require_lock_on_read();
return -ENOENT;
}
- bool ImageCtx::test_flags(uint64_t flags) const
+ int ImageCtx::test_flags(uint64_t flags, bool *flags_set) const
{
RWLock::RLocker l(snap_lock);
- return test_flags(flags, snap_lock);
+ return test_flags(flags, snap_lock, flags_set);
}
- bool ImageCtx::test_flags(uint64_t flags, const RWLock &in_snap_lock) const
+ int ImageCtx::test_flags(uint64_t flags, const RWLock &in_snap_lock,
+ bool *flags_set) const
{
assert(snap_lock.is_locked());
uint64_t snap_flags;
- get_flags(snap_id, &snap_flags);
- return ((snap_flags & flags) == flags);
+ int r = get_flags(snap_id, &snap_flags);
+ if (r < 0) {
+ return r;
+ }
+ *flags_set = ((snap_flags & flags) == flags);
+ return 0;
}
int ImageCtx::update_flags(snap_t in_snap_id, uint64_t flag, bool enabled)
bool test_features(uint64_t test_features,
const RWLock &in_snap_lock) const;
int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const;
- bool test_flags(uint64_t test_flags) const;
- bool test_flags(uint64_t test_flags, const RWLock &in_snap_lock) const;
+ int test_flags(uint64_t test_flags, bool *flags_set) const;
+ int test_flags(uint64_t test_flags, const RWLock &in_snap_lock,
+ bool *flags_set) const;
int update_flags(librados::snap_t in_snap_id, uint64_t flag, bool enabled);
const ParentInfo* get_parent_info(librados::snap_t in_snap_id) const;
// Fall back to default logic if object map is disabled or invalid
if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
- m_image_ctx.snap_lock) ||
- m_image_ctx.test_flags(RBD_FLAG_OBJECT_MAP_INVALID,
- m_image_ctx.snap_lock)) {
+ m_image_ctx.snap_lock)) {
+ return true;
+ }
+
+ bool flags_set;
+ int r = m_image_ctx.test_flags(RBD_FLAG_OBJECT_MAP_INVALID,
+ m_image_ctx.snap_lock, &flags_set);
+ if (r < 0 || flags_set) {
return true;
}
if (m_force) {
Context *ctx = create_context_callback<
klass, &klass::handle_exclusive_lock_force>(this);
- m_image_ctx->exclusive_lock->shut_down(ctx);
+ m_exclusive_lock = m_image_ctx->exclusive_lock;
+ m_exclusive_lock->shut_down(ctx);
} else {
Context *ctx = create_context_callback<
klass, &klass::handle_exclusive_lock>(this);
Context *RemoveRequest<I>::handle_exclusive_lock_force(int *result) {
ldout(m_cct, 20) << ": r=" << *result << dendl;
+ delete m_exclusive_lock;
+ m_exclusive_lock = nullptr;
+
if (*result < 0) {
lderr(m_cct) << "error shutting down exclusive lock: "
<< cpp_strerror(*result) << dendl;
bool m_unknown_format = true;
ImageCtxT *m_image_ctx;
+ decltype(m_image_ctx->exclusive_lock) m_exclusive_lock = nullptr;
+
int m_ret_val = 0;
bufferlist m_out_bl;
std::list<obj_watch_t> m_watchers;
ictx->exclusive_lock->is_lock_owner();
if (is_locked) {
C_SaferCond ctx;
- ictx->exclusive_lock->shut_down(&ctx);
+ auto exclusive_lock = ictx->exclusive_lock;
+ exclusive_lock->shut_down(&ctx);
ictx->owner_lock.put_read();
int r = ctx.wait();
if (r < 0) {
lderr(cct) << "error shutting down exclusive lock" << dendl;
}
+ delete exclusive_lock;
} else {
ictx->owner_lock.put_read();
}
}
bool Request::invalidate() {
- if (m_image_ctx.test_flags(RBD_FLAG_OBJECT_MAP_INVALID)) {
+ bool flags_set;
+ int r = m_image_ctx.test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set);
+ if (r == 0 && flags_set) {
return true;
}
break
self.get_next_chunk()
+ def __dealloc__(self):
+ if self.last_read:
+ free(self.last_read)
+
def get_next_chunk(self):
cdef:
char *c_keys = NULL
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_FALSE(flags_set);
C_SaferCond cond_ctx;
AsyncRequest<> *request = new InvalidateRequest<>(*ictx, CEPH_NOSNAP, false, &cond_ctx);
}
ASSERT_EQ(0, cond_ctx.wait());
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
}
TEST_F(TestMockObjectMapInvalidateRequest, UpdatesHeadOnDiskFlag) {
ASSERT_EQ(0, ictx->get_flags(snap_id, &flags));
ASSERT_NE(0U, flags & RBD_FLAG_OBJECT_MAP_INVALID);
}
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
expect_unlock_exclusive_lock(*ictx);
}
ASSERT_EQ(0, ictx->get_flags(snap_id, &flags));
ASSERT_EQ(0U, flags & RBD_FLAG_OBJECT_MAP_INVALID);
}
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
expect_unlock_exclusive_lock(*ictx);
}
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_FALSE(flags_set);
C_SaferCond lock_ctx;
{
ASSERT_EQ(0, ictx->md_ctx.write_full(oid, bl));
ASSERT_EQ(0, when_open_object_map(ictx));
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
}
TEST_F(TestObjectMap, RefreshInvalidatesWhenTooSmall) {
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_FALSE(flags_set);
C_SaferCond lock_ctx;
{
ASSERT_EQ(0, ictx->md_ctx.operate(oid, &op));
ASSERT_EQ(0, when_open_object_map(ictx));
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
}
TEST_F(TestObjectMap, InvalidateFlagOnDisk) {
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_FALSE(flags_set);
C_SaferCond lock_ctx;
{
ASSERT_EQ(0, ictx->md_ctx.write_full(oid, bl));
ASSERT_EQ(0, when_open_object_map(ictx));
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
}
TEST_F(TestObjectMap, InvalidateFlagInMemoryOnly) {
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ bool flags_set;
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_FALSE(flags_set);
std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
bufferlist valid_bl;
ASSERT_EQ(0, ictx->md_ctx.write_full(oid, corrupt_bl));
ASSERT_EQ(0, when_open_object_map(ictx));
- ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_TRUE(flags_set);
ASSERT_EQ(0, ictx->md_ctx.write_full(oid, valid_bl));
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID));
+ ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+ ASSERT_FALSE(flags_set);
}
rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx);
rbd_image_t image;
- int order = 0;
+ int order = 0;
std::string name = get_temp_image_name();
uint64_t size = 2 << 20;
int num_snaps, max_size = 10;
rbd_snap_info_t snaps[max_size];
-
+
ASSERT_EQ(0, create_image(ioctx, name.c_str(), size, &order));
ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL));
ASSERT_EQ(0, rbd_snap_create(image, "snap1"));
num_snaps = rbd_snap_list(image, snaps, &max_size);
- ASSERT_EQ(1, num_snaps);
+ ASSERT_EQ(1, num_snaps);
ASSERT_EQ(0, test_get_snapshot_timestamp(image, snaps[0].id));
-
+ free((void *)snaps[0].name);
ASSERT_EQ(0, rbd_snap_create(image, "snap2"));
num_snaps = rbd_snap_list(image, snaps, &max_size);
ASSERT_EQ(2, num_snaps);
- ASSERT_EQ(0, test_get_snapshot_timestamp(image, snaps[0].id));
+ ASSERT_EQ(0, test_get_snapshot_timestamp(image, snaps[0].id));
ASSERT_EQ(0, test_get_snapshot_timestamp(image, snaps[1].id));
+ free((void *)snaps[0].name);
+ free((void *)snaps[1].name);
ASSERT_EQ(0, rbd_close(image));
ASSERT_EQ(0, rbd_close(image));
ASSERT_EQ(0, rbd_close(image1));
ASSERT_EQ(0, rbd_close(image2));
+ rados_ioctx_destroy(ioctx);
}
TEST_F(TestLibRBD, MetadataPP)
RWLock::RLocker snap_locker(m_local_image_ctx->snap_lock);
local_size = m_local_image_ctx->get_image_size(
m_local_image_ctx->snap_id);
- ASSERT_FALSE(m_local_image_ctx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID,
- m_local_image_ctx->snap_lock));
+ bool flags_set;
+ ASSERT_EQ(0, m_local_image_ctx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID,
+ m_local_image_ctx->snap_lock,
+ &flags_set));
+ ASSERT_FALSE(flags_set);
}
ASSERT_EQ(remote_size, local_size);