cls_rbd: get_flags now reads all snapshot flags

As a convenience, get_flags now retrieves the current image
flags as well as all historical snapshop flags with a single
librados operation.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2015-02-02 23:17:56 -05:00
parent 9e9356b1d8
commit 16e4d712ae
3 changed files with 29 additions and 11 deletions

View File

@ -245,13 +245,25 @@ namespace librbd {
}
int get_flags(librados::IoCtx *ioctx, const std::string &oid,
snapid_t snap_id, uint64_t *flags)
uint64_t *flags, const std::vector<snapid_t> &snap_ids,
vector<uint64_t> *snap_flags)
{
bufferlist inbl;
::encode(snap_id, inbl);
::encode(static_cast<snapid_t>(CEPH_NOSNAP), inbl);
librados::ObjectReadOperation op;
op.exec("rbd", "get_flags", inbl);
for (size_t i = 0; i < snap_ids.size(); ++i) {
bufferlist snapbl;
::encode(snap_ids[i], snapbl);
op.exec("rbd", "get_flags", snapbl);
}
snap_flags->clear();
snap_flags->resize(snap_ids.size());
bufferlist outbl;
int r = ioctx->exec(oid, "rbd", "get_flags", inbl, outbl);
int r = ioctx->operate(oid, &op, &outbl);
if (r < 0) {
return r;
}
@ -259,6 +271,9 @@ namespace librbd {
try {
bufferlist::iterator iter = outbl.begin();
::decode(*flags, iter);
for (size_t i = 0; i < snap_ids.size(); ++i) {
::decode((*snap_flags)[i], iter);
}
} catch (const buffer::error &err) {
return -EBADMSG;
}

View File

@ -48,7 +48,8 @@ namespace librbd {
int set_parent(librados::IoCtx *ioctx, const std::string &oid,
parent_spec pspec, uint64_t parent_overlap);
int get_flags(librados::IoCtx *ioctx, const std::string &oid,
snapid_t snap_id, uint64_t *flags);
uint64_t *flags, const std::vector<snapid_t> &snap_ids,
vector<uint64_t> *snap_flags);
void set_flags(librados::ObjectWriteOperation *op,
uint64_t flags, uint64_t mask);
int remove_parent(librados::IoCtx *ioctx, const std::string &oid);

View File

@ -1038,27 +1038,29 @@ TEST_F(TestClsRbd, flags)
ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid));
uint64_t flags;
ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags));
std::vector<snapid_t> snap_ids;
std::vector<uint64_t> snap_flags;
ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
ASSERT_EQ(0U, flags);
librados::ObjectWriteOperation op1;
set_flags(&op1, 3, 2);
ASSERT_EQ(0, ioctx.operate(oid, &op1));
ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags));
ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
ASSERT_EQ(2U, flags);
uint64_t snap_id = 10;
ASSERT_EQ(-ENOENT, get_flags(&ioctx, oid, snap_id, &flags));
snap_ids.push_back(snap_id);
ASSERT_EQ(-ENOENT, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, snap_id, "snap"));
librados::ObjectWriteOperation op2;
set_flags(&op2, 31, 4);
ASSERT_EQ(0, ioctx.operate(oid, &op2));
ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags));
ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
ASSERT_EQ(6U, flags);
ASSERT_EQ(0, get_flags(&ioctx, oid, snap_id, &flags));
ASSERT_EQ(2U, flags);
ASSERT_EQ(snap_ids.size(), snap_flags.size());
ASSERT_EQ(2U, snap_flags[0]);
ioctx.close();
}