osd: read/write op flags revision (for class methods)

This commit is contained in:
Yehuda Sadeh 2009-06-09 13:24:31 -07:00
parent bdfbc610b5
commit 85a65e5fc6
12 changed files with 126 additions and 32 deletions

View File

@ -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 \

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
View 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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -793,6 +793,8 @@ protected:
void force_remount();
LogClient *get_logclient() { return &logclient; }
int get_op_flags(MOSDOp *op);
};
#endif

View File

@ -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++;