#include "librbd/ImageState.h"
#include "librbd/ImageWatcher.h"
#include "librbd/ObjectMap.h"
+#include "librbd/Types.h"
#include "librbd/Utils.h"
#include "librbd/journal/DisabledPolicy.h"
#include "librbd/journal/StandardPolicy.h"
return r;
}
} else {
- RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
C_SaferCond cond_ctx;
- execute_rename(dstname, &cond_ctx);
+ {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ execute_rename(dstname, &cond_ctx);
+ }
r = cond_ctx.wait();
if (r < 0) {
m_image_ctx.image_watcher->register_watch(on_finish);
});
on_finish = new FunctionContext([this, dest_name, on_finish](int r) {
+ RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
operation::RenameRequest<I> *req = new operation::RenameRequest<I>(
m_image_ctx, on_finish, dest_name);
req->send();
if (r < 0)
return r;
- RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+ C_SaferCond cond_ctx;
{
- // need to drop snap_lock before invalidating cache
- RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
- if (!m_image_ctx.snap_exists) {
- return -ENOENT;
- }
+ RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+ {
+ // need to drop snap_lock before invalidating cache
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ if (!m_image_ctx.snap_exists) {
+ return -ENOENT;
+ }
- if (m_image_ctx.snap_id != CEPH_NOSNAP || m_image_ctx.read_only) {
- return -EROFS;
+ if (m_image_ctx.snap_id != CEPH_NOSNAP || m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ uint64_t snap_id = m_image_ctx.get_snap_id(snap_namespace, snap_name);
+ if (snap_id == CEPH_NOSNAP) {
+ lderr(cct) << "No such snapshot found." << dendl;
+ return -ENOENT;
+ }
}
- uint64_t snap_id = m_image_ctx.get_snap_id(snap_namespace, snap_name);
- if (snap_id == CEPH_NOSNAP) {
- lderr(cct) << "No such snapshot found." << dendl;
- return -ENOENT;
+ r = prepare_image_update(false);
+ if (r < 0) {
+ return -EROFS;
}
- }
- r = prepare_image_update();
- if (r < 0) {
- return -EROFS;
- }
- if (m_image_ctx.exclusive_lock != nullptr &&
- !m_image_ctx.exclusive_lock->is_lock_owner()) {
- return -EROFS;
+ execute_snap_rollback(snap_namespace, snap_name, prog_ctx, &cond_ctx);
}
- C_SaferCond cond_ctx;
- execute_snap_rollback(snap_namespace, snap_name, prog_ctx, &cond_ctx);
r = cond_ctx.wait();
if (r < 0) {
return r;
return r;
}
} else {
- RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
C_SaferCond cond_ctx;
- execute_snap_rename(snap_id, dstname, &cond_ctx);
+ {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ execute_snap_rename(snap_id, dstname, &cond_ctx);
+ }
r = cond_ctx.wait();
if (r < 0) {
return r;
}
} else {
- RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
C_SaferCond cond_ctx;
- execute_snap_protect(snap_namespace, snap_name, &cond_ctx);
+ {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ execute_snap_protect(snap_namespace, snap_name, &cond_ctx);
+ }
r = cond_ctx.wait();
if (r < 0) {
return r;
}
} else {
- RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
C_SaferCond cond_ctx;
- execute_snap_unprotect(snap_namespace, snap_name, &cond_ctx);
+ {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ execute_snap_unprotect(snap_namespace, snap_name, &cond_ctx);
+ }
r = cond_ctx.wait();
if (r < 0) {
return r;
}
+ C_SaferCond limit_ctx;
{
RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
- C_SaferCond limit_ctx;
-
- if (m_image_ctx.exclusive_lock != nullptr &&
- !m_image_ctx.exclusive_lock->is_lock_owner()) {
- C_SaferCond lock_ctx;
-
- m_image_ctx.exclusive_lock->acquire_lock(&lock_ctx);
- r = lock_ctx.wait();
- if (r < 0) {
- return r;
- }
+ r = prepare_image_update(true);
+ if (r < 0) {
+ return r;
}
execute_snap_set_limit(limit, &limit_ctx);
- r = limit_ctx.wait();
}
+ r = limit_ctx.wait();
return r;
}
ldout(cct, 5) << this << " " << __func__ << ": key=" << key << ", value="
<< value << dendl;
- string start = m_image_ctx.METADATA_CONF_PREFIX;
- size_t conf_prefix_len = start.size();
-
- if (key.size() > conf_prefix_len && !key.compare(0, conf_prefix_len, start)) {
+ std::string config_key;
+ bool config_override = util::is_metadata_config_override(key, &config_key);
+ if (config_override) {
// validate config setting
- string subkey = key.substr(conf_prefix_len, key.size() - conf_prefix_len);
- int r = md_config_t().set_val(subkey.c_str(), value);
+ int r = md_config_t().set_val(config_key.c_str(), value);
if (r < 0) {
return r;
}
return -EROFS;
}
+ C_SaferCond metadata_ctx;
{
RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
- C_SaferCond metadata_ctx;
-
- if (m_image_ctx.exclusive_lock != nullptr &&
- !m_image_ctx.exclusive_lock->is_lock_owner()) {
- C_SaferCond lock_ctx;
-
- m_image_ctx.exclusive_lock->acquire_lock(&lock_ctx);
- r = lock_ctx.wait();
- if (r < 0) {
- return r;
- }
+ r = prepare_image_update(true);
+ if (r < 0) {
+ return r;
}
execute_metadata_set(key, value, &metadata_ctx);
- r = metadata_ctx.wait();
+ }
+
+ r = metadata_ctx.wait();
+ if (config_override && r >= 0) {
+ // apply new config key immediately
+ r = m_image_ctx.state->refresh_if_required();
}
return r;
<< value << dendl;
operation::MetadataSetRequest<I> *request =
- new operation::MetadataSetRequest<I>(m_image_ctx, on_finish, key, value);
+ new operation::MetadataSetRequest<I>(m_image_ctx,
+ new C_NotifyUpdate<I>(m_image_ctx, on_finish),
+ key, value);
request->send();
}
if(r < 0)
return r;
+ C_SaferCond metadata_ctx;
{
RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
- C_SaferCond metadata_ctx;
-
- if (m_image_ctx.exclusive_lock != nullptr &&
- !m_image_ctx.exclusive_lock->is_lock_owner()) {
- C_SaferCond lock_ctx;
-
- m_image_ctx.exclusive_lock->acquire_lock(&lock_ctx);
- r = lock_ctx.wait();
- if (r < 0) {
- return r;
- }
+ r = prepare_image_update(true);
+ if (r < 0) {
+ return r;
}
execute_metadata_remove(key, &metadata_ctx);
- r = metadata_ctx.wait();
+ }
+
+ r = metadata_ctx.wait();
+
+ std::string config_key;
+ if (util::is_metadata_config_override(key, &config_key) && r >= 0) {
+ // apply new config key immediately
+ r = m_image_ctx.state->refresh_if_required();
}
return r;
ldout(cct, 5) << this << " " << __func__ << ": key=" << key << dendl;
operation::MetadataRemoveRequest<I> *request =
- new operation::MetadataRemoveRequest<I>(m_image_ctx, on_finish, key);
+ new operation::MetadataRemoveRequest<I>(
+ m_image_ctx,
+ new C_NotifyUpdate<I>(m_image_ctx, on_finish), key);
request->send();
}
template <typename I>
-int Operations<I>::prepare_image_update() {
+int Operations<I>::prepare_image_update(bool request_lock) {
assert(m_image_ctx.owner_lock.is_locked() &&
!m_image_ctx.owner_lock.is_wlocked());
- if (m_image_ctx.image_watcher == NULL) {
+ if (m_image_ctx.image_watcher == nullptr) {
return -EROFS;
}
// need to upgrade to a write lock
- bool trying_lock = false;
C_SaferCond ctx;
m_image_ctx.owner_lock.put_read();
+ bool attempting_lock = false;
{
RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
if (m_image_ctx.exclusive_lock != nullptr &&
(!m_image_ctx.exclusive_lock->is_lock_owner() ||
!m_image_ctx.exclusive_lock->accept_requests())) {
- m_image_ctx.exclusive_lock->try_acquire_lock(&ctx);
- trying_lock = true;
+
+ attempting_lock = true;
+ m_image_ctx.exclusive_lock->block_requests(0);
+
+ if (request_lock) {
+ m_image_ctx.exclusive_lock->acquire_lock(&ctx);
+ } else {
+ m_image_ctx.exclusive_lock->try_acquire_lock(&ctx);
+ }
}
}
int r = 0;
- if (trying_lock) {
+ if (attempting_lock) {
r = ctx.wait();
}
+
m_image_ctx.owner_lock.get_read();
+ if (attempting_lock && m_image_ctx.exclusive_lock != nullptr) {
+ m_image_ctx.exclusive_lock->unblock_requests();
+ }
- return r;
+ if (r < 0) {
+ return r;
+ } else if (m_image_ctx.exclusive_lock != nullptr &&
+ !m_image_ctx.exclusive_lock->is_lock_owner()) {
+ return -EROFS;
+ }
+
+ return 0;
}
template <typename I>