mirror of
https://github.com/ceph/ceph
synced 2025-02-19 08:57:27 +00:00
librbd: owner_lock should be held during flush request
Flush might result in the cache writing out dirty objects, which would require that the owner_lock be held. Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
a38f9e5104
commit
c9142fe353
@ -735,7 +735,7 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type,
|
||||
ldout(ictx->cct, 20) << "snap_create_helper " << ictx << " " << snap_name
|
||||
<< dendl;
|
||||
|
||||
int r = ictx_check(ictx);
|
||||
int r = ictx_check(ictx, true);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
@ -835,7 +835,7 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type,
|
||||
ldout(ictx->cct, 20) << "snap_remove_helper " << ictx << " " << snap_name
|
||||
<< dendl;
|
||||
|
||||
int r = ictx_check(ictx);
|
||||
int r = ictx_check(ictx, true);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
@ -1442,10 +1442,10 @@ reprotect_and_return_err:
|
||||
}
|
||||
}
|
||||
|
||||
p_imctx->md_lock.get_write();
|
||||
r = ictx_refresh(p_imctx);
|
||||
p_imctx->md_lock.put_write();
|
||||
|
||||
{
|
||||
RWLock::RLocker owner_locker(p_imctx->owner_lock);
|
||||
r = ictx_refresh(p_imctx);
|
||||
}
|
||||
if (r == 0) {
|
||||
p_imctx->snap_lock.get_read();
|
||||
r = p_imctx->is_snap_protected(p_imctx->snap_id, &snap_protected);
|
||||
@ -2076,7 +2076,7 @@ reprotect_and_return_err:
|
||||
<< size << dendl;
|
||||
ictx->snap_lock.put_read();
|
||||
|
||||
int r = ictx_check(ictx);
|
||||
int r = ictx_check(ictx, true);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
@ -2217,7 +2217,7 @@ reprotect_and_return_err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ictx_check(ImageCtx *ictx)
|
||||
int ictx_check(ImageCtx *ictx, bool owner_locked)
|
||||
{
|
||||
CephContext *cct = ictx->cct;
|
||||
ldout(cct, 20) << "ictx_check " << ictx << dendl;
|
||||
@ -2227,9 +2227,13 @@ reprotect_and_return_err:
|
||||
ictx->refresh_lock.Unlock();
|
||||
|
||||
if (needs_refresh) {
|
||||
RWLock::WLocker l(ictx->md_lock);
|
||||
|
||||
int r = ictx_refresh(ictx);
|
||||
int r;
|
||||
if (owner_locked) {
|
||||
r = ictx_refresh(ictx);
|
||||
} else {
|
||||
RWLock::RLocker owner_lock(ictx->owner_lock);
|
||||
r = ictx_refresh(ictx);
|
||||
}
|
||||
if (r < 0) {
|
||||
lderr(cct) << "Error re-reading rbd header: " << cpp_strerror(-r)
|
||||
<< dendl;
|
||||
@ -2277,6 +2281,9 @@ reprotect_and_return_err:
|
||||
|
||||
int ictx_refresh(ImageCtx *ictx)
|
||||
{
|
||||
assert(ictx->owner_lock.is_locked());
|
||||
RWLock::WLocker md_locker(ictx->md_lock);
|
||||
|
||||
CephContext *cct = ictx->cct;
|
||||
bufferlist bl, bl2;
|
||||
|
||||
@ -2790,9 +2797,10 @@ reprotect_and_return_err:
|
||||
}
|
||||
}
|
||||
|
||||
ictx->md_lock.get_write();
|
||||
r = ictx_refresh(ictx);
|
||||
ictx->md_lock.put_write();
|
||||
{
|
||||
RWLock::RLocker owner_locker(ictx->owner_lock);
|
||||
r = ictx_refresh(ictx);
|
||||
}
|
||||
if (r < 0)
|
||||
goto err_close;
|
||||
|
||||
@ -2908,7 +2916,7 @@ reprotect_and_return_err:
|
||||
|
||||
int r;
|
||||
// ictx_check also updates parent data
|
||||
if ((r = ictx_check(ictx)) < 0) {
|
||||
if ((r = ictx_check(ictx, true)) < 0) {
|
||||
lderr(cct) << "ictx_check failed" << dendl;
|
||||
return r;
|
||||
}
|
||||
@ -2993,7 +3001,7 @@ reprotect_and_return_err:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int r = ictx_check(ictx);
|
||||
int r = ictx_check(ictx, true);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
@ -3238,7 +3246,10 @@ reprotect_and_return_err:
|
||||
<< " len = " << len << dendl;
|
||||
|
||||
// ensure previous writes are visible to listsnaps
|
||||
_flush(ictx);
|
||||
{
|
||||
RWLock::RLocker owner_locker(ictx->owner_lock);
|
||||
_flush(ictx);
|
||||
}
|
||||
|
||||
int r = ictx_check(ictx);
|
||||
if (r < 0)
|
||||
@ -3689,13 +3700,17 @@ reprotect_and_return_err:
|
||||
}
|
||||
|
||||
ictx->user_flushed();
|
||||
r = _flush(ictx);
|
||||
{
|
||||
RWLock::RLocker owner_locker(ictx->owner_lock);
|
||||
r = _flush(ictx);
|
||||
}
|
||||
ictx->perfcounter->inc(l_librbd_flush);
|
||||
return r;
|
||||
}
|
||||
|
||||
int _flush(ImageCtx *ictx)
|
||||
{
|
||||
assert(ictx->owner_lock.is_locked());
|
||||
CephContext *cct = ictx->cct;
|
||||
int r;
|
||||
// flush any outstanding writes
|
||||
|
@ -117,7 +117,7 @@ namespace librbd {
|
||||
int add_snap(ImageCtx *ictx, const char *snap_name);
|
||||
int rm_snap(ImageCtx *ictx, const char *snap_name, uint64_t snap_id);
|
||||
int refresh_parent(ImageCtx *ictx);
|
||||
int ictx_check(ImageCtx *ictx);
|
||||
int ictx_check(ImageCtx *ictx, bool owner_locked=false);
|
||||
int ictx_refresh(ImageCtx *ictx);
|
||||
int copy(ImageCtx *ictx, IoCtx& dest_md_ctx, const char *destname,
|
||||
ProgressContext &prog_ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user