From e53eb38ce210e1035fba742d5d5b06900e4001d2 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Wed, 9 Dec 2015 14:58:35 -0500 Subject: [PATCH] librgw: implement stat_bucket, call from rgw_lookup Signed-off-by: Matt Benjamin --- src/rgw/rgw_file.cc | 38 +++++--- src/rgw/rgw_file.h | 222 ++++++++++++++++++++++++++++---------------- 2 files changed, 168 insertions(+), 92 deletions(-) diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 4a2ff02d5aa05..8ccaf2ad66684 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -35,13 +35,28 @@ const string RGWFileHandle::root_name = "/"; atomic RGWLibFS::fs_inst; +LookupFHResult RGWLibFS::stat_bucket(RGWFileHandle* parent, + const char *path, uint32_t flags) +{ + LookupFHResult fhr{nullptr, 0}; + std::string bucket_name{path}; + RGWStatBucketRequest req(cct, get_user(), bucket_name); + + int rc = librgw.get_fe()->execute_req(&req); + if ((rc == 0) && + (req.get_ret() == 0) && + (req.matched)) { + fhr = lookup_fh(parent, path, RGWFileHandle::FLAG_NONE); + } + return fhr; +} + LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent, const char *path, uint32_t flags) { /* find either-of , , only one of * which should exist; atomicity? */ - RGWLibFS* fs = parent->get_fs(); LookupFHResult fhr{nullptr, 0}; std::string object_name{path}; @@ -49,28 +64,28 @@ LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent, switch (ix) { case 0: { - RGWStatObjRequest req(cct, fs->get_user(), + RGWStatObjRequest req(cct, get_user(), parent->bucket_name(), object_name, RGWStatObjRequest::FLAG_NONE); int rc = librgw.get_fe()->execute_req(&req); if ((rc == 0) && (req.get_ret() == 0)) { - fhr = fs->lookup_fh(parent, path, RGWFileHandle::FLAG_NONE); + fhr = lookup_fh(parent, path, RGWFileHandle::FLAG_NONE); } } break; case 1: { - RGWStatLeafRequest req(cct, fs->get_user(), parent->bucket_name(), + RGWStatLeafRequest req(cct, get_user(), parent->bucket_name(), object_name); int rc = librgw.get_fe()->execute_req(&req); if ((rc == 0) && (req.get_ret() == 0)) { if (req.matched) { - fhr = fs->lookup_fh(parent, path, - (req.path.back() == '/') ? - RGWFileHandle::FLAG_DIRECTORY : - RGWFileHandle::FLAG_NONE); + fhr = lookup_fh(parent, path, + (req.path.back() == '/') ? + RGWFileHandle::FLAG_DIRECTORY : + RGWFileHandle::FLAG_NONE); } } } @@ -355,13 +370,10 @@ int rgw_lookup(struct rgw_fs *rgw_fs, if (strcmp(path, "/") == 0) { rgw_fh = parent->ref(); } else { - /* name lookup in root--for now) just get a handle */ - /* XXX RGWStatBucket? */ - fhr = fs->lookup_fh(parent, path); + fhr = fs->stat_bucket(parent, path, RGWFileHandle::FLAG_NONE); rgw_fh = get<0>(fhr); - if (! rgw_fh) - return -ENOMEM; + return -ENOENT; } } else { fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_NONE); diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 5392f70584c8e..d444cbdeee980 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -503,37 +503,43 @@ namespace rgw { LookupFHResult lookup_fh(RGWFileHandle* parent, const char *name, const uint32_t cflags = RGWFileHandle::FLAG_NONE) { + using std::get; + std::string sname(name); RGWFileHandle::FHCache::Latch lat; fh_key fhk = parent->make_fhk(sname); LookupFHResult fhr { nullptr, RGWFileHandle::FLAG_NONE }; - using std::get; - RGWFileHandle* fh = fh_cache.find_latch(fhk.fh_hk.object /* partition selector*/, fhk /* key */, lat /* serializer */, RGWFileHandle::FHCache::FLAG_LOCK); /* LATCHED */ - if ((! fh) && - (cflags & RGWFileHandle::FLAG_CREATE)) { - fh = new RGWFileHandle(this, get_inst(), parent, fhk, sname, cflags); - intrusive_ptr_add_ref(fh); /* sentinel ref */ - fh_cache.insert_latched(fh, lat, + if (! fh) { + if (cflags & RGWFileHandle::FLAG_CREATE) { + fh = new RGWFileHandle(this, get_inst(), parent, fhk, sname, cflags); + intrusive_ptr_add_ref(fh); /* sentinel ref */ + fh_cache.insert_latched(fh, lat, RGWFileHandle::FHCache::FLAG_NONE); - if (cflags & RGWFileHandle::FLAG_PSEUDO) - fh->set_pseudo(); - get<1>(fhr) = RGWFileHandle::FLAG_CREATE; + if (cflags & RGWFileHandle::FLAG_PSEUDO) + fh->set_pseudo(); + get<1>(fhr) = RGWFileHandle::FLAG_CREATE; + } else { + lat.lock->unlock(); /* !LATCHED */ + return fhr; + } } intrusive_ptr_add_ref(fh); /* call path/handle ref */ lat.lock->unlock(); /* !LATCHED */ - get<0>(fhr) = fh; return fhr; } + LookupFHResult stat_bucket(RGWFileHandle* parent, + const char *path, uint32_t flags); + LookupFHResult stat_leaf(RGWFileHandle* parent, const char *path, uint32_t flags); @@ -1236,87 +1242,145 @@ public: }; /* RGWStatObjRequest */ - class RGWStatLeafRequest : public RGWLibRequest, - public RGWListBucket /* RGWOp */ - { - public: - const std::string& bucket; - std::string path; - bool matched; - - RGWStatLeafRequest(CephContext* _cct, RGWUserInfo *_user, - const std::string& _bucket, const std::string& _path) - : RGWLibRequest(_cct, _user), bucket(_bucket), path(_path), - matched(false) { - default_max = 2; // logical max {"foo", "foo/"} - magic = 79; - op = this; - } +class RGWStatBucketRequest : public RGWLibRequest, + public RGWStatBucket /* RGWOp */ +{ +public: + std::string uri; + bool matched; - virtual bool only_bucket() { return false; } + RGWStatBucketRequest(CephContext* _cct, RGWUserInfo *_user, + const std::string& _path) + : RGWLibRequest(_cct, _user), matched(false) { + uri = "/" + _path; + magic = 79; + op = this; + } - virtual int op_init() { - // assign store, s, and dialect_handler - RGWObjectCtx* rados_ctx - = static_cast(get_state()->obj_ctx); - // framework promises to call op_init after parent init - assert(rados_ctx); - RGWOp::init(rados_ctx->store, get_state(), this); - op = this; // assign self as op: REQUIRED - return 0; - } + virtual bool only_bucket() { return false; } + + virtual int op_init() { + // assign store, s, and dialect_handler + RGWObjectCtx* rados_ctx + = static_cast(get_state()->obj_ctx); + // framework promises to call op_init after parent init + assert(rados_ctx); + RGWOp::init(rados_ctx->store, get_state(), this); + op = this; // assign self as op: REQUIRED + return 0; + } - virtual int header_init() { + virtual int header_init() { - struct req_state* s = get_state(); - s->info.method = "GET"; - s->op = OP_GET; + struct req_state* s = get_state(); + s->info.method = "GET"; + s->op = OP_GET; - /* XXX derp derp derp */ - std::string uri = "/" + bucket; - s->relative_uri = uri; - s->info.request_uri = uri; // XXX - s->info.effective_uri = uri; - s->info.request_params = ""; - s->info.domain = ""; /* XXX ? */ + /* XXX derp derp derp */ + s->relative_uri = uri; + s->info.request_uri = uri; // XXX + s->info.effective_uri = uri; + s->info.request_params = ""; + s->info.domain = ""; /* XXX ? */ - // woo - s->user = user; + // woo + s->user = user; - return 0; - } + return 0; + } - virtual int get_params() { - // XXX S3 - struct req_state* s = get_state(); - list_versions = s->info.args.exists("versions"); - if (!list_versions) { - marker = s->info.args.get("marker"); - } else { - marker.name = s->info.args.get("key-marker"); - marker.instance = s->info.args.get("version-id-marker"); - } - max_keys = default_max; // 2 - prefix = path; - delimiter = "/"; + virtual int get_params() { + return 0; + } + + virtual void send_response() { + if (bucket.bucket.name.length() > 0) + matched = true; + } + +}; /* RGWStatBucketRequest */ + +class RGWStatLeafRequest : public RGWLibRequest, + public RGWListBucket /* RGWOp */ +{ +public: + const std::string& bucket; + std::string path; + bool matched; + + RGWStatLeafRequest(CephContext* _cct, RGWUserInfo *_user, + const std::string& _bucket, const std::string& _path) + : RGWLibRequest(_cct, _user), bucket(_bucket), path(_path), + matched(false) { + default_max = 2; // logical max {"foo", "foo/"} + magic = 80; + op = this; + } + + virtual bool only_bucket() { return false; } + + virtual int op_init() { + // assign store, s, and dialect_handler + RGWObjectCtx* rados_ctx + = static_cast(get_state()->obj_ctx); + // framework promises to call op_init after parent init + assert(rados_ctx); + RGWOp::init(rados_ctx->store, get_state(), this); + op = this; // assign self as op: REQUIRED + return 0; + } + + virtual int header_init() { + + struct req_state* s = get_state(); + s->info.method = "GET"; + s->op = OP_GET; + + /* XXX derp derp derp */ + std::string uri = "/" + bucket; + s->relative_uri = uri; + s->info.request_uri = uri; // XXX + s->info.effective_uri = uri; + s->info.request_params = ""; + s->info.domain = ""; /* XXX ? */ + + // woo + s->user = user; + + return 0; + } + + virtual int get_params() { + // XXX S3 + struct req_state* s = get_state(); + list_versions = s->info.args.exists("versions"); + if (!list_versions) { + marker = s->info.args.get("marker"); + } else { + marker.name = s->info.args.get("key-marker"); + marker.instance = s->info.args.get("version-id-marker"); + } + max_keys = default_max; // 2 + prefix = path; + delimiter = "/"; #if 0 /* XXX? */ - encoding_type = s->info.args.get("encoding-type"); + encoding_type = s->info.args.get("encoding-type"); #endif - return 0; - } + return 0; + } - virtual void send_response() { - for (const auto& iter : objs) { - path = iter.key.name; - matched = true; - break; - } + virtual void send_response() { + for (const auto& iter : objs) { + path = iter.key.name; + matched = true; + break; } + } - virtual void send_versioned_response() { - send_response(); - } - }; /* RGWStatLeafRequest */ + virtual void send_versioned_response() { + send_response(); + } +}; /* RGWStatLeafRequest */ } /* namespace rgw */ -- 2.39.5