From 6752babdfda1be0524d82b84adfa4663aded32f6 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 26 Oct 2011 14:30:26 -0700 Subject: [PATCH] rgw: fix bucket suspension --- src/rgw/rgw_access.h | 4 +-- src/rgw/rgw_admin.cc | 5 +-- src/rgw/rgw_common.h | 18 +++++++--- src/rgw/rgw_fs.cc | 5 +++ src/rgw/rgw_fs.h | 1 + src/rgw/rgw_op.cc | 23 +++++-------- src/rgw/rgw_op.h | 7 ---- src/rgw/rgw_rados.cc | 78 ++++++++++++++++++++++++-------------------- src/rgw/rgw_rados.h | 4 +-- 9 files changed, 76 insertions(+), 69 deletions(-) diff --git a/src/rgw/rgw_access.h b/src/rgw/rgw_access.h index 0e421dc22687e..204dd38506cce 100644 --- a/src/rgw/rgw_access.h +++ b/src/rgw/rgw_access.h @@ -128,8 +128,7 @@ public: virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool) = 0; virtual int purge_buckets(std::string& id, vector& buckets) { return -ENOTSUP; } - virtual int disable_buckets(std::vector& buckets) { return -ENOTSUP; } - virtual int enable_buckets(std::vector& buckets, uint64_t auid) { return -ENOTSUP; } + virtual int set_buckets_enabled(std::vector& buckets, bool enabled) { return -ENOTSUP; } virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended) { *suspended = false; return 0; @@ -271,6 +270,7 @@ public: /* The bucket here can either be the bucket name identifier, or the ID * in period format: ".123" */ virtual int get_bucket_info(void *ctx, string& bucket, RGWBucketInfo& info) = 0; + virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info) = 0; virtual int remove_temp_objects(string date, string time) { diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index e8ae9cc519fbe..3747ad72daa34 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -1218,10 +1218,7 @@ int main(int argc, char **argv) RGWBucketEnt obj = iter->second; bucket_names.push_back(obj.bucket); } - if (disable) - ret = rgwstore->disable_buckets(bucket_names); - else - ret = rgwstore->enable_buckets(bucket_names, info.auid); + ret = rgwstore->set_buckets_enabled(bucket_names, !disable); if (ret < 0) { cerr << "ERROR: failed to change pool" << std::endl; return 1; diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 8d5c66a928d66..72c4ed8b93333 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -430,24 +430,34 @@ inline ostream& operator<<(ostream& out, const rgw_bucket b) { extern rgw_bucket rgw_root_bucket; +enum RGWBucketFlags { + BUCKET_SUSPENDED = 0x1, +}; + struct RGWBucketInfo { rgw_bucket bucket; string owner; + uint32_t flags; void encode(bufferlist& bl) const { - __u32 ver = 2; + __u32 ver = 3; ::encode(ver, bl); ::encode(bucket, bl); ::encode(owner, bl); + ::encode(flags, bl); } void decode(bufferlist::iterator& bl) { __u32 ver; ::decode(ver, bl); ::decode(bucket, bl); - if (ver > 1) + if (ver >= 2) ::decode(owner, bl); + if (ver >= 3) + ::decode(flags, bl); } + + RGWBucketInfo() : flags(0) {} }; WRITE_CLASS_ENCODER(RGWBucketInfo) @@ -545,12 +555,11 @@ struct RGWObjEnt { } }; -/** Store basic data on an object */ +/** Store basic data on bucket */ struct RGWBucketEnt { rgw_bucket bucket; size_t size; time_t mtime; - string etag; uint64_t count; void encode(bufferlist& bl) const { @@ -583,7 +592,6 @@ struct RGWBucketEnt { bucket.clear(); size = 0; mtime = 0; - etag = ""; count = 0; } }; diff --git a/src/rgw/rgw_fs.cc b/src/rgw/rgw_fs.cc index 3b9c1d0b85bd4..9f213464ddfdd 100644 --- a/src/rgw/rgw_fs.cc +++ b/src/rgw/rgw_fs.cc @@ -667,3 +667,8 @@ int RGWFS::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info) { return -ENOTSUP; } + +int RGWFS::put_bucket_info(string& bucket_name, RGWBucketInfo& info) +{ + return -ENOTSUP; +} diff --git a/src/rgw/rgw_fs.h b/src/rgw/rgw_fs.h index ec1957afc1f61..56e2959936a56 100644 --- a/src/rgw/rgw_fs.h +++ b/src/rgw/rgw_fs.h @@ -63,6 +63,7 @@ public: int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map *attrs); virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info); + virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info); }; #endif diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 2c75cc2f313c8..7e4507ddbe841 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -172,21 +172,16 @@ static int get_obj_attrs(struct req_state *s, rgw_obj& obj, mapargs.get("uploadId"), upload_id); string oid = object; rgw_obj obj; - if (!oid.empty()) { - bool suspended; - int ret = rgwstore->bucket_suspended(bucket, &suspended); - if (ret < 0) - return ret; - - if (suspended) - return -ERR_USER_SUSPENDED; + if (bucket_info.flags & BUCKET_SUSPENDED) { + dout(0) << "bucket " << bucket_info.bucket.name << " is suspended" << dendl; + return -ERR_USER_SUSPENDED; } if (!oid.empty() && !upload_id.empty()) { @@ -224,7 +219,7 @@ int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& b * only_bucket: If true, reads the bucket ACL rather than the object ACL. * Returns: 0 on success, -ERR# otherwise. */ -int read_acls(struct req_state *s, bool only_bucket) +static int read_acls(struct req_state *s, bool only_bucket) { int ret = 0; string obj_str; @@ -242,8 +237,8 @@ int read_acls(struct req_state *s, bool only_bucket) rgwstore->set_atomic(s->obj_ctx, obj); } + RGWBucketInfo bucket_info; if (s->bucket_name_str.size()) { - RGWBucketInfo bucket_info; ret = rgwstore->get_bucket_info(s->obj_ctx, s->bucket_name_str, bucket_info); if (ret < 0) { dout(0) << "couldn't get bucket from bucket_name (name=" << s->bucket_name_str << ")" << dendl; @@ -253,7 +248,7 @@ int read_acls(struct req_state *s, bool only_bucket) s->bucket_owner = bucket_info.owner; } - ret = read_acls(s, s->acl, s->bucket, obj_str); + ret = read_acls(s, bucket_info, s->acl, s->bucket, obj_str); return ret; } @@ -926,7 +921,7 @@ int RGWCopyObj::verify_permission() src_bucket = bucket_info.bucket; /* just checking the bucket's permission */ - ret = read_acls(s, &src_policy, src_bucket, empty_str); + ret = read_acls(s, bucket_info, &src_policy, src_bucket, empty_str); if (ret < 0) return ret; @@ -1008,7 +1003,7 @@ int RGWGetACLs::verify_permission() void RGWGetACLs::execute() { - ret = read_acls(s); + ret = read_acls(s, false); if (ret < 0) { send_response(); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index e54d2a98849ed..2e6fe39039cb7 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -22,13 +22,6 @@ struct req_state; /** Get the HTTP request metadata */ extern void get_request_metadata(struct req_state *s, map& attrs); -/** - * Get the ACL for an object off of disk. If you hold the req_state, use next - * method. - */ -extern int read_acls(RGWAccessControlPolicy *policy, rgw_obj& bucket, string& object); -/** Get the ACL needed for a request off of disk.*/ -extern int read_acls(struct req_state *s, bool only_bucket = false); /** * Provide the base class for all ops. diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index d2c235f0115b6..48d15fa1fd446 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -939,56 +939,51 @@ int RGWRados::purge_buckets(std::string& id, vector& buckets) return ret; } -int RGWRados::set_buckets_auid(vector& buckets, uint64_t auid) +int RGWRados::set_buckets_enabled(vector& buckets, bool enabled) { - librados::IoCtx ctx; - vector completions; + int ret = 0; vector::iterator iter; + for (iter = buckets.begin(); iter != buckets.end(); ++iter) { rgw_bucket& bucket = *iter; - int r = open_bucket_ctx(bucket, ctx); - if (r < 0) - return r; + if (enabled) + dout(20) << "enabling bucket name=" << bucket.name << dendl; + else + dout(20) << "disabling bucket name=" << bucket.name << dendl; - librados::PoolAsyncCompletion *c = librados::Rados::pool_async_create_completion(); - completions.push_back(c); - ctx.set_auid_async(auid, c); - } + RGWBucketInfo info; + int r = get_bucket_info(NULL, bucket.name, info); + if (r < 0) { + dout(0) << "get_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl; + ret = r; + continue; + } + if (enabled) { + info.flags &= ~BUCKET_SUSPENDED; + } else { + info.flags |= BUCKET_SUSPENDED; + } - vector::iterator citer; - for (citer = completions.begin(); citer != completions.end(); ++citer) { - PoolAsyncCompletion *c = *citer; - c->wait(); - c->release(); + r = put_bucket_info(bucket.name, info); + if (r < 0) { + dout(0) << "put_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl; + ret = r; + continue; + } } - return 0; } -int RGWRados::disable_buckets(vector& buckets) -{ - return set_buckets_auid(buckets, RGW_SUSPENDED_USER_AUID); -} - -int RGWRados::enable_buckets(vector& buckets, uint64_t auid) -{ - return set_buckets_auid(buckets, auid); -} - int RGWRados::bucket_suspended(rgw_bucket& bucket, bool *suspended) { - librados::IoCtx ctx; - int r = open_bucket_ctx(bucket, ctx); - if (r < 0) - return r; - - uint64_t auid; - int ret = ctx.get_auid(&auid); - if (ret < 0) + RGWBucketInfo bucket_info; + int ret = rgwstore->get_bucket_info(NULL, bucket.name, bucket_info); + if (ret < 0) { return ret; + } - *suspended = (auid == RGW_SUSPENDED_USER_AUID); + *suspended = ((bucket_info.flags & BUCKET_SUSPENDED) != 0); return 0; } @@ -1789,6 +1784,7 @@ int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, mtime = ut.sec(); } catch (buffer::error& err) { dout(0) << "ERROR: failed decoding object (obj=" << obj << ") info (either size or mtime), aborting" << dendl; + return -EIO; } if (psize) *psize = size; @@ -1848,6 +1844,18 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf return 0; } +int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info) +{ + bufferlist bl; + + ::encode(info, bl); + + string unused; + + int ret = rgw_put_obj(unused, pi_buckets_rados, bucket_name, bl.c_str(), bl.length()); + + return ret; +} int RGWRados::tmap_get(rgw_obj& obj, bufferlist& header, std::map& m) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 63379be990a64..2ae5a5d01d1c6 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -239,8 +239,7 @@ public: virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool); virtual int purge_buckets(std::string& id, vector& buckets); - virtual int disable_buckets(std::vector& buckets); - virtual int enable_buckets(std::vector& buckets, uint64_t auid); + virtual int set_buckets_enabled(std::vector& buckets, bool enabled); virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended); /** Delete an object.*/ @@ -309,6 +308,7 @@ public: int decode_policy(bufferlist& bl, ACLOwner *owner); int get_bucket_stats(rgw_bucket& bucket, map& stats); virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info); + virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info); int cls_rgw_init_index(rgw_bucket& bucket, string& oid); int cls_obj_prepare_op(rgw_bucket& bucket, uint8_t op, string& tag, -- 2.39.5