class PGLSHelloFilter : public PGLSFilter {
string val;
public:
- PGLSHelloFilter(bufferlist::iterator& params) {
- ::decode(xattr, params);
- ::decode(val, params);
+ int init(bufferlist::iterator& params) {
+ try {
+ ::decode(xattr, params);
+ ::decode(val, params);
+ } catch (buffer::error &e) {
+ return -EINVAL;
+ }
}
+
virtual ~PGLSHelloFilter() {}
virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
bufferlist& outdata)
};
-PGLSFilter *hello_filter(bufferlist::iterator *q)
+PGLSFilter *hello_filter()
{
- assert(q);
- return new PGLSHelloFilter(*q);
+ return new PGLSHelloFilter();
}
virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
bufferlist& outdata) = 0;
+ /**
+ * Arguments passed from the RADOS client. Implementations must
+ * handle any encoding errors, and return an appropriate error code,
+ * or 0 on valid input.
+ */
+ virtual int init(bufferlist::iterator ¶ms) = 0;
+
/**
* xattr key, or empty string. If non-empty, this xattr will be fetched
* and the value passed into ::filter
};
// Classes expose a filter constructor that returns a subclass of PGLSFilter
-typedef PGLSFilter* (*cls_cxx_filter_factory_t)(
- bufferlist::iterator *args);
-
+typedef PGLSFilter* (*cls_cxx_filter_factory_t)();
extern int cls_register_cxx_method(cls_handle_t hclass, const char *method, int flags,
class PGLSPlainFilter : public PGLSFilter {
string val;
public:
- PGLSPlainFilter(bufferlist::iterator& params) {
- ::decode(xattr, params);
- ::decode(val, params);
+ virtual int init(bufferlist::iterator ¶ms)
+ {
+ try {
+ ::decode(xattr, params);
+ ::decode(val, params);
+ } catch (buffer::error &e) {
+ return -EINVAL;
+ }
+
+ return 0;
}
virtual ~PGLSPlainFilter() {}
virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
class PGLSParentFilter : public PGLSFilter {
inodeno_t parent_ino;
public:
- PGLSParentFilter(bufferlist::iterator& params) {
+ PGLSParentFilter() {
xattr = "_parent";
- ::decode(parent_ino, params);
+ }
+ virtual int init(bufferlist::iterator ¶ms)
+ {
+ try {
+ ::decode(parent_ino, params);
+ } catch (buffer::error &e) {
+ return -EINVAL;
+ }
generic_dout(0) << "parent_ino=" << parent_ino << dendl;
+
+ return 0;
}
virtual ~PGLSParentFilter() {}
virtual bool filter(const hobject_t &obj, bufferlist& xattr_data,
}
if (type.compare("parent") == 0) {
- filter = new PGLSParentFilter(iter);
+ filter = new PGLSParentFilter();
} else if (type.compare("plain") == 0) {
- filter = new PGLSPlainFilter(iter);
+ filter = new PGLSPlainFilter();
} else {
std::size_t dot = type.find(".");
if (dot == std::string::npos || dot == 0 || dot == type.size() - 1) {
<< class_name << dendl;
return -EINVAL;
}
- filter = class_filter->fn(&iter);
- assert(filter);
+ filter = class_filter->fn();
+ if (!filter) {
+ // Object classes are obliged to return us something, but let's
+ // give an error rather than asserting out.
+ derr << "Buggy class " << class_name << " failed to construct "
+ "filter " << filter_name << dendl;
+ return -EINVAL;
+ }
}
- *pfilter = filter;
-
- return 0;
+ assert(filter);
+ int r = filter->init(iter);
+ if (r < 0) {
+ derr << "Error initializing filter " << type << ": "
+ << cpp_strerror(r) << dendl;
+ delete filter;
+ return -EINVAL;
+ } else {
+ // Successfully constructed and initialized, return it.
+ *pfilter = filter;
+ return 0;
+ }
}