return 1;
}
+int cls_register_cxx_filter(cls_handle_t hclass, const std::string &filter_name,
+ cls_cxx_filter_factory_t fn)
+{
+ ClassHandler::ClassData *cls = (ClassHandler::ClassData *)hclass;
+ cls->register_cxx_filter(filter_name, fn);
+ return 0;
+}
+
int cls_call(cls_method_context_t hctx, const char *cls, const char *method,
char *indata, int datalen,
char **outdata, int *outdatalen)
#include "../include/types.h"
#include "msg/msg_types.h"
+#include "common/hobject.h"
extern "C" {
#endif
typedef int (*cls_method_cxx_call_t)(cls_method_context_t ctx,
class buffer::list *inbl, class buffer::list *outbl);
+class PGLSFilter {
+protected:
+ string xattr;
+public:
+ PGLSFilter();
+ virtual ~PGLSFilter();
+ virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
+ bufferlist& outdata) = 0;
+
+ /**
+ * xattr key, or empty string. If non-empty, this xattr will be fetched
+ * and the value passed into ::filter
+ */
+ virtual string& get_xattr() { return xattr; }
+
+ /**
+ * If true, objects without the named xattr (if xattr name is not empty)
+ * will be rejected without calling ::filter
+ */
+ virtual bool reject_empty_xattr() { return true; }
+};
+
+// Classes expose a filter constructor that returns a subclass of PGLSFilter
+typedef PGLSFilter* (*cls_cxx_filter_factory_t)(
+ bufferlist::iterator *args);
+
+
+
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_register_cxx_filter(cls_handle_t hclass,
+ const std::string &filter_name,
+ cls_cxx_filter_factory_t fn);
+
extern int cls_cxx_create(cls_method_context_t hctx, bool exclusive);
extern int cls_cxx_remove(cls_method_context_t hctx);
extern int cls_cxx_stat(cls_method_context_t hctx, uint64_t *size, time_t *mtime);
return &method;
}
+void ClassHandler::ClassData::register_cxx_filter(
+ const std::string &filter_name,
+ cls_cxx_filter_factory_t fn)
+{
+ filters_map[filter_name] = fn;
+}
+
ClassHandler::ClassMethod *ClassHandler::ClassData::_get_method(const char *mname)
{
map<string, ClassHandler::ClassMethod>::iterator iter = methods_map.find(mname);
void *handle;
map<string, ClassMethod> methods_map;
+ map<string, cls_cxx_filter_factory_t> filters_map;
set<ClassData *> dependencies; /* our dependencies */
set<ClassData *> missing_dependencies; /* only missing dependencies */
ClassMethod *register_cxx_method(const char *mname, int flags, cls_method_cxx_call_t func);
void unregister_method(ClassMethod *method);
+ void register_cxx_filter(
+ const std::string &filter_name,
+ cls_cxx_filter_factory_t fn);
+
ClassMethod *get_method(const char *mname) {
Mutex::Locker l(handler->mutex);
return _get_method(mname);
}
int get_method_flags(const char *mname);
+
+ cls_cxx_filter_factory_t get_filter(const std::string &filter_name)
+ {
+ Mutex::Locker l(handler->mutex);
+ return filters_map[filter_name];
+ }
};
private:
#include "ReplicatedPG.h"
#include "OSD.h"
#include "OpRequest.h"
+#include "objclass/objclass.h"
#include "common/errno.h"
#include "common/perf_counters.h"
op->mark_delayed("waiting for blocked object");
}
+class PGLSPlainFilter : public PGLSFilter {
+ string val;
+public:
+ PGLSPlainFilter(bufferlist::iterator& params) {
+ ::decode(xattr, params);
+ ::decode(val, params);
+ }
+ virtual ~PGLSPlainFilter() {}
+ virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
+ bufferlist& outdata);
+};
+
+class PGLSParentFilter : public PGLSFilter {
+ inodeno_t parent_ino;
+public:
+ PGLSParentFilter(bufferlist::iterator& params) {
+ xattr = "_parent";
+ ::decode(parent_ino, params);
+ generic_dout(0) << "parent_ino=" << parent_ino << dendl;
+ }
+ virtual ~PGLSParentFilter() {}
+ virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
+ bufferlist& outdata);
+};
+
bool PGLSParentFilter::filter(const hobject_t &obj,
bufferlist& xattr_data, bufferlist& outdata)
{
} else if (type.compare("plain") == 0) {
filter = new PGLSPlainFilter(iter);
} else {
- return -EINVAL;
+ std::size_t dot = type.find(".");
+ if (dot == std::string::npos || dot == 0 || dot == type.size() - 1) {
+ return -EINVAL;
+ }
+
+ const std::string class_name = type.substr(0, dot);
+ const std::string filter_name = type.substr(dot + 1);
+ ClassHandler::ClassData *cls = NULL;
+ int r = osd->class_handler->open_class(class_name, &cls);
+ if (r != 0) {
+ derr << "Error opening class '" << class_name << "': "
+ << cpp_strerror(r) << dendl;
+ return -EINVAL;
+ } else {
+ assert(cls);
+ }
+
+ cls_cxx_filter_factory_t fn = cls->get_filter(filter_name);
+ if (fn == NULL) {
+ derr << "Error finding filter '" << filter_name << "' in class "
+ << class_name << dendl;
+ return -EINVAL;
+ }
+ filter = fn(&iter);
+ assert(filter);
}
*pfilter = filter;
class PromoteCallback;
class ReplicatedPG;
+class PGLSFilter;
void intrusive_ptr_add_ref(ReplicatedPG *pg);
void intrusive_ptr_release(ReplicatedPG *pg);
uint64_t get_with_id(ReplicatedPG *pg);
typedef boost::intrusive_ptr<ReplicatedPG> ReplicatedPGRef;
#endif
-class PGLSFilter {
-protected:
- string xattr;
-public:
- PGLSFilter();
- virtual ~PGLSFilter();
- virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
- bufferlist& outdata) = 0;
-
- /**
- * xattr key, or empty string. If non-empty, this xattr will be fetched
- * and the value passed into ::filter
- */
- virtual string& get_xattr() { return xattr; }
-
- /**
- * If true, objects without the named xattr (if xattr name is not empty)
- * will be rejected without calling ::filter
- */
- virtual bool reject_empty_xattr() { return true; }
-};
-
-class PGLSPlainFilter : public PGLSFilter {
- string val;
-public:
- PGLSPlainFilter(bufferlist::iterator& params) {
- ::decode(xattr, params);
- ::decode(val, params);
- }
- virtual ~PGLSPlainFilter() {}
- virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
- bufferlist& outdata);
-};
-
-class PGLSParentFilter : public PGLSFilter {
- inodeno_t parent_ino;
-public:
- PGLSParentFilter(bufferlist::iterator& params) {
- xattr = "_parent";
- ::decode(parent_ino, params);
- generic_dout(0) << "parent_ino=" << parent_ino << dendl;
- }
- virtual ~PGLSParentFilter() {}
- virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
- bufferlist& outdata);
-};
-
class ReplicatedPG : public PG, public PGBackend::Listener {
friend class OSD;
friend class Watch;