mirror of
https://github.com/ceph/ceph
synced 2025-01-20 18:21:57 +00:00
Merge pull request #4623 from ceph/wip-11577
librbd: possible deadlock during copyup Reviewed-by: Josh Durgin <jdurgin@redhat.com>
This commit is contained in:
commit
0543003f43
@ -416,6 +416,7 @@ namespace librbd {
|
||||
m_state = LIBRBD_AIO_WRITE_PRE;
|
||||
FunctionContext *ctx = new FunctionContext(
|
||||
boost::bind(&AioRequest::complete, this, _1));
|
||||
RWLock::RLocker snap_locker(m_ictx->snap_lock);
|
||||
RWLock::WLocker object_map_locker(m_ictx->object_map_lock);
|
||||
if (!m_ictx->object_map.aio_update(m_object_no, new_state,
|
||||
current_state, ctx)) {
|
||||
@ -451,6 +452,7 @@ namespace librbd {
|
||||
m_state = LIBRBD_AIO_WRITE_POST;
|
||||
FunctionContext *ctx = new FunctionContext(
|
||||
boost::bind(&AioRequest::complete, this, _1));
|
||||
RWLock::RLocker snap_locker(m_ictx->snap_lock);
|
||||
RWLock::WLocker object_map_locker(m_ictx->object_map_lock);
|
||||
if (!m_ictx->object_map.aio_update(m_object_no, OBJECT_NONEXISTENT,
|
||||
OBJECT_PENDING, ctx)) {
|
||||
|
@ -172,6 +172,7 @@ void AsyncTrimRequest::send_pre_remove() {
|
||||
} else {
|
||||
// flag the objects as pending deletion
|
||||
Context *ctx = create_callback_context();
|
||||
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
|
||||
RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock);
|
||||
if (!m_image_ctx.object_map.aio_update(m_delete_start, m_num_objects,
|
||||
OBJECT_PENDING, OBJECT_EXISTS,
|
||||
@ -210,6 +211,7 @@ bool AsyncTrimRequest::send_post_remove() {
|
||||
} else {
|
||||
// flag the pending objects as removed
|
||||
Context *ctx = create_callback_context();
|
||||
RWLock::RLocker snap_lock(m_image_ctx.snap_lock);
|
||||
RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock);
|
||||
if (!m_image_ctx.object_map.aio_update(m_delete_start, m_num_objects,
|
||||
OBJECT_NONEXISTENT,
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
uint64_t snap_id = m_snap_ids[m_snap_id_idx];
|
||||
if (snap_id == CEPH_NOSNAP) {
|
||||
RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
|
||||
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
|
||||
RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock);
|
||||
assert(m_image_ctx.image_watcher->is_lock_owner());
|
||||
bool sent = m_image_ctx.object_map.aio_update(m_object_no, OBJECT_EXISTS,
|
||||
@ -49,7 +50,7 @@ public:
|
||||
}
|
||||
|
||||
uint8_t state = OBJECT_EXISTS;
|
||||
if (m_image_ctx.test_features(RBD_FEATURE_DEEP_FLATTEN) &&
|
||||
if (m_image_ctx.test_features(RBD_FEATURE_FAST_DIFF) &&
|
||||
m_snap_id_idx + 1 < m_snap_ids.size()) {
|
||||
state = OBJECT_EXISTS_CLEAN;
|
||||
}
|
||||
|
@ -56,8 +56,13 @@ ImageWatcher::~ImageWatcher()
|
||||
}
|
||||
|
||||
bool ImageWatcher::is_lock_supported() const {
|
||||
assert(m_image_ctx.owner_lock.is_locked());
|
||||
RWLock::RLocker l(m_image_ctx.snap_lock);
|
||||
return is_lock_supported(m_image_ctx.snap_lock);
|
||||
}
|
||||
|
||||
bool ImageWatcher::is_lock_supported(const RWLock &) const {
|
||||
assert(m_image_ctx.owner_lock.is_locked());
|
||||
assert(m_image_ctx.snap_lock.is_locked());
|
||||
return ((m_image_ctx.features & RBD_FEATURE_EXCLUSIVE_LOCK) != 0 &&
|
||||
!m_image_ctx.read_only && m_image_ctx.snap_id == CEPH_NOSNAP);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ namespace librbd {
|
||||
~ImageWatcher();
|
||||
|
||||
bool is_lock_supported() const;
|
||||
bool is_lock_supported(const RWLock &snap_lock) const;
|
||||
bool is_lock_owner() const;
|
||||
|
||||
int register_watch();
|
||||
|
@ -450,9 +450,10 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no,
|
||||
const boost::optional<uint8_t> ¤t_state,
|
||||
Context *on_finish)
|
||||
{
|
||||
assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP));
|
||||
assert(m_image_ctx.snap_lock.is_locked());
|
||||
assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
|
||||
assert(m_image_ctx.owner_lock.is_locked());
|
||||
assert(!m_image_ctx.image_watcher->is_lock_supported() ||
|
||||
assert(!m_image_ctx.image_watcher->is_lock_supported(m_image_ctx.snap_lock) ||
|
||||
m_image_ctx.image_watcher->is_lock_owner());
|
||||
assert(m_image_ctx.object_map_lock.is_wlocked());
|
||||
assert(start_object_no < end_object_no);
|
||||
|
@ -482,7 +482,7 @@ TEST_F(TestInternal, SnapshotCopyup)
|
||||
// verify the object map was properly updated
|
||||
if ((ictx2->features & RBD_FEATURE_OBJECT_MAP) != 0) {
|
||||
uint8_t state = OBJECT_EXISTS;
|
||||
if ((ictx2->features & RBD_FEATURE_DEEP_FLATTEN) != 0 &&
|
||||
if ((ictx2->features & RBD_FEATURE_FAST_DIFF) != 0 &&
|
||||
it != snaps.begin() && snap_name != NULL) {
|
||||
state = OBJECT_EXISTS_CLEAN;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user