https://github.com/ceph/ceph/pull/72589

From e7dc985976c1226749f7f969b0db5c8a75b61cd6 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max.kellermann@ionos.com>
Date: Mon, 12 Oct 2026 13:50:47 +0200
Subject: [PATCH] rgw: cast time spans to ceph::timespan before adding

Adding std::chrono::seconds to a ceph::coarse_real_time yields a
time_point whose `rep` is common_type<uint64_t, seconds::rep>.  With
libc++, seconds::rep is `long long`, so the result's `rep` is
`unsigned long long` instead of `unsigned long`, the result is no
longer a ceph::coarse_real_time, and ceph's operator<<(ostream&,
time_point) doesn't match.  This breaks the build with clang/libc++.

Converting the duration to ceph::timespan before adding keeps the
result type unchanged.

Signed-off-by: Max Kellermann <max.kellermann@ionos.com>

diff --git a/src/rgw/driver/rados/rgw_reshard.cc b/src/rgw/driver/rados/rgw_reshard.cc
index 987604cfd09..8ab48fa5053 100644
--- a/src/rgw/driver/rados/rgw_reshard.cc
+++ b/src/rgw/driver/rados/rgw_reshard.cc
@@ -1735,7 +1735,7 @@ int RGWReshard::process_entry(const cls_rgw_reshard_entry& entry,
       reshard_reduction_wait_hours = reshard_reduction_wait_hours * debug_interval / secs_per_day;
     }
 
-    auto timespan = std::chrono::seconds(int(60 * 60 * reshard_reduction_wait_hours));
+    const ceph::timespan timespan = std::chrono::seconds(int(60 * 60 * reshard_reduction_wait_hours));
     if (now < when_queued + timespan) {
       // too early to reshard; log and skip
       ldpp_dout(dpp, 20) <<  __func__ <<
diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc
index 472f0855d55..9f5a2eb7137 100644
--- a/src/rgw/driver/rados/rgw_sal_rados.cc
+++ b/src/rgw/driver/rados/rgw_sal_rados.cc
@@ -3201,7 +3201,7 @@ int RadosObject::set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, A
   const bool log_op = flags & rgw::sal::FLAG_LOG_OP;
   // make a tiny adjustment to the existing mtime so that fetch_remote_obj()
   // won't return ERR_NOT_MODIFIED when syncing the modified object
-  const auto mtime = log_op ? state.mtime + std::chrono::nanoseconds(1) : state.mtime;
+  const auto mtime = log_op ? state.mtime + ceph::timespan{std::chrono::nanoseconds{1}} : state.mtime;
   return store->getRados()->set_attrs(dpp, rados_ctx,
 			bucket->get_info(),
 			get_obj(),
diff --git a/src/rgw/rgw_bucket_logging.cc b/src/rgw/rgw_bucket_logging.cc
index 8106bcc37e1..5bb39ca82b0 100644
--- a/src/rgw/rgw_bucket_logging.cc
+++ b/src/rgw/rgw_bucket_logging.cc
@@ -578,7 +578,7 @@ int log_record(rgw::sal::Driver* driver,
   RGWObjVersionTracker objv_tracker;
   ret = target_bucket->get_logging_object_name(obj_name, conf.target_prefix, y, dpp, &objv_tracker);
   if (ret == 0) {
-    const auto time_to_commit = time_from_name(obj_name, dpp) + std::chrono::seconds(conf.obj_roll_time);
+    const auto time_to_commit = time_from_name(obj_name, dpp) + ceph::timespan{std::chrono::seconds{conf.obj_roll_time}};
     if (ceph::coarse_real_time::clock::now() > time_to_commit) {
       ldpp_dout(dpp, 20) << "INFO: logging object '" << obj_name << "' exceeded its time, will be committed to logging bucket '" <<
         target_bucket_id << "'" << dendl;
-- 
2.49.1

