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: v18.2.8~10^2~224^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f7b390c324f89633c4342cc0494fe87bf8f77a6f;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) Conflicts: src/rgw/rgw_op.cc put_info() doesn't take optional_yield --- diff --git a/PendingReleaseNotes b/PendingReleaseNotes index 82755aceeed..fc5292aad06 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -4,6 +4,8 @@ * RBD: The ``try-netlink`` mapping option for rbd-nbd has become the default and is now deprecated. If the NBD netlink interface is not supported by the kernel, then the mapping is retried using the legacy ioctl interface. +* 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. >=18.2.4 -------- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 09f15979629..54de4256cde 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -8381,8 +8381,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; @@ -8424,6 +8425,17 @@ void RGWPutBucketObjectLock::execute(optional_yield y) } op_ret = retry_raced_bucket_write(this, s->bucket.get(), [this] { + 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()); return op_ret;