return 0;
}
-int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket)
+int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket, time_t creation_time)
{
int ret;
string& bucket_name = bucket.name;
RGWBucketEnt new_bucket;
new_bucket.bucket = bucket;
new_bucket.size = 0;
- time(&new_bucket.mtime);
+ if (!creation_time)
+ time(&new_bucket.creation_time);
+ else
+ new_bucket.creation_time = creation_time;
::encode(new_bucket, bl);
string buckets_obj_id;
rgw_bucket& bucket = bucket_info.bucket;
- ret = store->create_bucket(user_id, bucket, region_name, attrs, objv_tracker, NULL, NULL);
+ RGWBucketInfo new_info;
+
+ ret = store->create_bucket(user_id, bucket, region_name, attrs, objv_tracker,
+ NULL, bucket_info.creation_time, NULL, &new_info);
if (ret && ret != -EEXIST)
goto done;
goto done;
}
- ret = rgw_add_bucket(store, user_id, bucket);
+ ret = rgw_add_bucket(store, user_id, bucket, new_info.creation_time);
if (ret == -EEXIST)
ret = 0;
cout << "bucket info mismatch: expected " << actual_bucket << " got " << bucket << std::endl;
if (fix) {
cout << "fixing" << std::endl;
- r = rgw_add_bucket(store, user_id, actual_bucket);
+ r = rgw_add_bucket(store, user_id, actual_bucket, bucket_info.creation_time);
if (r < 0) {
cerr << "failed to fix bucket: " << cpp_strerror(-r) << std::endl;
}
if (r < 0)
return r;
- r = rgw_add_bucket(store, user_id, bucket);
+ r = rgw_add_bucket(store, user_id, bucket, 0);
if (r < 0)
return r;
} else {
if (ret < 0)
return ret;
- ret = rgw_add_bucket(store, bci.info.owner, bci.info.bucket);
+ ret = rgw_add_bucket(store, bci.info.owner, bci.info.bucket, bci.info.creation_time);
if (ret < 0)
return ret;
extern int rgw_read_user_buckets(RGWRados *store, string user_id, RGWUserBuckets& buckets,
const string& marker, uint64_t max, bool need_stats);
-extern int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket);
+extern int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket, time_t creation_time);
extern int rgw_remove_user_bucket_info(RGWRados *store, string user_id, rgw_bucket& bucket);
extern int rgw_remove_object(RGWRados *store, rgw_bucket& bucket, std::string& object);
string owner;
uint32_t flags;
string region;
+ time_t creation_time;
void encode(bufferlist& bl) const {
- ENCODE_START(5, 4, bl);
+ ENCODE_START(6, 4, bl);
::encode(bucket, bl);
::encode(owner, bl);
::encode(flags, bl);
::encode(region, bl);
+ ::encode(creation_time, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator& bl) {
- DECODE_START_LEGACY_COMPAT_LEN_32(5, 4, 4, bl);
+ DECODE_START_LEGACY_COMPAT_LEN_32(6, 4, 4, bl);
::decode(bucket, bl);
if (struct_v >= 2)
::decode(owner, bl);
::decode(flags, bl);
if (struct_v >= 5)
::decode(region, bl);
+ if (struct_v >= 6)
+ ::decode(creation_time, bl);
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
- RGWBucketInfo() : flags(0) {}
+ RGWBucketInfo() : flags(0), creation_time(0) {}
};
WRITE_CLASS_ENCODER(RGWBucketInfo)
rgw_bucket bucket;
size_t size;
size_t size_rounded;
- time_t mtime;
+ time_t creation_time;
uint64_t count;
- RGWBucketEnt() : size(0), size_rounded(0), mtime(0), count(0) {}
+ RGWBucketEnt() : size(0), size_rounded(0), creation_time(0), count(0) {}
void encode(bufferlist& bl) const {
ENCODE_START(5, 5, bl);
uint64_t s = size;
- __u32 mt = mtime;
+ __u32 mt = creation_time;
string empty_str; // originally had the bucket name here, but we encode bucket later
::encode(empty_str, bl);
::encode(s, bl);
::decode(s, bl);
::decode(mt, bl);
size = s;
- mtime = mt;
+ creation_time = mt;
if (struct_v >= 2)
::decode(count, bl);
if (struct_v >= 3)
}
void dump(Formatter *f) const;
static void generate_test_instances(list<RGWBucketEnt*>& o);
- void clear() {
- bucket.clear();
- size = 0;
- size_rounded = 0;
- mtime = 0;
- count = 0;
- }
};
WRITE_CLASS_ENCODER(RGWBucketEnt)
void RGWBucketInfo::dump(Formatter *f) const
{
encode_json("bucket", bucket, f);
+ encode_json("creation_time", creation_time, f);
encode_json("owner", owner, f);
encode_json("flags", flags, f);
encode_json("region", region, f);
void RGWBucketInfo::decode_json(JSONObj *obj) {
JSONDecoder::decode_json("bucket", bucket, obj);
+ JSONDecoder::decode_json("creation_time", creation_time, obj);
JSONDecoder::decode_json("owner", owner, obj);
JSONDecoder::decode_json("flags", flags, obj);
JSONDecoder::decode_json("region", region, obj);
encode_json("bucket", bucket, f);
encode_json("size", size, f);
encode_json("size_rounded", size_rounded, f);
- encode_json("mtime", mtime, f);
+ encode_json("mtime", creation_time, f); /* mtime / creation time discrepency needed for backward compatibility */
encode_json("count", count, f);
}
}
}
- rgw_bucket master_bucket;
+ RGWBucketInfo master_info;
rgw_bucket *pmaster_bucket;
+ time_t creation_time;
if (!store->region.is_master) {
JSONParser jp;
return;
JSONDecoder::decode_json("object_ver", objv, &jp);
- JSONDecoder::decode_json("bucket", master_bucket, &jp);
+ JSONDecoder::decode_json("bucket_info", master_info, &jp);
ldout(s->cct, 20) << "parsed: objv.tag=" << objv.tag << " objv.ver=" << objv.ver << dendl;
- pmaster_bucket = &master_bucket;
+ ldout(s->cct, 20) << "got creation time: << " << master_info.creation_time << dendl;
+ pmaster_bucket= &master_info.bucket;
+ creation_time = master_info.creation_time;
pobjv = &objv;
} else {
pmaster_bucket = NULL;
+ creation_time = 0;
}
string region_name;
attrs[RGW_ATTR_ACL] = aclbl;
s->bucket.name = s->bucket_name_str;
- ret = store->create_bucket(s->user.user_id, s->bucket, region_name, attrs, objv_tracker, pobjv, pmaster_bucket, true);
+ ret = store->create_bucket(s->user.user_id, s->bucket, region_name, attrs, objv_tracker, pobjv,
+ creation_time, pmaster_bucket, &info, true);
/* continue if EEXIST and create_bucket will fail below. this way we can recover
* from a partial create by retrying it. */
ldout(s->cct, 20) << "rgw_create_bucket returned ret=" << ret << " bucket=" << s->bucket << dendl;
* info, verify that the reported bucket owner is the current user.
* If all is ok then update the user's list of buckets
*/
- RGWBucketInfo info;
- map<string, bufferlist> attrs;
- int r = store->get_bucket_info(NULL, s->bucket.name, info, &s->objv_tracker, NULL, &attrs);
- if (r < 0) {
- ldout(s->cct, 0) << "ERROR: get_bucket_info on bucket=" << s->bucket.name << " returned err=" << r << " after create_bucket returned -EEXIST" << dendl;
- ret = r;
- return;
- }
if (info.owner.compare(s->user.user_id) != 0) {
ret = -ERR_BUCKET_EXISTS;
return;
s->bucket = info.bucket;
}
- ret = rgw_add_bucket(store, s->user.user_id, s->bucket);
+ ret = rgw_add_bucket(store, s->user.user_id, s->bucket, info.creation_time);
if (ret && !existed && ret != -EEXIST) /* if it exists (or previously existed), don't remove it! */
rgw_remove_user_bucket_info(store, s->user.user_id, s->bucket);
if (ret == -EEXIST)
ret = -ERR_BUCKET_EXISTS;
-
- bucket = s->bucket;
}
int RGWDeleteBucket::verify_permission()
RGWAccessControlPolicy policy;
string location_constraint;
RGWObjVersionTracker objv_tracker;
- rgw_bucket bucket;
+ RGWBucketInfo info;
bufferlist in_data;
map<std::string, bufferlist>& attrs,
RGWObjVersionTracker& objv_tracker,
obj_version *pobjv,
+ time_t creation_time,
rgw_bucket *pmaster_bucket,
+ RGWBucketInfo *pinfo,
bool exclusive)
{
#define MAX_CREATE_RETRIES 20 /* need to bound retries */
info.bucket = bucket;
info.owner = owner;
info.region = region_name;
+ if (!creation_time)
+ time(&info.creation_time);
+ else
+ info.creation_time = creation_time;
ret = put_bucket_info(bucket.name, info, exclusive, &objv_tracker, &attrs);
if (ret == -EEXIST) {
librados::IoCtx index_ctx; // context for new bucket
return r;
}
}
+ if (pinfo)
+ *pinfo = info;
return ret;
}
map<std::string,bufferlist>& attrs,
RGWObjVersionTracker& objv_tracker,
obj_version *pobjv,
+ time_t creation_time,
rgw_bucket *master_bucket,
+ RGWBucketInfo *pinfo,
bool exclusive = true);
virtual int add_bucket_placement(std::string& new_pool);
virtual int remove_bucket_placement(std::string& new_pool);
{
s->formatter->open_object_section("Bucket");
s->formatter->dump_string("Name", obj.bucket.name);
- dump_time(s, "CreationDate", &obj.mtime);
+ dump_time(s, "CreationDate", &obj.creation_time);
s->formatter->close_section();
}
f.open_object_section("info");
encode_json("object_ver", objv_tracker.read_version, &f);
- encode_json("bucket", bucket, &f);
+ encode_json("bucket_info", info, &f);
f.close_section();
rgw_flush_formatter_and_reset(s, &f);
}