mirror of
https://github.com/ceph/ceph
synced 2025-01-01 08:32:24 +00:00
librgw: implement stat_bucket, call from rgw_lookup
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
This commit is contained in:
parent
21bf277639
commit
e53eb38ce2
@ -35,13 +35,28 @@ const string RGWFileHandle::root_name = "/";
|
||||
|
||||
atomic<uint32_t> 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 <object_name>, <object_name/>, 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);
|
||||
|
@ -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;
|
||||
class RGWStatBucketRequest : public RGWLibRequest,
|
||||
public RGWStatBucket /* RGWOp */
|
||||
{
|
||||
public:
|
||||
std::string uri;
|
||||
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;
|
||||
RGWStatBucketRequest(CephContext* _cct, RGWUserInfo *_user,
|
||||
const std::string& _path)
|
||||
: RGWLibRequest(_cct, _user), matched(false) {
|
||||
uri = "/" + _path;
|
||||
magic = 79;
|
||||
op = this;
|
||||
}
|
||||
|
||||
virtual bool only_bucket() { return false; }
|
||||
|
||||
virtual int op_init() {
|
||||
// assign store, s, and dialect_handler
|
||||
RGWObjectCtx* rados_ctx
|
||||
= static_cast<RGWObjectCtx*>(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 */
|
||||
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() {
|
||||
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<RGWObjectCtx*>(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");
|
||||
}
|
||||
|
||||
virtual bool only_bucket() { return false; }
|
||||
|
||||
virtual int op_init() {
|
||||
// assign store, s, and dialect_handler
|
||||
RGWObjectCtx* rados_ctx
|
||||
= static_cast<RGWObjectCtx*>(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 = "/";
|
||||
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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user