diff options
author | Josh Durgin <josh.durgin@inktank.com> | 2013-02-25 11:33:48 -0800 |
---|---|---|
committer | Josh Durgin <josh.durgin@inktank.com> | 2013-02-25 11:36:58 -0800 |
commit | 5806226cf0743bb44eaf7bc815897c6846d43233 (patch) | |
tree | 33e2f2a4275b867e3d824c49de10f52c672e33a5 | |
parent | 0cd215ee5b4768012041006377e10eeff53de7b0 (diff) | |
download | ceph-5806226cf0743bb44eaf7bc815897c6846d43233.tar.gz |
librbd: drop snap_lock before invalidating cache
Writeback will take the snap_lock, so read everything we need under it
before invalidating the cache. This avoids a recursive lock when writeback
uses snap_lock while snap_rollback() was holding it.
Remove a not-very-useful debugging message that depended on snap_lock being held.
Fixes: #4249
Backport: bobtail
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r-- | src/librbd/internal.cc | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 33b948d2310..a4c25dfaa52 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1749,17 +1749,23 @@ reprotect_and_return_err: return r; Mutex::Locker l(ictx->md_lock); - Mutex::Locker l2(ictx->snap_lock); - if (!ictx->snap_exists) - return -ENOENT; + snap_t snap_id; + uint64_t new_size; + { + // need to drop snap_lock before invalidating cache + Mutex::Locker l2(ictx->snap_lock); + if (!ictx->snap_exists) + return -ENOENT; - if (ictx->snap_id != CEPH_NOSNAP || ictx->read_only) - return -EROFS; + if (ictx->snap_id != CEPH_NOSNAP || ictx->read_only) + return -EROFS; - snap_t snap_id = ictx->get_snap_id(snap_name); - if (snap_id == CEPH_NOSNAP) { - lderr(cct) << "No such snapshot found." << dendl; - return -ENOENT; + snap_id = ictx->get_snap_id(snap_name); + if (snap_id == CEPH_NOSNAP) { + lderr(cct) << "No such snapshot found." << dendl; + return -ENOENT; + } + new_size = ictx->get_image_size(ictx->snap_id); } // need to flush any pending writes before resizing and rolling back - @@ -1767,9 +1773,6 @@ reprotect_and_return_err: // the current version, so we have to invalidate that too. ictx->invalidate_cache(); - uint64_t new_size = ictx->get_image_size(ictx->snap_id); - ictx->get_snap_size(snap_name, &new_size); - ldout(cct, 2) << "resizing to snapshot size..." << dendl; NoOpProgressContext no_op; r = resize_helper(ictx, new_size, no_op); @@ -1785,10 +1788,6 @@ reprotect_and_return_err: return r; } - snap_t new_snap_id = ictx->get_snap_id(snap_name); - ldout(cct, 20) << "snap_id is " << ictx->snap_id << " new snap_id is " - << new_snap_id << dendl; - notify_change(ictx->md_ctx, ictx->header_oid, NULL, ictx); ictx->perfcounter->inc(l_librbd_snap_rollback); |