Skip to content

Commit 8654b1f

Browse files
committed
rgw: hook up delete-marker detection
Introduces is_delete_marker() getter in rgw::sal::Object interface, and implements it for rgw/sal/rados (and filter), replacing unimplemented Object::get_delete_marker(). (Looked into rgw/sal/posix, but delete marker handling seems not working as expected there, so deferring for now.) Next, the new interface is used in GET/HEAD request paths to return a correct AWS-specified x-amz-delete-marker header when required, c.f. https://docs.aws.amazon.com/AmazonS3/latest/userguide/DeleteMarker.html. Signed-off-by: Matt Benjamin <[email protected]>
1 parent 2248211 commit 8654b1f

File tree

6 files changed

+27
-9
lines changed

6 files changed

+27
-9
lines changed

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6863,12 +6863,12 @@ int RGWRados::get_obj_state(const DoutPrefixProvider *dpp, RGWObjectCtx *rctx,
68636863
RGWObjStateManifest* sm = nullptr;
68646864
int r = get_obj_state(dpp, rctx, bucket_info, obj, &sm,
68656865
follow_olh, y, assume_noent);
6866-
if (r < 0) {
6867-
return r;
6868-
}
68696866
if (pstate) {
68706867
*pstate = &sm->state;
68716868
}
6869+
if (r < 0) {
6870+
return r;
6871+
}
68726872
if (pmanifest) {
68736873
if (sm->manifest) {
68746874
*pmanifest = &(*sm->manifest);
@@ -9474,6 +9474,8 @@ int RGWRados::follow_olh(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_in
94749474
}
94759475

94769476
if (olh.removed) {
9477+
/* the object is a delete marker */
9478+
state->is_dm = true;
94779479
return -ENOENT;
94789480
}
94799481

src/rgw/driver/rados/rgw_sal_rados.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,6 +2773,9 @@ int RadosObject::load_obj_state(const DoutPrefixProvider* dpp, optional_yield y,
27732773

27742774
int ret = store->getRados()->get_obj_state(dpp, rados_ctx, bucket->get_info(), get_obj(), &pstate, &manifest, follow_olh, y);
27752775
if (ret < 0) {
2776+
if (ret == -ENOENT) {
2777+
state.is_dm = pstate->is_dm;
2778+
}
27762779
return ret;
27772780
}
27782781

src/rgw/rgw_rest.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1931,7 +1931,20 @@ int RGWHandler_REST::read_permissions(RGWOp* op_obj, optional_yield y)
19311931
return -EINVAL;
19321932
}
19331933

1934-
return do_read_permissions(op_obj, only_bucket, y);
1934+
auto ret = do_read_permissions(op_obj, only_bucket, y);
1935+
switch (s->op) {
1936+
case OP_HEAD:
1937+
case OP_GET:
1938+
if (ret == -ENOENT /* note, access already accounted for */) [[unlikely]] {
1939+
(void) s->object->load_obj_state(s, s->yield, true /* follow_olh */);
1940+
auto tf = s->object->is_delete_marker() ? "true" : "false";
1941+
dump_header(s, "x-amz-delete-marker", tf);
1942+
}
1943+
default:
1944+
break;
1945+
}
1946+
1947+
return ret;
19351948
}
19361949

19371950
void RGWRESTMgr::register_resource(string resource, RGWRESTMgr *mgr)

src/rgw/rgw_sal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,8 @@ class Object {
12141214
virtual void set_compressed() = 0;
12151215
/** Check if this object is compressed */
12161216
virtual bool is_compressed() = 0;
1217+
/** True if this object is a delete marker (newest version is deleted) */
1218+
virtual bool is_delete_marker() = 0;
12171219
/** Check if object is synced */
12181220
virtual bool is_sync_completed(const DoutPrefixProvider* dpp,
12191221
optional_yield y,
@@ -1339,8 +1341,6 @@ class Object {
13391341
virtual void set_hash_source(std::string s) = 0;
13401342
/** Build an Object Identifier string for this object */
13411343
virtual std::string get_oid(void) const = 0;
1342-
/** True if this object is a delete marker (newest version is deleted) */
1343-
virtual bool get_delete_marker(void) = 0;
13441344
/** True if this object is stored in the extra data pool */
13451345
virtual bool get_in_extra_data(void) = 0;
13461346
/** True if this object exists in the store */

src/rgw/rgw_sal_filter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ class FilterObject : public Object {
787787
virtual bool is_prefetch_data() override { return next->is_prefetch_data(); }
788788
virtual void set_compressed() override { return next->set_compressed(); }
789789
virtual bool is_compressed() override { return next->is_compressed(); }
790+
virtual bool is_delete_marker() override { return next->is_delete_marker(); }
790791
bool is_sync_completed(const DoutPrefixProvider* dpp, optional_yield y,
791792
const ceph::real_time& obj_mtime) override {
792793
return next->is_sync_completed(dpp, y, obj_mtime);
@@ -865,7 +866,6 @@ class FilterObject : public Object {
865866
virtual std::string get_hash_source(void) override { return next->get_hash_source(); };
866867
virtual void set_hash_source(std::string s) override { return next->set_hash_source(s); };
867868
virtual std::string get_oid(void) const override { return next->get_oid(); };
868-
virtual bool get_delete_marker(void) override { return next->get_delete_marker(); };
869869
virtual bool get_in_extra_data(void) override { return next->get_in_extra_data(); };
870870
virtual bool exists(void) override { return next->exists(); };
871871
virtual void set_in_extra_data(bool i) override { return next->set_in_extra_data(i); };

src/rgw/rgw_sal_store.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ struct RGWObjState {
2525
bool is_atomic{false};
2626
bool has_attrs{false};
2727
bool exists{false};
28+
bool is_dm{false};
2829
uint64_t size{0}; //< size of raw object
2930
uint64_t accounted_size{0}; //< size before compression, encryption
3031
ceph::real_time mtime;
@@ -279,7 +280,6 @@ class StoreObject : public Object {
279280
protected:
280281
RGWObjState state;
281282
Bucket* bucket = nullptr;
282-
bool delete_marker{false};
283283
jspan_context trace_ctx{false, false};
284284

285285
public:
@@ -299,6 +299,7 @@ class StoreObject : public Object {
299299
virtual bool is_prefetch_data() override { return state.prefetch_data; }
300300
virtual void set_compressed() override { state.compressed = true; }
301301
virtual bool is_compressed() override { return state.compressed; }
302+
virtual bool is_delete_marker() override { return state.is_dm; }
302303
virtual void invalidate() override {
303304
rgw_obj obj = state.obj;
304305
bool is_atomic = state.is_atomic;
@@ -342,7 +343,6 @@ class StoreObject : public Object {
342343
virtual std::string get_hash_source(void) override { return state.obj.index_hash_source; }
343344
virtual void set_hash_source(std::string s) override { state.obj.index_hash_source = s; }
344345
virtual std::string get_oid(void) const override { return state.obj.key.get_oid(); }
345-
virtual bool get_delete_marker(void) override { return delete_marker; }
346346
virtual bool get_in_extra_data(void) override { return state.obj.is_in_extra_data(); }
347347
virtual bool exists(void) override { return state.exists; }
348348
virtual void set_in_extra_data(bool i) override { state.obj.set_in_extra_data(i); }

0 commit comments

Comments
 (0)