Skip to content

Commit c076eca

Browse files
authored
Merge pull request ceph#54957 from jzhu116-bloomberg/wip-63799
rgw: revert PR ceph#41897 to allow multiple delete markers to be created Reviewed-by: Casey Bodley <[email protected]>
2 parents 6b42c07 + 84e2f2f commit c076eca

File tree

3 files changed

+51
-31
lines changed

3 files changed

+51
-31
lines changed

qa/workunits/rgw/test_rgw_versioning.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,21 @@ def main():
5858
assert 'DeleteMarker' in resp, 'DeleteMarker key not present in response'
5959
assert resp['DeleteMarker'], 'DeleteMarker value not True in response'
6060
assert 'VersionId' in resp, 'VersionId key not present in response'
61-
version_id = resp['VersionId']
62-
bucket.Object(key).delete()
63-
connection.ObjectVersion(bucket.name, key, version_id).delete()
61+
version_id_1 = resp['VersionId']
62+
63+
resp = bucket.Object(key).delete()
64+
assert 'DeleteMarker' in resp, 'DeleteMarker key not present in response'
65+
assert resp['DeleteMarker'], 'DeleteMarker value not True in response'
66+
assert 'VersionId' in resp, 'VersionId key not present in response'
67+
version_id_2 = resp['VersionId']
68+
69+
connection.ObjectVersion(bucket.name, key, version_id_2).delete()
70+
# bucket index should only include entries for an object version
71+
out = exec_cmd(f'radosgw-admin bi list --bucket {BUCKET_NAME}')
72+
json_out = json.loads(out.replace(b'\x80', b'0x80'))
73+
assert len(json_out) == 4, 'bucket index did not only include entries for an object version'
74+
75+
connection.ObjectVersion(bucket.name, key, version_id_1).delete()
6476
# bucket index should now be empty
6577
out = exec_cmd(f'radosgw-admin bi list --bucket {BUCKET_NAME}')
6678
json_out = json.loads(out.replace(b'\x80', b'0x80'))

src/cls/rgw/cls_rgw.cc

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,28 +1811,6 @@ static int rgw_bucket_link_olh(cls_method_context_t hctx, bufferlist *in, buffer
18111811
return ret;
18121812
}
18131813

1814-
BIOLHEntry olh(hctx, op.key);
1815-
bool olh_read_attempt = false;
1816-
bool olh_found = false;
1817-
if (!existed && op.delete_marker) {
1818-
/* read olh */
1819-
ret = olh.init(&olh_found);
1820-
if (ret < 0) {
1821-
return ret;
1822-
}
1823-
olh_read_attempt = true;
1824-
1825-
// if we're deleting (i.e., adding a delete marker, and the OLH
1826-
// indicates it already refers to a delete marker, error out)
1827-
if (olh_found && olh.get_entry().delete_marker) {
1828-
CLS_LOG(10,
1829-
"%s: delete marker received for \"%s\" although OLH"
1830-
" already refers to a delete marker",
1831-
__func__, escape_str(op.key.to_string()).c_str());
1832-
return -ENOENT;
1833-
}
1834-
}
1835-
18361814
if (existed && !real_clock::is_zero(op.unmod_since)) {
18371815
timespec mtime = ceph::real_clock::to_timespec(obj.mtime());
18381816
timespec unmod = ceph::real_clock::to_timespec(op.unmod_since);
@@ -1885,12 +1863,11 @@ static int rgw_bucket_link_olh(cls_method_context_t hctx, bufferlist *in, buffer
18851863
}
18861864

18871865
/* read olh */
1888-
if (!olh_read_attempt) { // only read if we didn't attempt earlier
1889-
ret = olh.init(&olh_found);
1890-
if (ret < 0) {
1891-
return ret;
1892-
}
1893-
olh_read_attempt = true;
1866+
BIOLHEntry olh(hctx, op.key);
1867+
bool olh_found = false;
1868+
ret = olh.init(&olh_found);
1869+
if (ret < 0) {
1870+
return ret;
18941871
}
18951872

18961873
const uint64_t prev_epoch = olh.get_epoch();

src/test/rgw/rgw_multi/tests.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,8 @@ def test_delete_marker_full_sync():
11021102
# create a delete marker
11031103
key2 = new_key(zone, bucket, 'obj')
11041104
key2.delete()
1105+
key2.delete()
1106+
key2.delete()
11051107

11061108
# wait for full sync
11071109
for _, bucket in zone_bucket:
@@ -1126,11 +1128,40 @@ def test_suspended_delete_marker_full_sync():
11261128
# create a delete marker
11271129
key2 = new_key(zone, bucket, 'obj')
11281130
key2.delete()
1131+
key2.delete()
1132+
key2.delete()
11291133

11301134
# wait for full sync
11311135
for _, bucket in zone_bucket:
11321136
zonegroup_bucket_checkpoint(zonegroup_conns, bucket.name)
11331137

1138+
def test_concurrent_delete_markers_incremental_sync():
1139+
zonegroup = realm.master_zonegroup()
1140+
zonegroup_conns = ZonegroupConns(zonegroup)
1141+
zone = zonegroup_conns.rw_zones[0]
1142+
1143+
# create a versioned bucket
1144+
bucket = zone.create_bucket(gen_bucket_name())
1145+
log.debug('created bucket=%s', bucket.name)
1146+
bucket.configure_versioning(True)
1147+
1148+
zonegroup_meta_checkpoint(zonegroup)
1149+
1150+
obj = 'obj'
1151+
1152+
# upload a dummy object and wait for sync. this forces each zone to finish
1153+
# a full sync and switch to incremental
1154+
new_key(zone, bucket, obj).set_contents_from_string('')
1155+
zonegroup_bucket_checkpoint(zonegroup_conns, bucket.name)
1156+
1157+
# create several concurrent delete markers on each zone and let them race to sync
1158+
for i in range(2):
1159+
for zone_conn in zonegroup_conns.rw_zones:
1160+
key = new_key(zone_conn, bucket, obj)
1161+
key.delete()
1162+
1163+
zonegroup_bucket_checkpoint(zonegroup_conns, bucket.name)
1164+
11341165
def test_bucket_versioning():
11351166
buckets, zone_bucket = create_bucket_per_zone_in_realm()
11361167
for _, bucket in zone_bucket:

0 commit comments

Comments
 (0)