virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool) = 0;
virtual int purge_buckets(std::string& id, vector<rgw_bucket>& buckets) { return -ENOTSUP; }
- virtual int disable_buckets(std::vector<rgw_bucket>& buckets) { return -ENOTSUP; }
- virtual int enable_buckets(std::vector<rgw_bucket>& buckets, uint64_t auid) { return -ENOTSUP; }
+ virtual int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled) { return -ENOTSUP; }
virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended) {
*suspended = false;
return 0;
/* 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) {
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;
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)
}
};
-/** 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 {
bucket.clear();
size = 0;
mtime = 0;
- etag = "";
count = 0;
}
};
{
return -ENOTSUP;
}
+
+int RGWFS::put_bucket_info(string& bucket_name, RGWBucketInfo& info)
+{
+ return -ENOTSUP;
+}
int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map<string, bufferlist> *attrs);
virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info);
+ virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info);
};
#endif
return ret;
}
-int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
+static int read_acls(struct req_state *s, RGWBucketInfo& bucket_info, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
{
string upload_id;
url_decode(s->args.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()) {
* 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;
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;
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;
}
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;
void RGWGetACLs::execute()
{
- ret = read_acls(s);
+ ret = read_acls(s, false);
if (ret < 0) {
send_response();
/** Get the HTTP request metadata */
extern void get_request_metadata(struct req_state *s, map<string, bufferlist>& 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.
return ret;
}
-int RGWRados::set_buckets_auid(vector<rgw_bucket>& buckets, uint64_t auid)
+int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
{
- librados::IoCtx ctx;
- vector<librados::PoolAsyncCompletion *> completions;
+ int ret = 0;
vector<rgw_bucket>::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<librados::PoolAsyncCompletion *>::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<rgw_bucket>& buckets)
-{
- return set_buckets_auid(buckets, RGW_SUSPENDED_USER_AUID);
-}
-
-int RGWRados::enable_buckets(vector<rgw_bucket>& 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;
}
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;
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<string, bufferlist>& m)
{
virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool);
virtual int purge_buckets(std::string& id, vector<rgw_bucket>& buckets);
- virtual int disable_buckets(std::vector<rgw_bucket>& buckets);
- virtual int enable_buckets(std::vector<rgw_bucket>& buckets, uint64_t auid);
+ virtual int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled);
virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended);
/** Delete an object.*/
int decode_policy(bufferlist& bl, ACLOwner *owner);
int get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& 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,