mirror of
https://github.com/ceph/ceph
synced 2024-12-29 15:03:33 +00:00
osd: read/write op flags revision (for class methods)
This commit is contained in:
parent
bdfbc610b5
commit
85a65e5fc6
@ -141,6 +141,9 @@ libcls_trivialmap.so: cls_trivialmap.cc
|
||||
${CXX} -I. -fPIC -shared -g -o libcls_trivialmap.so cls_trivialmap.cc
|
||||
BUILT_SOURCES += libcls_trivialmap.so
|
||||
|
||||
libcls_acl.so: cls_acl.cc
|
||||
${CXX} -I. -fPIC -shared -g -o libcls_acl.so cls_acl.cc
|
||||
BUILT_SOURCES += libcls_acl.so
|
||||
|
||||
## libcephclient.so
|
||||
#libcephclient_so_a_SOURCES = \
|
||||
@ -300,6 +303,7 @@ libos_a_SOURCES = \
|
||||
os/JournalingObjectStore.cc
|
||||
|
||||
libosd_a_SOURCES = \
|
||||
messages/MOSDOp.cc \
|
||||
osd/PG.cc \
|
||||
osd/ReplicatedPG.cc \
|
||||
osd/Ager.cc \
|
||||
|
@ -74,8 +74,8 @@ void class_init()
|
||||
cls_log("Loaded crypto class!");
|
||||
|
||||
cls_register("crypto", &h_class);
|
||||
cls_register_method(h_class, "md5", md5_method, &h_md5);
|
||||
cls_register_method(h_class, "sha1", sha1_method, &h_sha1);
|
||||
cls_register_method(h_class, "md5", CLS_METHOD_RD, md5_method, &h_md5);
|
||||
cls_register_method(h_class, "sha1", CLS_METHOD_RD, sha1_method, &h_sha1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -84,8 +84,8 @@ static int update(cls_method_context_t ctx, bufferlist *inbl, bufferlist *outbl)
|
||||
void class_init()
|
||||
{
|
||||
cls_register("trivialmap", &h_class);
|
||||
cls_register_cxx_method(h_class, "read_all", read_all, &h_read_all);
|
||||
cls_register_cxx_method(h_class, "update", update, &h_update);
|
||||
cls_register_cxx_method(h_class, "read_all", CLS_METHOD_RD, read_all, &h_read_all);
|
||||
cls_register_cxx_method(h_class, "update", CLS_METHOD_WR, update, &h_update);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -287,6 +287,7 @@ void ClassHandler::ClassData::_add_dependent(ClassData& dependent)
|
||||
}
|
||||
|
||||
ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *mname,
|
||||
int flags,
|
||||
cls_method_call_t func)
|
||||
{
|
||||
/* no need for locking, called under the class_init mutex */
|
||||
@ -299,6 +300,7 @@ ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *
|
||||
}
|
||||
|
||||
ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const char *mname,
|
||||
int flags,
|
||||
cls_method_cxx_call_t func)
|
||||
{
|
||||
/* no need for locking, called under the class_init mutex */
|
||||
@ -383,3 +385,16 @@ int ClassHandler::ClassMethod::exec(cls_method_context_t ctx, bufferlist& indata
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ClassHandler::get_method_flags(const nstring& cname, const nstring& mname)
|
||||
{
|
||||
ClassData& cls = get_obj(cname);
|
||||
if (&cls == &null_cls_data)
|
||||
return 0;
|
||||
|
||||
ClassMethod *method = cls.get_method(mname.c_str());
|
||||
if (!method)
|
||||
return 0;
|
||||
|
||||
return method->flags;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ class OSD;
|
||||
class MClass;
|
||||
|
||||
|
||||
|
||||
class ClassHandler
|
||||
{
|
||||
OSD *osd;
|
||||
@ -25,6 +26,7 @@ public:
|
||||
struct ClassMethod {
|
||||
struct ClassHandler::ClassData *cls;
|
||||
string name;
|
||||
int flags;
|
||||
cls_method_call_t func;
|
||||
cls_method_cxx_call_t cxx_func;
|
||||
|
||||
@ -66,8 +68,8 @@ public:
|
||||
ClassData() : mutex(NULL), status(CLASS_UNKNOWN), version(), timeout(0), handle(NULL), registered(false) {}
|
||||
~ClassData() { if (mutex) delete mutex; }
|
||||
|
||||
ClassMethod *register_method(const char *mname, cls_method_call_t func);
|
||||
ClassMethod *register_cxx_method(const char *mname, cls_method_cxx_call_t func);
|
||||
ClassMethod *register_method(const char *mname, int flags, cls_method_call_t func);
|
||||
ClassMethod *register_cxx_method(const char *mname, int flags, cls_method_cxx_call_t func);
|
||||
ClassMethod *get_method(const char *mname);
|
||||
void unregister_method(ClassMethod *method);
|
||||
|
||||
@ -96,6 +98,7 @@ public:
|
||||
ClassData *register_class(const char *cname);
|
||||
void unregister_class(ClassData *cls);
|
||||
|
||||
int get_method_flags(const nstring& cname, const nstring& mname);
|
||||
};
|
||||
|
||||
|
||||
|
11
src/messages/MOSDOp.cc
Normal file
11
src/messages/MOSDOp.cc
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
#include "MOSDOp.h"
|
||||
#include "osd/OSD.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* need to update read/write flags for class method operations */
|
||||
void MOSDOp::update_flags(OSD *osd)
|
||||
{
|
||||
flags = osd->get_op_flags(this);
|
||||
}
|
@ -27,6 +27,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class OSD;
|
||||
|
||||
class MOSDOp : public Message {
|
||||
private:
|
||||
ceph_osd_request_head head;
|
||||
@ -36,6 +38,7 @@ public:
|
||||
bufferlist ticket;
|
||||
vector<snapid_t> snaps;
|
||||
osd_peer_stat_t peer_stat;
|
||||
int flags;
|
||||
|
||||
friend class MOSDOpReply;
|
||||
|
||||
@ -61,9 +64,13 @@ public:
|
||||
eversion_t get_version() { return head.reassert_version; }
|
||||
|
||||
utime_t get_mtime() { return head.mtime; }
|
||||
|
||||
#if 0
|
||||
bool may_read() { return head.flags & CEPH_OSD_FLAG_READ; }
|
||||
bool may_write() { return head.flags & CEPH_OSD_FLAG_WRITE; }
|
||||
#endif
|
||||
bool may_read() { assert(flags); return flags & CEPH_OSD_FLAG_READ; }
|
||||
bool may_write() { assert(flags); return flags & CEPH_OSD_FLAG_WRITE; }
|
||||
void update_flags(OSD *osd);
|
||||
|
||||
void set_peer_stat(const osd_peer_stat_t& stat) {
|
||||
peer_stat = stat;
|
||||
@ -187,11 +194,12 @@ public:
|
||||
out << " " << oid;
|
||||
|
||||
out << " ";
|
||||
#if 0
|
||||
if (may_read())
|
||||
out << "r";
|
||||
if (may_write())
|
||||
out << "w";
|
||||
|
||||
#endif
|
||||
if (head.snapid != CEPH_NOSNAP)
|
||||
out << "@" << snapid_t((__u64)head.snapid);
|
||||
|
||||
|
@ -51,26 +51,28 @@ int cls_unregister(cls_handle_t handle)
|
||||
}
|
||||
|
||||
int cls_register_method(cls_handle_t hclass, const char *method,
|
||||
int flags,
|
||||
cls_method_call_t class_call, cls_method_handle_t *handle)
|
||||
{
|
||||
ClassHandler::ClassData *cd;
|
||||
cls_method_handle_t hmethod;
|
||||
|
||||
cd = (ClassHandler::ClassData *)hclass;
|
||||
hmethod = (cls_method_handle_t)cd->register_method(method, class_call);
|
||||
hmethod = (cls_method_handle_t)cd->register_method(method, flags, class_call);
|
||||
if (handle)
|
||||
*handle = hmethod;
|
||||
return (hmethod != NULL);
|
||||
}
|
||||
|
||||
int cls_register_cxx_method(cls_handle_t hclass, const char *method,
|
||||
int flags,
|
||||
cls_method_cxx_call_t class_call, cls_method_handle_t *handle)
|
||||
{
|
||||
ClassHandler::ClassData *cd;
|
||||
cls_method_handle_t hmethod;
|
||||
|
||||
cd = (ClassHandler::ClassData *)hclass;
|
||||
hmethod = (cls_method_handle_t)cd->register_cxx_method(method, class_call);
|
||||
hmethod = (cls_method_handle_t)cd->register_cxx_method(method, flags, class_call);
|
||||
if (handle)
|
||||
*handle = hmethod;
|
||||
return (hmethod != NULL);
|
||||
@ -84,7 +86,7 @@ int cls_unregister_method(cls_method_handle_t handle)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cls_rdcall(cls_method_handle_t hctx, const char *cls, const char *method,
|
||||
int cls_rdcall(cls_method_context_t hctx, const char *cls, const char *method,
|
||||
char *indata, int datalen,
|
||||
char **outdata, int *outdatalen)
|
||||
{
|
||||
@ -105,14 +107,37 @@ int cls_rdcall(cls_method_handle_t hctx, const char *cls, const char *method,
|
||||
bufferlist::iterator iter = idata.begin();
|
||||
r = (*pctx)->pg->do_osd_ops(*pctx, nops, iter, odata);
|
||||
|
||||
*outdata = odata.c_str();
|
||||
*outdata = (char *)malloc(odata.length());
|
||||
memcpy(*outdata, odata.c_str(), odata.length());
|
||||
*outdatalen = odata.length();
|
||||
#warning use after free!
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int cls_read(cls_method_handle_t hctx, int ofs, int len,
|
||||
int cls_getxattr(cls_method_context_t hctx, const char *name,
|
||||
char **outdata, int *outdatalen)
|
||||
{
|
||||
ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
|
||||
bufferlist name_data;
|
||||
bufferlist odata;
|
||||
vector<ceph_osd_op> nops(1);
|
||||
ceph_osd_op& op = nops[0];
|
||||
int r;
|
||||
|
||||
op.op = CEPH_OSD_OP_GETXATTR;
|
||||
name_data.append(name);
|
||||
op.name_len = strlen(name);
|
||||
bufferlist::iterator iter = name_data.begin();
|
||||
r = (*pctx)->pg->do_osd_ops(*pctx, nops, iter, odata);
|
||||
|
||||
*outdata = (char *)malloc(odata.length());
|
||||
memcpy(*outdata, odata.c_str(), odata.length());
|
||||
*outdatalen = odata.length();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int cls_read(cls_method_context_t hctx, int ofs, int len,
|
||||
char **outdata, int *outdatalen)
|
||||
{
|
||||
ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
|
||||
@ -124,14 +149,14 @@ int cls_read(cls_method_handle_t hctx, int ofs, int len,
|
||||
bufferlist::iterator iter = idata.begin();
|
||||
int r = (*pctx)->pg->do_osd_ops(*pctx, ops, iter, odata);
|
||||
|
||||
*outdata = odata.c_str();
|
||||
*outdata = (char *)malloc(odata.length());
|
||||
memcpy(*outdata, odata.c_str(), odata.length());
|
||||
*outdatalen = odata.length();
|
||||
#warning use after free!
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int cls_cxx_read(cls_method_handle_t hctx, int ofs, int len, bufferlist *outbl)
|
||||
int cls_cxx_read(cls_method_context_t hctx, int ofs, int len, bufferlist *outbl)
|
||||
{
|
||||
ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
|
||||
vector<ceph_osd_op> ops(1);
|
||||
@ -143,7 +168,7 @@ int cls_cxx_read(cls_method_handle_t hctx, int ofs, int len, bufferlist *outbl)
|
||||
return (*pctx)->pg->do_osd_ops(*pctx, ops, iter, *outbl);
|
||||
}
|
||||
|
||||
int cls_cxx_write(cls_method_handle_t hctx, int ofs, int len, bufferlist *inbl)
|
||||
int cls_cxx_write(cls_method_context_t hctx, int ofs, int len, bufferlist *inbl)
|
||||
{
|
||||
ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
|
||||
vector<ceph_osd_op> ops(1);
|
||||
@ -155,7 +180,7 @@ int cls_cxx_write(cls_method_handle_t hctx, int ofs, int len, bufferlist *inbl)
|
||||
return (*pctx)->pg->do_osd_ops(*pctx, ops, iter, outbl);
|
||||
}
|
||||
|
||||
int cls_cxx_replace(cls_method_handle_t hctx, int ofs, int len, bufferlist *inbl)
|
||||
int cls_cxx_replace(cls_method_context_t hctx, int ofs, int len, bufferlist *inbl)
|
||||
{
|
||||
ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
|
||||
vector<ceph_osd_op> ops(2);
|
||||
|
@ -14,6 +14,10 @@ int __cls_ver__## maj ## _ ##min = 0;
|
||||
#define CLS_NAME(name) \
|
||||
int __cls_name__## name = 0;
|
||||
|
||||
#define CLS_METHOD_RD 0x1
|
||||
#define CLS_METHOD_WR 0x2
|
||||
|
||||
|
||||
typedef void *cls_handle_t;
|
||||
typedef void *cls_method_handle_t;
|
||||
typedef void *cls_method_context_t;
|
||||
@ -30,17 +34,19 @@ extern int cls_log(const char *format, ...);
|
||||
extern void *cls_alloc(size_t size);
|
||||
extern void cls_free(void *p);
|
||||
|
||||
extern int cls_read(cls_method_handle_t hctx, int ofs, int len,
|
||||
extern int cls_read(cls_method_context_t hctx, int ofs, int len,
|
||||
char **outdata, int *outdatalen);
|
||||
extern int cls_rdcall(cls_method_handle_t hctx, const char *cls, const char *method,
|
||||
extern int cls_rdcall(cls_method_context_t hctx, const char *cls, const char *method,
|
||||
char *indata, int datalen,
|
||||
char **outdata, int *outdatalen);
|
||||
extern int cls_getxattr(cls_method_context_t hctx, const char *name,
|
||||
char **outdata, int *outdatalen);
|
||||
|
||||
/* class registration api */
|
||||
extern int cls_register(const char *name, cls_handle_t *handle);
|
||||
extern int cls_unregister(cls_handle_t);
|
||||
|
||||
extern int cls_register_method(cls_handle_t hclass, const char *method,
|
||||
extern int cls_register_method(cls_handle_t hclass, const char *method, int flags,
|
||||
cls_method_call_t class_call, cls_method_handle_t *handle);
|
||||
extern int cls_unregister_method(cls_method_handle_t handle);
|
||||
|
||||
@ -67,12 +73,12 @@ extern void class_fini(void);
|
||||
typedef int (*cls_method_cxx_call_t)(cls_method_context_t ctx,
|
||||
class buffer::list *inbl, class buffer::list *outbl);
|
||||
|
||||
extern int cls_register_cxx_method(cls_handle_t hclass, const char *method,
|
||||
extern int cls_register_cxx_method(cls_handle_t hclass, const char *method, int flags,
|
||||
cls_method_cxx_call_t class_call, cls_method_handle_t *handle);
|
||||
|
||||
extern int cls_cxx_read(cls_method_handle_t hctx, int ofs, int len, bufferlist *bl);
|
||||
extern int cls_cxx_write(cls_method_handle_t hctx, int ofs, int len, bufferlist *bl);
|
||||
extern int cls_cxx_replace(cls_method_handle_t hctx, int ofs, int len, bufferlist *bl);
|
||||
extern int cls_cxx_read(cls_method_context_t hctx, int ofs, int len, bufferlist *bl);
|
||||
extern int cls_cxx_write(cls_method_context_t hctx, int ofs, int len, bufferlist *bl);
|
||||
extern int cls_cxx_replace(cls_method_context_t hctx, int ofs, int len, bufferlist *bl);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -3883,4 +3883,14 @@ void OSD::send_class_request(const char *cname, ClassVersion& version)
|
||||
}
|
||||
|
||||
|
||||
int OSD::get_op_flags(MOSDOp *op)
|
||||
{
|
||||
vector<ceph_osd_op>::iterator iter;
|
||||
|
||||
return op->get_flags();
|
||||
|
||||
/* FIXME */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -793,6 +793,8 @@ protected:
|
||||
void force_remount();
|
||||
|
||||
LogClient *get_logclient() { return &logclient; }
|
||||
|
||||
int get_op_flags(MOSDOp *op);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -829,6 +829,20 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<ceph_osd_op>& ops,
|
||||
|
||||
for (vector<ceph_osd_op>::iterator p = ops.begin(); p != ops.end(); p++) {
|
||||
ceph_osd_op& op = *p;
|
||||
bool is_modify;
|
||||
string cname, mname;
|
||||
|
||||
switch (op.op) {
|
||||
case CEPH_OSD_OP_RDCALL:
|
||||
bp.copy(op.class_len, cname);
|
||||
bp.copy(op.method_len, mname);
|
||||
is_modify = osd->class_handler->get_method_flags(cname, mname) & CLS_METHOD_WR;
|
||||
break;
|
||||
|
||||
default:
|
||||
is_modify = (op.op & CEPH_OSD_OP_MODE_WR);
|
||||
break;
|
||||
}
|
||||
|
||||
// munge ZERO -> TRUNCATE? (don't munge to DELETE or we risk hosing attributes)
|
||||
if (op.op == CEPH_OSD_OP_ZERO &&
|
||||
@ -851,7 +865,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<ceph_osd_op>& ops,
|
||||
dout(10) << "do_osd_op " << op << dendl;
|
||||
|
||||
// make writeable (i.e., clone if necessary)
|
||||
if (op.op & CEPH_OSD_OP_MODE_WR)
|
||||
if (is_modify)
|
||||
make_writeable(ctx);
|
||||
|
||||
switch (op.op) {
|
||||
@ -878,10 +892,6 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<ceph_osd_op>& ops,
|
||||
|
||||
case CEPH_OSD_OP_RDCALL:
|
||||
{
|
||||
string cname, mname;
|
||||
bp.copy(op.class_len, cname);
|
||||
bp.copy(op.method_len, mname);
|
||||
|
||||
bufferlist indata;
|
||||
bp.copy(op.indata_len, indata);
|
||||
//dout(20) << "rdcall param=" << indata.c_str() << dendl;
|
||||
@ -1250,7 +1260,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<ceph_osd_op>& ops,
|
||||
assert(0); // for now
|
||||
}
|
||||
|
||||
if ((op.op & CEPH_OSD_OP_MODE_WR) &&
|
||||
if ((is_modify) &&
|
||||
!ctx->obs->exists && oi.snapset.head_exists) {
|
||||
dout(20) << " num_objects " << info.stats.num_objects << " -> " << (info.stats.num_objects+1) << dendl;
|
||||
info.stats.num_objects++;
|
||||
|
Loading…
Reference in New Issue
Block a user