From: Casey Bodley Date: Thu, 20 Feb 2025 19:42:37 +0000 (-0500) Subject: rgw: PutObjectLockConfiguration can enable object lock on existing buckets X-Git-Tag: v19.2.3~284^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3a5750d20c7e92c2ec7667840e8a136e5ac890dd;p=ceph.git rgw: PutObjectLockConfiguration can enable object lock on existing buckets AWS now allows PutObjectLockConfiguration on existing buckets, even if x-amz-bucket-object-lock-enabled was not specified on bucket creation object lock still requires the bucket to be versioning-enabled, so such requests are rejected otherwise. if the bucket is versioning-enabled but not object-lock-enabled, enable the BUCKET_OBJ_LOCK_ENABLED flag this logic was moved into retry_raced_bucket_write() in case the request races with PutBucketVersioning Fixes: https://tracker.ceph.com/issues/70013 Signed-off-by: Casey Bodley (cherry picked from commit b454668983fe45687f9f77c75628a4d641dd545b) --- diff --git a/PendingReleaseNotes b/PendingReleaseNotes index 66bf643cd5f..7fbc4988c50 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -48,6 +48,11 @@ CephFS does not support disk space reservation. The only flags supported are `FALLOC_FL_KEEP_SIZE` and `FALLOC_FL_PUNCH_HOLE`. +>=19.2.2 + +* RGW: PutObjectLockConfiguration can now be used to enable S3 Object Lock on an + existing versioning-enabled bucket that was not created with Object Lock enabled. + >=19.0.0 * RGW: GetObject and HeadObject requests now return a x-rgw-replicated-at diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 414e1196691..0271da7c813 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -8046,8 +8046,9 @@ int RGWPutBucketObjectLock::verify_permission(optional_yield y) void RGWPutBucketObjectLock::execute(optional_yield y) { - if (!s->bucket->get_info().obj_lock_enabled()) { - s->err.message = "object lock configuration can't be set if bucket object lock not enabled"; + if (!s->bucket->get_info().versioning_enabled()) { + s->err.message = "Object lock cannot be enabled unless the " + "bucket has versioning enabled"; ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_BUCKET_STATE; return; @@ -8090,6 +8091,17 @@ void RGWPutBucketObjectLock::execute(optional_yield y) } op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this, y] { + if (!s->bucket->get_info().obj_lock_enabled()) { + // automatically enable object lock if the bucket is versioning-enabled + if (!s->bucket->get_info().versioning_enabled()) { + s->err.message = "Object lock cannot be enabled unless the " + "bucket has versioning enabled"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; + return -ERR_INVALID_BUCKET_STATE; + } + s->bucket->get_info().flags |= BUCKET_OBJ_LOCK_ENABLED; + } + s->bucket->get_info().obj_lock = obj_lock; op_ret = s->bucket->put_info(this, false, real_time(), y); return op_ret;