int ImageCtx::get_features(snap_t in_snap_id, uint64_t *out_features) const
{
+ assert(snap_lock.is_locked());
if (in_snap_id == CEPH_NOSNAP) {
*out_features = features;
return 0;
/**
* Lock ordering:
- * owner_lock, md_lock, cache_lock, snap_lock, parent_lock, refresh_lock,
- * object_map_lock, async_op_lock
+ *
+ * owner_lock, md_lock, cache_lock, snap_lock, parent_lock,
+ * refresh_lock, object_map_lock, async_op_lock
*/
RWLock owner_lock; // protects exclusive lock leadership updates
RWLock md_lock; // protects access to the mutable image metadata that
// isn't guarded by other locks below
// (size, features, image locks, etc)
Mutex cache_lock; // used as client_lock for the ObjectCacher
- RWLock snap_lock; // protects snapshot-related member variables:
+ RWLock snap_lock; // protects snapshot-related member variables and features
RWLock parent_lock; // protects parent_md and parent
Mutex refresh_lock; // protects refresh_seq and last_refresh
RWLock object_map_lock; // protects object map updates
uint64_t get_image_size(librados::snap_t in_snap_id) const;
int get_features(librados::snap_t in_snap_id,
uint64_t *out_features) const;
+ bool test_features(uint64_t test_features) const;
int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const;
const parent_info* get_parent_info(librados::snap_t in_snap_id) const;
int64_t get_parent_pool_id(librados::snap_t in_snap_id) const;
}
void ObjectMap::refresh(uint64_t snap_id)
-{
- if ((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) == 0) {
+{
+ assert(m_image_ctx.snap_lock.is_locked());
+ uint64_t features;
+ m_image_ctx.get_features(m_image_ctx.snap_id, &features);
+ if ((features & RBD_FEATURE_OBJECT_MAP) == 0) {
return;
}
}
void ObjectMap::rollback(uint64_t snap_id) {
- if ((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) == 0) {
+ assert(m_image_ctx.snap_lock.is_wlocked());
+ uint64_t features;
+ m_image_ctx.get_features(snap_id, &features);
+ if ((features & RBD_FEATURE_OBJECT_MAP) == 0) {
return;
}
}
void ObjectMap::snapshot(uint64_t snap_id) {
- if ((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) == 0) {
+ assert(m_image_ctx.snap_lock.is_wlocked());
+ uint64_t features;
+ m_image_ctx.get_features(CEPH_NOSNAP, &features);
+ if ((features & RBD_FEATURE_OBJECT_MAP) == 0) {
return;
}
int r = ictx_check(ictx);
if (r < 0)
return r;
- RWLock::RLocker l(ictx->md_lock);
- RWLock::RLocker l2(ictx->snap_lock);
+ RWLock::RLocker l(ictx->snap_lock);
return ictx->get_features(ictx->snap_id, features);
}
src->md_lock.get_read();
src->snap_lock.get_read();
+ uint64_t src_features;
+ src->get_features(src->snap_id, &src_features);
uint64_t src_size = src->get_image_size(src->snap_id);
src->snap_lock.put_read();
src->md_lock.put_read();
int r = create(dest_md_ctx, destname, src_size, src->old_format,
- src->features, &order, src->stripe_unit, src->stripe_count);
+ src_features, &order, src->stripe_unit, src->stripe_count);
if (r < 0) {
lderr(cct) << "header creation failed" << dendl;
return r;