return 0;
}
+ time_t mtime() {
+ return instance_entry.meta.mtime;
+ }
};
return ret;
}
+ if (existed && op.unmod_since > 0) {
+ if (obj.mtime() >= op.unmod_since) {
+ return 0; /* no need to set error, we just return 0 and avoid writing to the bi log */
+ }
+ }
+
bool removing;
/*
int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, bufferlist& olh_tag,
bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
- uint64_t olh_epoch, bool log_op)
+ uint64_t olh_epoch, time_t unmod_since, bool log_op)
{
bufferlist in, out;
struct rgw_cls_link_olh_op call;
}
call.olh_epoch = olh_epoch;
call.log_op = log_op;
+ call.unmod_since = unmod_since;
::encode(call, in);
int r = io_ctx.exec(oid, "rgw", "bucket_link_olh", in, out);
if (r < 0)
int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, bufferlist& olh_tag,
bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
- uint64_t olh_epoch, bool log_op);
+ uint64_t olh_epoch, time_t unmod_since, bool log_op);
int cls_rgw_bucket_unlink_instance(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, const string& op_tag,
uint64_t olh_epoch, bool log_op);
int cls_rgw_get_olh_log(librados::IoCtx& io_ctx, string& oid, librados::ObjectReadOperation& op, const cls_rgw_obj_key& olh, uint64_t ver_marker,
::encode_json("olh_epoch", olh_epoch, f);
::encode_json("log_op", log_op, f);
::encode_json("bilog_flags", (uint32_t)bilog_flags, f);
+ ::encode_json("unmod_since", unmod_since, f);
}
void rgw_cls_unlink_instance_op::generate_test_instances(list<rgw_cls_unlink_instance_op*>& o)
uint64_t olh_epoch;
bool log_op;
uint16_t bilog_flags;
+ time_t unmod_since; /* only create delete marker if newer then this */
rgw_cls_link_olh_op() : delete_marker(false), olh_epoch(0), log_op(false), bilog_flags(0) {}
void encode(bufferlist& bl) const {
- ENCODE_START(1, 1, bl);
+ ENCODE_START(2, 1, bl);
::encode(key, bl);
::encode(olh_tag, bl);
::encode(delete_marker, bl);
::encode(olh_epoch, bl);
::encode(log_op, bl);
::encode(bilog_flags, bl);
+ ::encode(unmod_since, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator& bl) {
- DECODE_START(1, bl);
+ DECODE_START(2, bl);
::decode(key, bl);
::decode(olh_tag, bl);
::decode(delete_marker, bl);
::decode(olh_epoch, bl);
::decode(log_op, bl);
::decode(bilog_flags, bl);
+ if (struct_v >= 2) {
+ ::decode(unmod_since, bl);
+ }
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
static void generate_test_instances(list<rgw_bi_log_entry*>& o);
+
+ bool is_versioned() {
+ return ((bilog_flags & RGW_BILOG_FLAG_VERSIONED_OP) != 0);
+ }
};
WRITE_CLASS_ENCODER(rgw_bi_log_entry)
if (del_if_older) {
del_op.params.unmod_since = timestamp;
}
+ if (versioned) {
+ del_op.params.versioning_status = BUCKET_VERSIONED;
+ }
del_op.params.olh_epoch = versioned_epoch;
del_op.params.marker_version_id = marker_version_id;
del_op.params.obj_owner.set_id(owner);
del_op.params.obj_owner.set_name(owner_display_name);
+ del_op.params.mtime = timestamp;
ret = del_op.delete_obj();
if (ret < 0) {
rgw_obj_key key;
string owner;
string owner_display_name;
+ bool versioned;
uint64_t versioned_epoch;
string marker_version_id;
const rgw_obj_key& _key,
const string& _owner,
const string& _owner_display_name,
+ bool _versioned,
uint64_t _versioned_epoch,
bool _delete_marker,
bool _if_older,
key(_key),
owner(_owner),
owner_display_name(_owner_display_name),
+ versioned(_versioned),
versioned_epoch(_versioned_epoch),
del_if_older(_if_older),
timestamp(_timestamp) {
RGWBucketInfo bucket_info;
rgw_obj_key key;
+ bool versioned;
uint64_t versioned_epoch;
bool delete_marker;
string owner;
const string& _source_zone,
RGWBucketInfo& _bucket_info,
const rgw_obj_key& _key,
+ bool _versioned,
uint64_t _versioned_epoch,
string *_owner,
string *_owner_display_name,
source_zone(_source_zone),
bucket_info(_bucket_info),
key(_key),
+ versioned(_versioned),
versioned_epoch(_versioned_epoch),
delete_marker(_delete_marker) {
del_if_older = (_timestamp != NULL);
int send_request() {
req = new RGWAsyncRemoveObj(stack->create_completion_notifier(), store, source_zone, bucket_info,
- key, owner, owner_display_name, versioned_epoch,
+ key, owner, owner_display_name, versioned, versioned_epoch,
delete_marker, del_if_older, timestamp);
async_rados->queue(req);
return 0;
int shard_id;
rgw_obj_key key;
+ bool versioned;
uint64_t versioned_epoch;
bucket_entry_owner owner;
utime_t timestamp;
public:
RGWBucketSyncSingleEntryCR(RGWRados *_store, RGWAsyncRadosProcessor *_async_rados,
const string& _source_zone, RGWBucketInfo *_bucket_info, int _shard_id,
- const rgw_obj_key& _key, uint64_t _versioned_epoch,
+ const rgw_obj_key& _key, bool _versioned, uint64_t _versioned_epoch,
utime_t& _timestamp,
const bucket_entry_owner& _owner,
RGWModifyOp _op, RGWPendingState _op_state,
async_rados(_async_rados),
source_zone(_source_zone),
bucket_info(_bucket_info), shard_id(_shard_id),
- key(_key), versioned_epoch(_versioned_epoch),
+ key(_key), versioned(_versioned), versioned_epoch(_versioned_epoch),
owner(_owner),
timestamp(_timestamp), op(_op),
op_state(_op_state),
true));
} else if (op == CLS_RGW_OP_DEL) {
set_status("removing obj");
- call(new RGWRemoveObjCR(async_rados, store, source_zone, *bucket_info, key, versioned_epoch, NULL, NULL, false, ×tamp));
+ call(new RGWRemoveObjCR(async_rados, store, source_zone, *bucket_info, key, versioned, versioned_epoch, NULL, NULL, false, ×tamp));
} else if (op == CLS_RGW_OP_LINK_OLH_DM) {
set_status("creating delete marker");
ldout(store->ctx(), 10) << "creating delete marker: obj: " << source_zone << "/" << bucket_info->bucket << "/" << key << "[" << versioned_epoch << "]" << dendl;
- call(new RGWRemoveObjCR(async_rados, store, source_zone, *bucket_info, key, versioned_epoch, &owner.id, &owner.display_name, true, ×tamp));
+ call(new RGWRemoveObjCR(async_rados, store, source_zone, *bucket_info, key, versioned, versioned_epoch, &owner.id, &owner.display_name, true, ×tamp));
}
}
} while (marker_tracker->need_retry(key));
yield {
spawn(new RGWBucketSyncSingleEntryCR<rgw_obj_key, rgw_obj_key>(store, async_rados, source_zone, bucket_info, shard_id,
- entry->key, entry->versioned_epoch, entry->mtime,
+ entry->key,
+ false, /* versioned, only matters for object removal */
+ entry->versioned_epoch, entry->mtime,
entry->owner, op, CLS_RGW_STATE_COMPLETE, entry->key, marker_tracker), false);
}
}
versioned_epoch = entry->ver.epoch;
}
spawn(new RGWBucketSyncSingleEntryCR<string, rgw_obj_key>(store, async_rados, source_zone, bucket_info, shard_id,
- key, versioned_epoch, entry->timestamp, owner, entry->op,
+ key, entry->is_versioned(), versioned_epoch, entry->timestamp, owner, entry->op,
entry->state, entry->id, marker_tracker), false);
}
// }
state = NULL;
if (versioned_op) {
- r = store->set_olh(target->get_ctx(), target->get_bucket_info(), obj, false, NULL, meta.olh_epoch);
+ r = store->set_olh(target->get_ctx(), target->get_bucket_info(), obj, false, NULL, meta.olh_epoch, 0);
if (r < 0) {
return r;
}
meta.owner = params.obj_owner.get_id().to_str();
meta.owner_display_name = params.obj_owner.get_display_name();
- meta.mtime = ceph_clock_now(store->ctx());
- int r = store->set_olh(target->get_ctx(), target->get_bucket_info(), marker, true, &meta, params.olh_epoch);
+ if (params.mtime == 0) {
+ meta.mtime = ceph_clock_now(store->ctx());
+ } else {
+ meta.mtime = utime_t(params.mtime, 0);
+ }
+
+ int r = store->set_olh(target->get_ctx(), target->get_bucket_info(), marker, true, &meta, params.olh_epoch, params.unmod_since);
if (r < 0) {
return r;
}
int RGWRados::bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instance, bool delete_marker,
const string& op_tag,
struct rgw_bucket_dir_entry_meta *meta,
- uint64_t olh_epoch)
+ uint64_t olh_epoch,
+ time_t unmod_since)
{
rgw_rados_ref ref;
rgw_bucket bucket;
cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance());
ret = cls_rgw_bucket_link_olh(bs.index_ctx, bs.bucket_obj, key, olh_state.olh_tag, delete_marker, op_tag, meta, olh_epoch,
+ unmod_since,
get_zone().log_data);
if (ret < 0) {
return ret;
}
int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta,
- uint64_t olh_epoch)
+ uint64_t olh_epoch, time_t unmod_since)
{
string op_tag;
}
return ret;
}
- ret = bucket_index_link_olh(*state, target_obj, delete_marker, op_tag, meta, olh_epoch);
+ ret = bucket_index_link_olh(*state, target_obj, delete_marker, op_tag, meta, olh_epoch, unmod_since);
if (ret < 0) {
ldout(cct, 20) << "bucket_index_link_olh() target_obj=" << target_obj << " delete_marker=" << (int)delete_marker << " returned " << ret << dendl;
if (ret == -ECANCELED) {
list<rgw_obj_key> *remove_objs;
utime_t expiration_time;
time_t unmod_since;
+ time_t mtime; /* for setting delete marker mtime */
- DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL), unmod_since(0) {}
+ DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL), unmod_since(0), mtime(0) {}
} params;
struct DeleteResult {
int olh_init_modification_impl(RGWObjState& state, rgw_obj& olh_obj, string *op_tag);
int bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instance, bool delete_marker,
const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
- uint64_t olh_epoch);
+ uint64_t olh_epoch,
+ time_t unmod_since);
int bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, uint64_t olh_epoch);
int bucket_index_read_olh_log(RGWObjState& state, rgw_obj& obj_instance, uint64_t ver_marker,
map<uint64_t, vector<rgw_bucket_olh_log_entry> > *log, bool *is_truncated);
uint64_t *plast_ver);
int update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInfo& bucket_info, rgw_obj& obj);
int set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta,
- uint64_t olh_epoch);
+ uint64_t olh_epoch, time_t unmod_since);
int unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj& target_obj,
uint64_t olh_epoch);