RGWObjStateManifest* sm = nullptr;
int r = get_obj_state(dpp, rctx, bucket_info, obj, &sm,
follow_olh, y, assume_noent);
- if (r < 0) {
- return r;
- }
if (pstate) {
*pstate = &sm->state;
}
+ if (r < 0) {
+ return r;
+ }
if (pmanifest) {
if (sm->manifest) {
*pmanifest = &(*sm->manifest);
}
if (olh.removed) {
+ /* the object is a delete marker */
+ state->is_dm = true;
return -ENOENT;
}
int ret = store->getRados()->get_obj_state(dpp, rados_ctx, bucket->get_info(), get_obj(), &pstate, &manifest, follow_olh, y);
if (ret < 0) {
+ if (ret == -ENOENT) {
+ state.is_dm = pstate->is_dm;
+ }
return ret;
}
return -EINVAL;
}
- return do_read_permissions(op_obj, only_bucket, y);
+ auto ret = do_read_permissions(op_obj, only_bucket, y);
+ switch (s->op) {
+ case OP_HEAD:
+ case OP_GET:
+ if (ret == -ENOENT /* note, access already accounted for */) [[unlikely]] {
+ (void) s->object->load_obj_state(s, s->yield, true /* follow_olh */);
+ auto tf = s->object->is_delete_marker() ? "true" : "false";
+ dump_header(s, "x-amz-delete-marker", tf);
+ }
+ default:
+ break;
+ }
+
+ return ret;
}
void RGWRESTMgr::register_resource(string resource, RGWRESTMgr *mgr)
virtual void set_compressed() = 0;
/** Check if this object is compressed */
virtual bool is_compressed() = 0;
+ /** True if this object is a delete marker (newest version is deleted) */
+ virtual bool is_delete_marker() = 0;
/** Check if object is synced */
virtual bool is_sync_completed(const DoutPrefixProvider* dpp,
optional_yield y,
virtual void set_hash_source(std::string s) = 0;
/** Build an Object Identifier string for this object */
virtual std::string get_oid(void) const = 0;
- /** True if this object is a delete marker (newest version is deleted) */
- virtual bool get_delete_marker(void) = 0;
/** True if this object is stored in the extra data pool */
virtual bool get_in_extra_data(void) = 0;
/** True if this object exists in the store */
virtual bool is_prefetch_data() override { return next->is_prefetch_data(); }
virtual void set_compressed() override { return next->set_compressed(); }
virtual bool is_compressed() override { return next->is_compressed(); }
+ virtual bool is_delete_marker() override { return next->is_delete_marker(); }
bool is_sync_completed(const DoutPrefixProvider* dpp, optional_yield y,
const ceph::real_time& obj_mtime) override {
return next->is_sync_completed(dpp, y, obj_mtime);
virtual std::string get_hash_source(void) override { return next->get_hash_source(); };
virtual void set_hash_source(std::string s) override { return next->set_hash_source(s); };
virtual std::string get_oid(void) const override { return next->get_oid(); };
- virtual bool get_delete_marker(void) override { return next->get_delete_marker(); };
virtual bool get_in_extra_data(void) override { return next->get_in_extra_data(); };
virtual bool exists(void) override { return next->exists(); };
virtual void set_in_extra_data(bool i) override { return next->set_in_extra_data(i); };
bool is_atomic{false};
bool has_attrs{false};
bool exists{false};
+ bool is_dm{false};
uint64_t size{0}; //< size of raw object
uint64_t accounted_size{0}; //< size before compression, encryption
ceph::real_time mtime;
protected:
RGWObjState state;
Bucket* bucket = nullptr;
- bool delete_marker{false};
jspan_context trace_ctx{false, false};
public:
virtual bool is_prefetch_data() override { return state.prefetch_data; }
virtual void set_compressed() override { state.compressed = true; }
virtual bool is_compressed() override { return state.compressed; }
+ virtual bool is_delete_marker() override { return state.is_dm; }
virtual void invalidate() override {
rgw_obj obj = state.obj;
bool is_atomic = state.is_atomic;
virtual std::string get_hash_source(void) override { return state.obj.index_hash_source; }
virtual void set_hash_source(std::string s) override { state.obj.index_hash_source = s; }
virtual std::string get_oid(void) const override { return state.obj.key.get_oid(); }
- virtual bool get_delete_marker(void) override { return delete_marker; }
virtual bool get_in_extra_data(void) override { return state.obj.is_in_extra_data(); }
virtual bool exists(void) override { return state.exists; }
virtual void set_in_extra_data(bool i) override { state.obj.set_in_extra_data(i); }