From: Greg Farnum Date: Wed, 5 Oct 2011 20:30:59 +0000 (-0700) Subject: objclass: add map interfaces. X-Git-Tag: v0.37~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=583e16d9591391c834cd17154571926bffc05abc;p=ceph.git objclass: add map interfaces. Right now, they implement the TMAP functions, plus a few obvious extras to read/write select keys and the header. In the future it should be easy to switch them to better mapping implementations. Signed-off-by: Greg Farnum --- diff --git a/src/include/rados.h b/src/include/rados.h index 959cb1bde47b..e3def822289d 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -307,7 +307,7 @@ static inline int ceph_osd_op_mode_modify(int op) /* * note that the following tmap stuff is also defined in the ceph librados.h - * any modification here needs to be updated there + * and objclass.h. Any modification here needs to be updated there */ #define CEPH_OSD_TMAP_HDR 'h' #define CEPH_OSD_TMAP_SET 's' diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 98702883c076..7cc83f38169d 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -10,6 +10,7 @@ extern "C" { #include #ifndef CEPH_OSD_TMAP_SET +/* These are also defined in rados.h and objclass.h. Keep them in sync! */ #define CEPH_OSD_TMAP_HDR 'h' #define CEPH_OSD_TMAP_SET 's' #define CEPH_OSD_TMAP_CREATE 'c' diff --git a/src/objclass/class_api.cc b/src/objclass/class_api.cc index 8e7caa334472..11d3e0c966d8 100644 --- a/src/objclass/class_api.cc +++ b/src/objclass/class_api.cc @@ -251,3 +251,115 @@ int cls_cxx_snap_revert(cls_method_context_t hctx, snapid_t snapid) return (*pctx)->pg->do_osd_ops(*pctx, ops, outbl); } +int cls_cxx_map_read_full(cls_method_context_t hctx, bufferlist* outbl) +{ + ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx; + vector ops(1); + int ret; + ops[0].op.op = CEPH_OSD_OP_TMAPGET; + ret = (*pctx)->pg->do_osd_ops(*pctx, ops, *outbl); + if (ret < 0) + return ret; + return outbl->length(); +} + +int cls_cxx_map_read_header(cls_method_context_t hctx, bufferlist *outbl) +{ + ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx; + vector ops(1); + int ret; + bufferlist full_map; + ops[0].op.op = CEPH_OSD_OP_TMAPGET; + ret = (*pctx)->pg->do_osd_ops(*pctx, ops, full_map); + if (ret < 0) + return ret; + + //decode and return the header + bufferlist::iterator map_iter = full_map.begin(); + ::decode(*outbl, map_iter); + return 0; +} +int cls_cxx_map_read_key(cls_method_context_t hctx, string key, bufferlist *outbl) +{ + ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx; + vector ops(1); + int ret; + bufferlist full_map; + ops[0].op.op = CEPH_OSD_OP_TMAPGET; + ret = (*pctx)->pg->do_osd_ops(*pctx, ops, full_map); + if (ret < 0) + return ret; + + //find and return just the requested key! + bufferlist header; + string next_key; + bufferlist next_val; + __u32 nkeys; + bufferlist::iterator map_iter = full_map.begin(); + ::decode(header, map_iter); + ::decode(nkeys, map_iter); + while (nkeys) { + ::decode(next_key, map_iter); + ::decode(next_val, map_iter); + if (next_key == key) { + *outbl = next_val; + return 0; + } + if (next_key > key) + return -ENOENT; + --nkeys; + } + return -ENOENT; +} + +int cls_cxx_map_write_full(cls_method_context_t hctx, bufferlist* inbl) +{ + ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx; + vector ops(1); + ops[0].op.op = CEPH_OSD_OP_TMAPPUT; + ops[0].data = *inbl; + bufferlist outbl; + return (*pctx)->pg->do_osd_ops(*pctx, ops, outbl); +} + +int cls_cxx_map_write_key(cls_method_context_t hctx, string key, bufferlist *inbl) +{ + bufferlist update_bl; + update_bl.append(CEPH_OSD_TMAP_SET); + ::encode(key, update_bl); + ::encode(*inbl, update_bl); + return cls_cxx_map_update(hctx, &update_bl); +} + +int cls_cxx_map_write_header(cls_method_context_t hctx, bufferlist *inbl) +{ + ReplicatedPG::OpContext **pctx = static_cast(hctx); + vector ops(1); + bufferlist update_bl; + update_bl.append(CEPH_OSD_TMAP_HDR); + ::encode(*inbl, update_bl); + + ops[0].op.op = CEPH_OSD_OP_TMAPUP; + ops[0].data = update_bl; + + bufferlist outbl; + return (*pctx)->pg->do_osd_ops(*pctx, ops, outbl); +} + +int cls_cxx_map_remove_key(cls_method_context_t hctx, string key) +{ + bufferlist update_bl; + update_bl.append(CEPH_OSD_TMAP_RM); + ::encode(key, update_bl); + return cls_cxx_map_update(hctx, &update_bl); +} + +int cls_cxx_map_update(cls_method_context_t hctx, bufferlist* inbl) +{ + ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx; + vector ops(1); + ops[0].op.op = CEPH_OSD_OP_TMAPUP; + ops[0].data = *inbl; + bufferlist outbl; + return (*pctx)->pg->do_osd_ops(*pctx, ops, outbl); +} diff --git a/src/objclass/objclass.h b/src/objclass/objclass.h index 6d94a4b5694c..822558c7d6b7 100644 --- a/src/objclass/objclass.h +++ b/src/objclass/objclass.h @@ -93,6 +93,20 @@ extern int cls_cxx_write(cls_method_context_t hctx, int ofs, int len, bufferlist extern int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *bl); extern int cls_cxx_replace(cls_method_context_t hctx, int ofs, int len, bufferlist *bl); extern int cls_cxx_snap_revert(cls_method_context_t hctx, snapid_t snapid); +extern int cls_cxx_map_read_full(cls_method_context_t hctx, bufferlist* outbl); +extern int cls_cxx_map_read_header(cls_method_context_t hctx, bufferlist *outbl); +extern int cls_cxx_map_read_key(cls_method_context_t hctx, string key, bufferlist *outbl); +extern int cls_cxx_map_write_full(cls_method_context_t hctx, bufferlist* in); +extern int cls_cxx_map_write_key(cls_method_context_t hctx, string key, bufferlist *inbl); +extern int cls_cxx_map_write_header(cls_method_context_t hctx, bufferlist *inbl); +extern int cls_cxx_map_remove_key(cls_method_context_t hctx, string key); +extern int cls_cxx_map_update(cls_method_context_t hctx, bufferlist* inbl); + +/* These are also defined in rados.h and librados.h. Keep them in sync! */ +#define CEPH_OSD_TMAP_HDR 'h' +#define CEPH_OSD_TMAP_SET 's' +#define CEPH_OSD_TMAP_CREATE 'c' +#define CEPH_OSD_TMAP_RM 'r' #endif