mirror of
https://github.com/ceph/ceph
synced 2025-01-03 09:32:43 +00:00
rgw: delete-at and delete-after also on obj put / copy
And potentially later we could use also the S3 api, so it could work with multipart upload, and POST obj. Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
parent
9db8122680
commit
fa347d8f69
@ -1581,7 +1581,7 @@ class RGWPutObjProcessor_Multipart : public RGWPutObjProcessor_Atomic
|
|||||||
protected:
|
protected:
|
||||||
int prepare(RGWRados *store, string *oid_rand);
|
int prepare(RGWRados *store, string *oid_rand);
|
||||||
int do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
int do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match = NULL, const char *if_nomatch = NULL);
|
const char *if_match = NULL, const char *if_nomatch = NULL);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1655,7 +1655,7 @@ static bool is_v2_upload_id(const string& upload_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int RGWPutObjProcessor_Multipart::do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
int RGWPutObjProcessor_Multipart::do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match, const char *if_nomatch)
|
const char *if_match, const char *if_nomatch)
|
||||||
{
|
{
|
||||||
complete_writing_data();
|
complete_writing_data();
|
||||||
@ -1666,6 +1666,7 @@ int RGWPutObjProcessor_Multipart::do_complete(string& etag, time_t *mtime, time_
|
|||||||
head_obj_op.meta.set_mtime = set_mtime;
|
head_obj_op.meta.set_mtime = set_mtime;
|
||||||
head_obj_op.meta.mtime = mtime;
|
head_obj_op.meta.mtime = mtime;
|
||||||
head_obj_op.meta.owner = s->owner.get_id();
|
head_obj_op.meta.owner = s->owner.get_id();
|
||||||
|
head_obj_op.meta.delete_at = delete_at;
|
||||||
|
|
||||||
int r = head_obj_op.write_meta(s->obj_size, attrs);
|
int r = head_obj_op.write_meta(s->obj_size, attrs);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1788,6 +1789,17 @@ static int get_system_versioning_params(req_state *s, uint64_t *olh_epoch, strin
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void encode_delete_at_attr(time_t delete_at, map<string, bufferlist>& attrs)
|
||||||
|
{
|
||||||
|
if (delete_at == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferlist delatbl;
|
||||||
|
::encode(utime_t(delete_at, 0), delatbl);
|
||||||
|
attrs[RGW_ATTR_DELETE_AT] = delatbl;
|
||||||
|
}
|
||||||
|
|
||||||
void RGWPutObj::execute()
|
void RGWPutObj::execute()
|
||||||
{
|
{
|
||||||
RGWPutObjProcessor *processor = NULL;
|
RGWPutObjProcessor *processor = NULL;
|
||||||
@ -1985,8 +1997,10 @@ void RGWPutObj::execute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
rgw_get_request_metadata(s->cct, s->info, attrs);
|
rgw_get_request_metadata(s->cct, s->info, attrs);
|
||||||
|
encode_delete_at_attr(delete_at, attrs);
|
||||||
|
|
||||||
|
ret = processor->complete(etag, &mtime, 0, attrs, delete_at, if_match, if_nomatch);
|
||||||
|
|
||||||
ret = processor->complete(etag, &mtime, 0, attrs, if_match, if_nomatch);
|
|
||||||
done:
|
done:
|
||||||
dispose_processor(processor);
|
dispose_processor(processor);
|
||||||
perfcounter->tinc(l_rgw_put_lat,
|
perfcounter->tinc(l_rgw_put_lat,
|
||||||
@ -2105,7 +2119,7 @@ void RGWPostObj::execute()
|
|||||||
attrs[RGW_ATTR_CONTENT_TYPE] = ct_bl;
|
attrs[RGW_ATTR_CONTENT_TYPE] = ct_bl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = processor->complete(etag, NULL, 0, attrs);
|
ret = processor->complete(etag, NULL, 0, attrs, delete_at);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dispose_processor(processor);
|
dispose_processor(processor);
|
||||||
@ -2372,12 +2386,7 @@ void RGWPutMetadataObject::execute()
|
|||||||
/* Filter currently existing attributes. */
|
/* Filter currently existing attributes. */
|
||||||
prepare_add_del_attrs(orig_attrs, attrs, rmattrs);
|
prepare_add_del_attrs(orig_attrs, attrs, rmattrs);
|
||||||
populate_with_generic_attrs(s, attrs);
|
populate_with_generic_attrs(s, attrs);
|
||||||
|
encode_delete_at_attr(delete_at, attrs);
|
||||||
if (!delete_at.is_zero()) {
|
|
||||||
bufferlist delatbl;
|
|
||||||
::encode(delete_at, delatbl);
|
|
||||||
attrs[RGW_ATTR_DELETE_AT] = delatbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, NULL);
|
ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, NULL);
|
||||||
}
|
}
|
||||||
@ -2612,6 +2621,8 @@ void RGWCopyObj::execute()
|
|||||||
obj_ctx.set_atomic(src_obj);
|
obj_ctx.set_atomic(src_obj);
|
||||||
obj_ctx.set_atomic(dst_obj);
|
obj_ctx.set_atomic(dst_obj);
|
||||||
|
|
||||||
|
encode_delete_at_attr(delete_at, attrs);
|
||||||
|
|
||||||
ret = store->copy_obj(obj_ctx,
|
ret = store->copy_obj(obj_ctx,
|
||||||
s->user.user_id,
|
s->user.user_id,
|
||||||
client_id,
|
client_id,
|
||||||
@ -2631,6 +2642,7 @@ void RGWCopyObj::execute()
|
|||||||
attrs_mod,
|
attrs_mod,
|
||||||
attrs, RGW_OBJ_CATEGORY_MAIN,
|
attrs, RGW_OBJ_CATEGORY_MAIN,
|
||||||
olh_epoch,
|
olh_epoch,
|
||||||
|
delete_at,
|
||||||
(version_id.empty() ? NULL : &version_id),
|
(version_id.empty() ? NULL : &version_id),
|
||||||
&s->req_id, /* use req_id as tag */
|
&s->req_id, /* use req_id as tag */
|
||||||
&etag,
|
&etag,
|
||||||
|
@ -436,6 +436,8 @@ protected:
|
|||||||
uint64_t olh_epoch;
|
uint64_t olh_epoch;
|
||||||
string version_id;
|
string version_id;
|
||||||
|
|
||||||
|
time_t delete_at;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RGWPutObj() {
|
RGWPutObj() {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -449,6 +451,7 @@ public:
|
|||||||
mtime = 0;
|
mtime = 0;
|
||||||
user_manifest_parts_hash = NULL;
|
user_manifest_parts_hash = NULL;
|
||||||
olh_epoch = 0;
|
olh_epoch = 0;
|
||||||
|
delete_at = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
||||||
@ -489,11 +492,12 @@ protected:
|
|||||||
string content_type;
|
string content_type;
|
||||||
RGWAccessControlPolicy policy;
|
RGWAccessControlPolicy policy;
|
||||||
map<string, bufferlist> attrs;
|
map<string, bufferlist> attrs;
|
||||||
|
time_t delete_at;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RGWPostObj() : min_len(0), max_len(LLONG_MAX), ret(0), len(0), ofs(0),
|
RGWPostObj() : min_len(0), max_len(LLONG_MAX), ret(0), len(0), ofs(0),
|
||||||
supplied_md5_b64(NULL), supplied_etag(NULL),
|
supplied_md5_b64(NULL), supplied_etag(NULL),
|
||||||
data_pending(false) {}
|
data_pending(false), delete_at(0) {}
|
||||||
|
|
||||||
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
||||||
RGWOp::init(store, s, h);
|
RGWOp::init(store, s, h);
|
||||||
@ -579,11 +583,11 @@ protected:
|
|||||||
int ret;
|
int ret;
|
||||||
RGWAccessControlPolicy policy;
|
RGWAccessControlPolicy policy;
|
||||||
string placement_rule;
|
string placement_rule;
|
||||||
utime_t delete_at;
|
time_t delete_at;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RGWPutMetadataObject()
|
RGWPutMetadataObject()
|
||||||
: ret(0)
|
: ret(0), delete_at(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
|
||||||
@ -658,6 +662,7 @@ protected:
|
|||||||
string version_id;
|
string version_id;
|
||||||
uint64_t olh_epoch;
|
uint64_t olh_epoch;
|
||||||
|
|
||||||
|
time_t delete_at;
|
||||||
|
|
||||||
int init_common();
|
int init_common();
|
||||||
|
|
||||||
@ -680,6 +685,7 @@ public:
|
|||||||
attrs_mod = RGWRados::ATTRSMOD_NONE;
|
attrs_mod = RGWRados::ATTRSMOD_NONE;
|
||||||
last_ofs = 0;
|
last_ofs = 0;
|
||||||
olh_epoch = 0;
|
olh_epoch = 0;
|
||||||
|
delete_at = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_copy_location(const string& src, string& bucket_name, rgw_obj_key& object);
|
static bool parse_copy_location(const string& src, string& bucket_name, rgw_obj_key& object);
|
||||||
|
@ -892,10 +892,10 @@ void RGWObjVersionTracker::generate_new_write_ver(CephContext *cct)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int RGWPutObjProcessor::complete(string& etag, time_t *mtime, time_t set_mtime,
|
int RGWPutObjProcessor::complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match, const char * if_nomatch)
|
const char *if_match, const char * if_nomatch)
|
||||||
{
|
{
|
||||||
int r = do_complete(etag, mtime, set_mtime, attrs, if_match, if_nomatch);
|
int r = do_complete(etag, mtime, set_mtime, attrs, delete_at, if_match, if_nomatch);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1209,7 +1209,7 @@ int RGWPutObjProcessor_Atomic::complete_writing_data()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int RGWPutObjProcessor_Atomic::do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
int RGWPutObjProcessor_Atomic::do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match,
|
const char *if_match,
|
||||||
const char *if_nomatch) {
|
const char *if_nomatch) {
|
||||||
int r = complete_writing_data();
|
int r = complete_writing_data();
|
||||||
@ -1235,6 +1235,7 @@ int RGWPutObjProcessor_Atomic::do_complete(string& etag, time_t *mtime, time_t s
|
|||||||
obj_op.meta.owner = bucket_info.owner;
|
obj_op.meta.owner = bucket_info.owner;
|
||||||
obj_op.meta.flags = PUT_OBJ_CREATE;
|
obj_op.meta.flags = PUT_OBJ_CREATE;
|
||||||
obj_op.meta.olh_epoch = olh_epoch;
|
obj_op.meta.olh_epoch = olh_epoch;
|
||||||
|
obj_op.meta.delete_at = delete_at;
|
||||||
|
|
||||||
r = obj_op.write_meta(obj_len, attrs);
|
r = obj_op.write_meta(obj_len, attrs);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -3624,6 +3625,17 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meta.delete_at > 0) {
|
||||||
|
rgw_obj_key obj_key;
|
||||||
|
obj.get_index_key(&obj_key);
|
||||||
|
|
||||||
|
r = store->objexp_hint_add(utime_t(meta.delete_at, 0), bucket.name, bucket.bucket_id, obj_key);
|
||||||
|
if (r < 0) {
|
||||||
|
ldout(store->ctx(), 0) << "ERROR: objexp_hint_add() returned r=" << r << ", object will not get removed" << dendl;
|
||||||
|
/* ignoring error, nothing we can do at this point */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* update quota cache */
|
/* update quota cache */
|
||||||
store->quota_handler->update_stats(meta.owner, bucket, (orig_exists ? 0 : 1), size, orig_size);
|
store->quota_handler->update_stats(meta.owner, bucket, (orig_exists ? 0 : 1), size, orig_size);
|
||||||
|
|
||||||
@ -3861,8 +3873,8 @@ public:
|
|||||||
processor->set_extra_data_len(len);
|
processor->set_extra_data_len(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int complete(string& etag, time_t *mtime, time_t set_mtime, map<string, bufferlist>& attrs) {
|
int complete(string& etag, time_t *mtime, time_t set_mtime, map<string, bufferlist>& attrs, time_t delete_at) {
|
||||||
return processor->complete(etag, mtime, set_mtime, attrs);
|
return processor->complete(etag, mtime, set_mtime, attrs, delete_at);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3925,7 +3937,7 @@ int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy_obj_data(rctx, dest_bucket_info, read_op, end, obj, obj, max_chunk_size, NULL, mtime, attrset, RGW_OBJ_CATEGORY_MAIN, 0, NULL, NULL, NULL, NULL);
|
return copy_obj_data(rctx, dest_bucket_info, read_op, end, obj, obj, max_chunk_size, NULL, mtime, attrset, RGW_OBJ_CATEGORY_MAIN, 0, 0, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
||||||
@ -3948,6 +3960,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
|||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs,
|
||||||
RGWObjCategory category,
|
RGWObjCategory category,
|
||||||
uint64_t olh_epoch,
|
uint64_t olh_epoch,
|
||||||
|
time_t delete_at,
|
||||||
string *version_id,
|
string *version_id,
|
||||||
string *ptag,
|
string *ptag,
|
||||||
string *petag,
|
string *petag,
|
||||||
@ -4047,7 +4060,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
|
|||||||
set_copy_attrs(src_attrs, attrs, attrs_mod);
|
set_copy_attrs(src_attrs, attrs, attrs_mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cb.complete(etag, mtime, set_mtime, attrs);
|
ret = cb.complete(etag, mtime, set_mtime, attrs, delete_at);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto set_err_state;
|
goto set_err_state;
|
||||||
}
|
}
|
||||||
@ -4128,6 +4141,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
|||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs,
|
||||||
RGWObjCategory category,
|
RGWObjCategory category,
|
||||||
uint64_t olh_epoch,
|
uint64_t olh_epoch,
|
||||||
|
time_t delete_at,
|
||||||
string *version_id,
|
string *version_id,
|
||||||
string *ptag,
|
string *ptag,
|
||||||
string *petag,
|
string *petag,
|
||||||
@ -4160,7 +4174,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
|||||||
return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone,
|
return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone,
|
||||||
dest_obj, src_obj, dest_bucket_info, src_bucket_info, src_mtime, mtime, mod_ptr,
|
dest_obj, src_obj, dest_bucket_info, src_bucket_info, src_mtime, mtime, mod_ptr,
|
||||||
unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category,
|
unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category,
|
||||||
olh_epoch, version_id, ptag, petag, err, progress_cb, progress_data);
|
olh_epoch, delete_at, version_id, ptag, petag, err, progress_cb, progress_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<string, bufferlist> src_attrs;
|
map<string, bufferlist> src_attrs;
|
||||||
@ -4238,7 +4252,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
|||||||
|
|
||||||
if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */
|
if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */
|
||||||
return copy_obj_data(obj_ctx, dest_bucket_info, read_op, end, dest_obj, src_obj,
|
return copy_obj_data(obj_ctx, dest_bucket_info, read_op, end, dest_obj, src_obj,
|
||||||
max_chunk_size, mtime, 0, attrs, category, olh_epoch,
|
max_chunk_size, mtime, 0, attrs, category, olh_epoch, delete_at,
|
||||||
version_id, ptag, petag, err);
|
version_id, ptag, petag, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4330,6 +4344,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
|
|||||||
write_op.meta.flags = PUT_OBJ_CREATE;
|
write_op.meta.flags = PUT_OBJ_CREATE;
|
||||||
write_op.meta.category = category;
|
write_op.meta.category = category;
|
||||||
write_op.meta.olh_epoch = olh_epoch;
|
write_op.meta.olh_epoch = olh_epoch;
|
||||||
|
write_op.meta.delete_at = delete_at;
|
||||||
|
|
||||||
ret = write_op.write_meta(end + 1, attrs);
|
ret = write_op.write_meta(end + 1, attrs);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -4373,6 +4388,7 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
|
|||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs,
|
||||||
RGWObjCategory category,
|
RGWObjCategory category,
|
||||||
uint64_t olh_epoch,
|
uint64_t olh_epoch,
|
||||||
|
time_t delete_at,
|
||||||
string *version_id,
|
string *version_id,
|
||||||
string *ptag,
|
string *ptag,
|
||||||
string *petag,
|
string *petag,
|
||||||
@ -4429,7 +4445,7 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = processor.complete(etag, mtime, set_mtime, attrs);
|
ret = processor.complete(etag, mtime, set_mtime, attrs, delete_at);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -5503,12 +5519,16 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
|
|||||||
|
|
||||||
if (name.compare(RGW_ATTR_DELETE_AT) == 0) {
|
if (name.compare(RGW_ATTR_DELETE_AT) == 0) {
|
||||||
utime_t ts;
|
utime_t ts;
|
||||||
::decode(ts, bl);
|
try {
|
||||||
|
::decode(ts, bl);
|
||||||
|
|
||||||
rgw_obj_key obj_key;
|
rgw_obj_key obj_key;
|
||||||
obj.get_index_key(&obj_key);
|
obj.get_index_key(&obj_key);
|
||||||
|
|
||||||
objexp_hint_add(ts, bucket.name, bucket.bucket_id, obj_key);
|
objexp_hint_add(ts, bucket.name, bucket.bucket_id, obj_key);
|
||||||
|
} catch (buffer::error& err) {
|
||||||
|
ldout(cct, 0) << "ERROR: failed to decode " RGW_ATTR_DELETE_AT << " attr" << dendl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1606,10 +1606,11 @@ public:
|
|||||||
const char *if_match;
|
const char *if_match;
|
||||||
const char *if_nomatch;
|
const char *if_nomatch;
|
||||||
uint64_t olh_epoch;
|
uint64_t olh_epoch;
|
||||||
|
time_t delete_at;
|
||||||
|
|
||||||
MetaParams() : mtime(NULL), rmattrs(NULL), data(NULL), manifest(NULL), ptag(NULL),
|
MetaParams() : mtime(NULL), rmattrs(NULL), data(NULL), manifest(NULL), ptag(NULL),
|
||||||
remove_objs(NULL), set_mtime(0), category(RGW_OBJ_CATEGORY_MAIN), flags(0),
|
remove_objs(NULL), set_mtime(0), category(RGW_OBJ_CATEGORY_MAIN), flags(0),
|
||||||
if_match(NULL), if_nomatch(NULL), olh_epoch(0) {}
|
if_match(NULL), if_nomatch(NULL), olh_epoch(0), delete_at(0) {}
|
||||||
} meta;
|
} meta;
|
||||||
|
|
||||||
Write(RGWRados::Object *_target) : target(_target) {}
|
Write(RGWRados::Object *_target) : target(_target) {}
|
||||||
@ -1808,6 +1809,7 @@ public:
|
|||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs,
|
||||||
RGWObjCategory category,
|
RGWObjCategory category,
|
||||||
uint64_t olh_epoch,
|
uint64_t olh_epoch,
|
||||||
|
time_t delete_at,
|
||||||
string *version_id,
|
string *version_id,
|
||||||
string *ptag,
|
string *ptag,
|
||||||
string *petag,
|
string *petag,
|
||||||
@ -1855,6 +1857,7 @@ public:
|
|||||||
map<std::string, bufferlist>& attrs,
|
map<std::string, bufferlist>& attrs,
|
||||||
RGWObjCategory category,
|
RGWObjCategory category,
|
||||||
uint64_t olh_epoch,
|
uint64_t olh_epoch,
|
||||||
|
time_t delete_at,
|
||||||
string *version_id,
|
string *version_id,
|
||||||
string *ptag,
|
string *ptag,
|
||||||
string *petag,
|
string *petag,
|
||||||
@ -1873,6 +1876,7 @@ public:
|
|||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs,
|
||||||
RGWObjCategory category,
|
RGWObjCategory category,
|
||||||
uint64_t olh_epoch,
|
uint64_t olh_epoch,
|
||||||
|
time_t delete_at,
|
||||||
string *version_id,
|
string *version_id,
|
||||||
string *ptag,
|
string *ptag,
|
||||||
string *petag,
|
string *petag,
|
||||||
@ -2377,7 +2381,7 @@ protected:
|
|||||||
RGWBucketInfo bucket_info;
|
RGWBucketInfo bucket_info;
|
||||||
|
|
||||||
virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match = NULL, const char *if_nomatch = NULL) = 0;
|
const char *if_match = NULL, const char *if_nomatch = NULL) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -2393,7 +2397,7 @@ public:
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
virtual int complete(string& etag, time_t *mtime, time_t set_mtime,
|
virtual int complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match = NULL, const char *if_nomatch = NULL);
|
const char *if_match = NULL, const char *if_nomatch = NULL);
|
||||||
|
|
||||||
CephContext *ctx();
|
CephContext *ctx();
|
||||||
@ -2464,7 +2468,7 @@ protected:
|
|||||||
|
|
||||||
int write_data(bufferlist& bl, off_t ofs, void **phandle, bool exclusive);
|
int write_data(bufferlist& bl, off_t ofs, void **phandle, bool exclusive);
|
||||||
virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime,
|
||||||
map<string, bufferlist>& attrs,
|
map<string, bufferlist>& attrs, time_t delete_at,
|
||||||
const char *if_match = NULL, const char *if_nomatch = NULL);
|
const char *if_match = NULL, const char *if_nomatch = NULL);
|
||||||
|
|
||||||
int prepare_next_part(off_t ofs);
|
int prepare_next_part(off_t ofs);
|
||||||
|
@ -481,6 +481,40 @@ void RGWDeleteBucket_ObjStore_SWIFT::send_response()
|
|||||||
rgw_flush_formatter_and_reset(s, s->formatter);
|
rgw_flush_formatter_and_reset(s, s->formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_delete_at_param(req_state *s, time_t *delete_at)
|
||||||
|
{
|
||||||
|
/* Handle Swift object expiration. */
|
||||||
|
utime_t delat_proposal;
|
||||||
|
string x_delete = s->info.env->get("HTTP_X_DELETE_AFTER", "");
|
||||||
|
|
||||||
|
if (x_delete.empty()) {
|
||||||
|
x_delete = s->info.env->get("HTTP_X_DELETE_AT", "");
|
||||||
|
} else {
|
||||||
|
/* X-Delete-After HTTP is present. It means we need add its value
|
||||||
|
* to the current time. */
|
||||||
|
delat_proposal = ceph_clock_now(g_ceph_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x_delete.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
string err;
|
||||||
|
long ts = strict_strtoll(x_delete.c_str(), 10, &err);
|
||||||
|
|
||||||
|
if (!err.empty()) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delat_proposal += utime_t(ts, 0);
|
||||||
|
if (delat_proposal < ceph_clock_now(g_ceph_context)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*delete_at = delat_proposal.sec();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int RGWPutObj_ObjStore_SWIFT::get_params()
|
int RGWPutObj_ObjStore_SWIFT::get_params()
|
||||||
{
|
{
|
||||||
if (s->has_bad_meta)
|
if (s->has_bad_meta)
|
||||||
@ -515,6 +549,12 @@ int RGWPutObj_ObjStore_SWIFT::get_params()
|
|||||||
|
|
||||||
obj_manifest = s->info.env->get("HTTP_X_OBJECT_MANIFEST");
|
obj_manifest = s->info.env->get("HTTP_X_OBJECT_MANIFEST");
|
||||||
|
|
||||||
|
int r = get_delete_at_param(s, &delete_at);
|
||||||
|
if (r < 0) {
|
||||||
|
ldout(s->cct, 5) << "ERROR: failed to get Delete-At param" << dendl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return RGWPutObj_ObjStore::get_params();
|
return RGWPutObj_ObjStore::get_params();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,31 +661,10 @@ int RGWPutMetadataObject_ObjStore_SWIFT::get_params()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle Swift object expiration. */
|
/* Handle Swift object expiration. */
|
||||||
utime_t delat_proposal;
|
int r = get_delete_at_param(s, &delete_at);
|
||||||
string x_delete = s->info.env->get("HTTP_X_DELETE_AFTER", "");
|
if (r < 0) {
|
||||||
|
ldout(s->cct, 5) << "ERROR: failed to get Delete-At param" << dendl;
|
||||||
if (x_delete.empty()) {
|
return r;
|
||||||
x_delete = s->info.env->get("HTTP_X_DELETE_AT", "");
|
|
||||||
} else {
|
|
||||||
/* X-Delete-After HTTP is present. It means we need add its value
|
|
||||||
* to the current time. */
|
|
||||||
delat_proposal = ceph_clock_now(g_ceph_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x_delete.empty()) {
|
|
||||||
string err;
|
|
||||||
long ts = strict_strtoll(x_delete.c_str(), 10, &err);
|
|
||||||
|
|
||||||
if (!err.empty()) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
delat_proposal += utime_t(ts, 0);
|
|
||||||
if (delat_proposal < ceph_clock_now(g_ceph_context)) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_at = delat_proposal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", "");
|
placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", "");
|
||||||
@ -750,6 +769,12 @@ int RGWCopyObj_ObjStore_SWIFT::get_params()
|
|||||||
attrs_mod = RGWRados::ATTRSMOD_MERGE;
|
attrs_mod = RGWRados::ATTRSMOD_MERGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int r = get_delete_at_param(s, &delete_at);
|
||||||
|
if (r < 0) {
|
||||||
|
ldout(s->cct, 5) << "ERROR: failed to get Delete-At param" << dendl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user