From 2d781ff658a4cdf107200733573a34d04a44c203 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 5 Jan 2011 16:50:07 -0800 Subject: [PATCH] osd, rados: pgls filter fixes --- src/include/ceph_strings.cc | 1 + src/include/librados.hpp | 2 +- src/librados.cc | 6 ++-- src/osd/ReplicatedPG.cc | 71 ++++++++++++++++++++++++------------- src/osd/ReplicatedPG.h | 36 +++++++++++++++++-- src/rados.cc | 25 ++++++++++--- 6 files changed, 105 insertions(+), 36 deletions(-) diff --git a/src/include/ceph_strings.cc b/src/include/ceph_strings.cc index c79e3cfac1d81..34fac00b63c4c 100644 --- a/src/include/ceph_strings.cc +++ b/src/include/ceph_strings.cc @@ -71,6 +71,7 @@ const char *ceph_osd_op_name(int op) case CEPH_OSD_OP_CALL: return "call"; case CEPH_OSD_OP_PGLS: return "pgls"; + case CEPH_OSD_OP_PGLS_FILTER: return "pgls-filter"; } return "???"; } diff --git a/src/include/librados.hpp b/src/include/librados.hpp index 70d9b29945244..4d399356ff094 100644 --- a/src/include/librados.hpp +++ b/src/include/librados.hpp @@ -98,7 +98,7 @@ public: int list_objects_open(pool_t pool, Rados::ListCtx *ctx); int list_objects_more(Rados::ListCtx& ctx, int max, std::list& entries); void list_objects_close(Rados::ListCtx& ctx); - void list_filter(Rados::ListCtx& ctx, const std::string& xattr, const std::string& val); + void list_filter(Rados::ListCtx& ctx, bufferlist& filter); int list_pools(std::list& v); int get_pool_stats(std::list& v, diff --git a/src/librados.cc b/src/librados.cc index fcf4f6fc69cd9..14598dd110dd0 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -1858,12 +1858,10 @@ void Rados::list_objects_close(Rados::ListCtx& ctx) delete h; } -void Rados::list_filter(Rados::ListCtx& ctx, const std::string& xattr, const std::string& val) +void Rados::list_filter(Rados::ListCtx& ctx, bufferlist& filter) { Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx; - h->filter.clear(); - ::encode(xattr, h->filter); - ::encode(val, h->filter); + h->filter = filter; } uint64_t Rados::get_last_version(rados_pool_t pool) diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index ec9abd9cae577..56ab86eb9ed3c 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -142,12 +142,14 @@ void ReplicatedPG::wait_for_degraded_object(const sobject_t& soid, Message *m) waiting_for_degraded_object[soid].push_back(m); } -bool ReplicatedPG::pgls_filter_find_parent(bufferlist& bl, inodeno_t search_ino, bufferlist& outdata) +bool PGLSParentFilter::filter(bufferlist& xattr_data, bufferlist& outdata) { - bufferlist::iterator iter = bl.begin(); + bufferlist::iterator iter = xattr_data.begin(); __u8 v; + generic_dout(0) << "PGLSParentFilter::filter" << dendl; ::decode(v, iter); + generic_dout(0) << "v=" << (int)v << dendl; if (v < 3) return false; @@ -155,10 +157,12 @@ bool ReplicatedPG::pgls_filter_find_parent(bufferlist& bl, inodeno_t search_ino, inodeno_t ino; ::decode(ino, iter); ::decode(ancestors, iter); + generic_dout(0) << "ino=" << ino << dendl; vector::iterator vi; for (vi = ancestors.begin(); vi != ancestors.end(); ++vi) { - if ( vi->dirino == search_ino) { + generic_dout(0) << "vi->dirino=" << vi->dirino << " parent_ino=" << parent_ino << dendl; + if ( vi->dirino == parent_ino) { ::encode(*vi, outdata); return true; } @@ -167,36 +171,47 @@ bool ReplicatedPG::pgls_filter_find_parent(bufferlist& bl, inodeno_t search_ino, return false; } -bool ReplicatedPG::pgls_filter(sobject_t& sobj, bufferlist::iterator& bp, - bufferlist& outdata) +bool PGLSPlainFilter::filter(bufferlist& xattr_data, bufferlist& outdata) { - string type, xattr; - ::decode(type, bp); - ::decode(xattr, bp); + if (val.size() != xattr_data.length()) + return false; + + if (memcmp(val.c_str(), xattr_data.c_str(), val.size())) + return false; + return true; +} + +bool ReplicatedPG::pgls_filter(PGLSFilter *filter, sobject_t& sobj, bufferlist& outdata) +{ bufferlist bl; - int ret = osd->store->getattr(coll_t(info.pgid), sobj, xattr.c_str(), bl); + int ret = osd->store->getattr(coll_t(info.pgid), sobj, filter->get_xattr().c_str(), bl); + dout(0) << "getattr (sobj=" << sobj << ", attr=" << filter->get_xattr() << ") returned " << ret << dendl; if (ret < 0) return false; - if (type.compare("find_parent") == 0) { - inodeno_t search_ino; - ::decode(search_ino, bp); - return pgls_filter_find_parent(bl, search_ino, outdata); - } else { - string val; - ::decode(val, bp); - dout(10) << "pgls_filter xattr=" << xattr << " val=" << val << dendl; + return filter->filter(bl, outdata); +} - if (val.size() != bl.length()) - return false; +int ReplicatedPG::get_pgls_filter(bufferlist::iterator& iter, PGLSFilter **pfilter) +{ + string type; + PGLSFilter *filter; + + ::decode(type, iter); - if (memcmp(val.c_str(), bl.c_str(), val.size())) - return false; + if (type.compare("parent") == 0) { + filter = new PGLSParentFilter(iter); + } else if (type.compare("plain") == 0) { + filter = new PGLSPlainFilter(iter); + } else { + return -EINVAL; } - return true; + *pfilter = filter; + + return 0; } @@ -208,7 +223,7 @@ void ReplicatedPG::do_pg_op(MOSDOp *op) bufferlist outdata; int result = 0; string cname, mname; - bool filter = false; + PGLSFilter *filter = NULL; bufferlist filter_out; snapid_t snapid = op->get_snapid(); @@ -219,7 +234,12 @@ void ReplicatedPG::do_pg_op(MOSDOp *op) case CEPH_OSD_OP_PGLS_FILTER: ::decode(cname, bp); ::decode(mname, bp); - filter = true; + + result = get_pgls_filter(bp, &filter); + if (result < 0) + break; + + assert(filter); // fall through @@ -268,7 +288,7 @@ void ReplicatedPG::do_pg_op(MOSDOp *op) } } if (filter) - keep = pgls_filter(*iter, bp, filter_out); + keep = pgls_filter(filter, *iter, filter_out); if (keep) response.entries.push_back(iter->oid); @@ -294,6 +314,7 @@ void ReplicatedPG::do_pg_op(MOSDOp *op) reply->set_result(result); osd->client_messenger->send_message(reply, op->get_connection()); op->put(); + delete filter; } void ReplicatedPG::calc_trim_to() diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index fd49c1a73a162..d128fe29642db 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -24,6 +24,38 @@ class MOSDSubOp; class MOSDSubOpReply; +class PGLSFilter { +protected: + string xattr; +public: + PGLSFilter() {} + virtual bool filter(bufferlist& xattr_data, bufferlist& outdata) = 0; + virtual string& get_xattr() { return xattr; } +}; + +class PGLSPlainFilter : public PGLSFilter { + string val; +public: + PGLSPlainFilter(bufferlist::iterator& params) { + ::decode(xattr, params); + ::decode(val, params); + } + virtual ~PGLSPlainFilter() {} + virtual bool filter(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(bufferlist& xattr_data, bufferlist& outdata); +}; + class ReplicatedPG : public PG { friend class OSD; public: @@ -612,8 +644,8 @@ protected: bufferlist::iterator& bp, ClassHandler::ClassMethod **pmethod); - bool pgls_filter(sobject_t& sobj, bufferlist::iterator& bp, bufferlist& outdata); - bool pgls_filter_find_parent(bufferlist& bl, inodeno_t search_ino, bufferlist& outdata); + bool pgls_filter(PGLSFilter *filter, sobject_t& sobj, bufferlist& outdata); + int get_pgls_filter(bufferlist::iterator& iter, PGLSFilter **pfilter); public: ReplicatedPG(OSD *o, PGPool *_pool, pg_t p, const sobject_t& oid, const sobject_t& ioid) : diff --git a/src/rados.cc b/src/rados.cc index 1df8fd39f1cf8..a0f90ba6b92ca 100644 --- a/src/rados.cc +++ b/src/rados.cc @@ -234,12 +234,29 @@ int main(int argc, const char **argv) rados.list_objects_open(p, &ctx); if (filter) { char *flt_str = strdup(filter); - char *xattr = strtok(flt_str, " "); + char *type = strtok(flt_str, " "); + char *xattr = strtok(NULL, " "); char *val = strtok(NULL, " "); - string xattr_str(xattr); - string val_str(val); - rados.list_filter(ctx, xattr, val); + if (!type || !xattr || !val) { + cerr << "filter was not specified correctly" << std::endl; + goto out; + } + + bufferlist bl; + ::encode(type, bl); + ::encode(xattr, bl); + if (strcmp(type, "parent") == 0) { + inodeno_t int_val = strtoll(val, NULL, 0); + ::encode(int_val, bl); + } else if (strcmp(type, "plain") == 0) { + ::encode(val, bl); + } else { + cerr << "unknown filter type" << std::endl; + goto out; + } + + rados.list_filter(ctx, bl); } while (1) { list vec; -- 2.39.5