From c4370ff03f8ab655a009cfd9ba3a0827d8c58b11 Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Wed, 2 Jan 2013 14:15:24 -0800 Subject: [PATCH] librbd: establish watch before reading header This eliminates a window in which a race could occur when we have an image open but no watch established. The previous fix (using assert_version) did not work well with resend operations. Signed-off-by: Josh Durgin --- src/librbd/internal.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index b69e40bbbdb..0b788136b0d 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1913,25 +1913,29 @@ reprotect_and_return_err: if (r < 0) return r; - ictx->md_lock.Lock(); - r = ictx_refresh(ictx); - ictx->md_lock.Unlock(); - if (r < 0) - return r; - - _snap_set(ictx, ictx->snap_name.c_str()); - if (!ictx->read_only) { r = ictx->register_watch(); if (r < 0) { lderr(ictx->cct) << "error registering a watch: " << cpp_strerror(r) << dendl; - close_image(ictx); - return r; + goto err_close; } } + ictx->md_lock.Lock(); + r = ictx_refresh(ictx); + ictx->md_lock.Unlock(); + if (r < 0) + goto err_close; + + if ((r = _snap_set(ictx, ictx->snap_name.c_str())) < 0) + goto err_close; + return 0; + + err_close: + close_image(ictx); + return r; } void close_image(ImageCtx *ictx)