//osd_op.data.hexdump(*_dout);
//_dout_lock.Unlock();
- // verify
- if (0) {
+ // verify sort order
+ bool unsorted = false;
+ if (true) {
bufferlist header;
- map<string, bufferlist> m;
::decode(header, bp);
- ::decode(m, bp);
- assert(bp.end());
+ uint32_t n;
+ ::decode(n, bp);
+ string last_key;
+ while (n--) {
+ string key;
+ ::decode(key, bp);
+ dout(10) << "tmapput key " << key << dendl;
+ bufferlist val;
+ ::decode(val, bp);
+ if (key < last_key) {
+ dout(10) << "TMAPPUT is unordered; resorting" << dendl;
+ unsorted = true;
+ break;
+ }
+ last_key = key;
+ }
}
if (g_conf->osd_tmapput_sets_uses_tmap) {
newop.op.extent.offset = 0;
newop.op.extent.length = osd_op.indata.length();
newop.indata = osd_op.indata;
+
+ if (unsorted) {
+ bp = osd_op.indata.begin();
+ bufferlist header;
+ map<string, bufferlist> m;
+ ::decode(header, bp);
+ ::decode(m, bp);
+ assert(bp.end());
+ bufferlist newbl;
+ ::encode(header, newbl);
+ ::encode(m, newbl);
+ newop.indata = newbl;
+ }
do_osd_ops(ctx, nops);
}
break;
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
}
+TEST(LibRadosMisc, TmapUpdateMisorderedPutPP) {
+ Rados cluster;
+ std::string pool_name = get_temp_pool_name();
+ ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
+ IoCtx ioctx;
+ cluster.ioctx_create(pool_name.c_str(), ioctx);
+
+ // create unsorted tmap
+ string h("header");
+ bufferlist bl;
+ ::encode(h, bl);
+ uint32_t n = 3;
+ ::encode(n, bl);
+ ::encode(string("b"), bl);
+ ::encode(string("bval"), bl);
+ ::encode(string("a"), bl);
+ ::encode(string("aval"), bl);
+ ::encode(string("c"), bl);
+ ::encode(string("cval"), bl);
+ ASSERT_EQ(0, ioctx.tmap_put("foo", bl));
+
+ // check
+ bufferlist newbl;
+ ASSERT_EQ(0, ioctx.read("foo", bl, 0, 0));
+ ASSERT_EQ(bl.contents_equal(newbl), false);
+
+ ioctx.close();
+ ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+}
+
TEST(LibRadosMisc, Exec) {
char buf[128];
rados_t cluster;