*/
int metadata_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
- map<string, bufferlist> vals;
- map<string, string> out_map;
+ map<string, bufferlist> raw_data, data;
int r = cls_cxx_map_get_vals(hctx, RBD_METADATA_KEY_PREFIX, RBD_METADATA_KEY_PREFIX,
- RBD_MAX_METAADATA_KEYS, &vals);
+ RBD_MAX_METAADATA_KEYS, &raw_data);
if (r < 0) {
CLS_ERR("failed to read the vals off of disk: %s", cpp_strerror(r).c_str());
return r;
bufferlist::iterator iter;
string v;
- for (map<string, bufferlist>::iterator it = vals.begin();
- it != vals.end(); ++it) {
- iter = it->second.begin();
- try {
- ::decode(v, iter);
- } catch (const buffer::error &err) {
- CLS_ERR("failed to decode the vals off of disk");
- return -EINVAL;
- }
-
+ for (map<string, bufferlist>::iterator it = raw_data.begin(); it != raw_data.end(); ++it) {
assert(it->first.find(RBD_METADATA_KEY_PREFIX, 0) == 0);
- out_map[metadata_name_from_key(it->first)] = v;
+ data[metadata_name_from_key(it->first)].swap(it->second);
}
- ::encode(out_map, *out);
+ ::encode(data, *out);
return 0;
}
/**
* Input:
- * @param key
- * @param value
+ * @param data <map(key, value)>
*
* Output:
* @returns 0 on success, negative error code on failure
*/
int metadata_set(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
- string key, value;
+ map<string, bufferlist> data, raw_data;
bufferlist::iterator iter = in->begin();
try {
- ::decode(key, iter);
- ::decode(value, iter);
+ ::decode(data, iter);
} catch (const buffer::error &err) {
return -EINVAL;
}
- CLS_LOG(20, "metdata_set key=%s value=%s", key.c_str(), value.c_str());
-
- bufferlist bl;
- ::encode(value, bl);
- int r = cls_cxx_map_set_val(hctx, metadata_key_for_name(key), &bl);
+ for (map<string, bufferlist>::iterator it = data.begin();
+ it != data.end(); ++it) {
+ CLS_LOG(20, "metdata_set key=%s value=%s", it->first.c_str(), it->second.c_str());
+ raw_data[metadata_key_for_name(it->first)].swap(it->second);
+ }
+ int r = cls_cxx_map_set_vals(hctx, &raw_data);
if (r < 0) {
CLS_ERR("error writing metadata: %d", r);
return r;
*/
int metadata_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
- string key, value;
+ string key;
+ bufferlist value;
bufferlist::iterator iter = in->begin();
try {
CLS_LOG(20, "metdata_get key=%s", key.c_str());
- int r = read_key(hctx, metadata_key_for_name(key), &value);
+ int r = cls_cxx_map_get_val(hctx, metadata_key_for_name(key), &value);
if (r < 0) {
CLS_ERR("error get metadata: %d", r);
return r;
}
int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
- const std::string &key, const std::string &data)
+ const map<string, bufferlist> &data)
{
bufferlist in;
- ::encode(key, in);
::encode(data, in);
bufferlist out;
return ioctx->exec(oid, "rbd", "metadata_set", in, out);
}
int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
- map<string, string> *pairs)
+ map<string, bufferlist> *pairs)
{
assert(pairs);
bufferlist in, out;
int set_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
uint64_t stripe_unit, uint64_t stripe_count);
int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
- map<string, string> *pairs);
+ map<string, bufferlist> *pairs);
int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
- const std::string &key, const std::string &data);
+ const map<std::string, bufferlist> &data);
int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
const std::string &key);
int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
/**
* Returns a pair of key/value for this image
*/
- int metadata_list(std::map<std::string, std::string> *pairs);
+ int metadata_list(std::map<std::string, ceph::bufferlist> *pairs);
private:
friend class RBD;
int remove_r;
librbd::NoOpProgressContext no_op;
ImageCtx *c_imctx = NULL;
- map<string, string> pairs;
+ map<string, bufferlist> pairs;
// make sure parent snapshot exists
ImageCtx *p_imctx = new ImageCtx(p_name, "", p_snap_name, p_ioctx, true);
r = open_image(p_imctx);
lderr(cct) << "couldn't list metadata: " << r << dendl;
goto err_close_child;
}
- for (map<string, string>::iterator it = pairs.begin(); it != pairs.end(); ++it) {
- r = cls_client::metadata_set(&c_ioctx, c_imctx->header_oid,
- it->first, it->second);
- if (r < 0) {
- lderr(cct) << "couldn't set metadata: " << r << dendl;
- goto err_close_child;
- }
+ r = cls_client::metadata_set(&c_ioctx, c_imctx->header_oid, pairs);
+ if (r < 0) {
+ lderr(cct) << "couldn't set metadata: " << r << dendl;
+ goto err_close_child;
}
p_imctx->md_lock.get_write();
return -EINVAL;
}
int r;
- map<string, string> pairs;
+ map<string, bufferlist> pairs;
r = cls_client::metadata_list(&src->md_ctx, src->header_oid, &pairs);
if (r < 0) {
lderr(cct) << "couldn't list metadata: " << r << dendl;
return r;
}
- for (map<string, string>::iterator it = pairs.begin(); it != pairs.end(); ++it) {
- r = cls_client::metadata_set(&dest->md_ctx, dest->header_oid, it->first, it->second);
- if (r < 0) {
- lderr(cct) << "couldn't set metadata: " << r << dendl;
- return r;
- }
+ r = cls_client::metadata_set(&dest->md_ctx, dest->header_oid, pairs);
+ if (r < 0) {
+ lderr(cct) << "couldn't set metadata: " << r << dendl;
+ return r;
}
SimpleThrottle throttle(cct->_conf->rbd_concurrent_management_ops, false);
return r;
}
- return cls_client::metadata_set(&ictx->md_ctx, ictx->header_oid, key, value);
+ map<string, bufferlist> data;
+ data[key].append(value);
+ return cls_client::metadata_set(&ictx->md_ctx, ictx->header_oid, data);
}
int metadata_remove(ImageCtx *ictx, const string &key)
return cls_client::metadata_remove(&ictx->md_ctx, ictx->header_oid, key);
}
- int metadata_list(ImageCtx *ictx, map<string, string> *pairs)
+ int metadata_list(ImageCtx *ictx, map<string, bufferlist> *pairs)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "metadata_list " << ictx << dendl;
int flush(ImageCtx *ictx);
int _flush(ImageCtx *ictx);
int invalidate_cache(ImageCtx *ictx);
- int metadata_list(ImageCtx *ictx, map<string, string> *pairs);
+ int metadata_list(ImageCtx *ictx, map<string, bufferlist> *pairs);
int metadata_get(ImageCtx *ictx, const std::string &key, std::string *value);
int metadata_set(ImageCtx *ictx, const std::string &key, const std::string &value);
int metadata_remove(ImageCtx *ictx, const std::string &key);
return r;
}
- int Image::metadata_list(map<string, string> *pairs)
+ int Image::metadata_list(map<string, bufferlist> *pairs)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, metadata_list_enter, ictx);
int r = librbd::metadata_list(ictx, pairs);
if (r >= 0) {
- for (map<string, string>::const_iterator it = pairs->begin();
+ for (map<string, bufferlist>::iterator it = pairs->begin();
it != pairs->end(); ++it) {
tracepoint(librbd, metadata_list_entry, it->first.c_str(), it->second.c_str());
}
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, metadata_list_enter, ictx);
- map<string, string> pairs;
+ map<string, bufferlist> pairs;
int r = librbd::metadata_list(ictx, &pairs);
size_t key_total_len = 0, val_total_len = 0;
bool too_short = false;
- for (map<string, string>::iterator it = pairs.begin();
+ for (map<string, bufferlist>::iterator it = pairs.begin();
it != pairs.end(); ++it) {
key_total_len += it->first.size() + 1;
val_total_len += it->second.length() + 1;
char *key_p = key, *value_p = value;
- for (map<string, string>::iterator it = pairs.begin();
+ for (map<string, bufferlist>::iterator it = pairs.begin();
it != pairs.end(); ++it) {
strncpy(key_p, it->first.c_str(), it->first.size());
key_p += it->first.size() + 1;
- strncpy(value_p, it->second.c_str(), it->second.size());
+ strncpy(value_p, it->second.c_str(), it->second.length());
value_p += it->second.length() + 1;
tracepoint(librbd, metadata_list_entry, it->first.c_str(), it->second.c_str());
}
static int do_metadata_list(librbd::Image& image, Formatter *f)
{
- map<string, string> pairs;
+ map<string, bufferlist> pairs;
int r;
TextTable tbl;
<< " metadata" << (one ? "" : "s") << " on this image.\n";
}
- for (map<string, string>::iterator it = pairs.begin();
+ for (map<string, bufferlist>::iterator it = pairs.begin();
it != pairs.end(); ++it) {
if (f) {
- f->dump_string(it->first.c_str(), it->second);
+ f->dump_string(it->first.c_str(), it->second.c_str());
} else {
- tbl << it->first << it->second << TextTable::endrow;
+ tbl << it->first << it->second.c_str() << TextTable::endrow;
}
}
if (!f)
string oid = get_temp_image_name();
ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid));
- map<string, string> pairs;
+ map<string, bufferlist> pairs;
string value;
ASSERT_EQ(0, metadata_list(&ioctx, oid, &pairs));
ASSERT_TRUE(pairs.empty());
- ASSERT_EQ(0, metadata_set(&ioctx, oid, "key1", "value1"));
- ASSERT_EQ(0, metadata_set(&ioctx, oid, "key2", "value2"));
+ pairs["key1"].append("value1");
+ pairs["key2"].append("value2");
+ ASSERT_EQ(0, metadata_set(&ioctx, oid, pairs));
ASSERT_EQ(0, metadata_get(&ioctx, oid, "key1", &value));
ASSERT_EQ(0, strcmp("value1", value.c_str()));
+ pairs.clear();
ASSERT_EQ(0, metadata_list(&ioctx, oid, &pairs));
ASSERT_EQ(2U, pairs.size());
- ASSERT_EQ(0, strcmp("value1", pairs["key1"].c_str()));
- ASSERT_EQ(0, strcmp("value2", pairs["key2"].c_str()));
+ ASSERT_EQ(0, strncmp("value1", pairs["key1"].c_str(), 6));
+ ASSERT_EQ(0, strncmp("value2", pairs["key2"].c_str(), 6));
pairs.clear();
ASSERT_EQ(0, metadata_remove(&ioctx, oid, "key1"));
ASSERT_TRUE(metadata_get(&ioctx, oid, "key1", &value) < 0);
ASSERT_EQ(0, metadata_list(&ioctx, oid, &pairs));
ASSERT_EQ(1U, pairs.size());
- ASSERT_EQ(0, strcmp("value2", pairs["key2"].c_str()));
+ ASSERT_EQ(0, strncmp("value2", pairs["key2"].c_str(), 6));
ioctx.close();
}
librbd::Image image1;
ASSERT_EQ(0, rbd.open(ioctx, image1, name.c_str(), NULL));
- map<string, string> pairs;
+ map<string, bufferlist> pairs;
ASSERT_EQ(0, image1.metadata_list(&pairs));
ASSERT_TRUE(pairs.empty());