summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--PendingReleaseNotes4
-rw-r--r--debian/control3
-rw-r--r--qa/suites/rgw/lua/tasks/0-install.yaml10
-rw-r--r--src/pybind/rados/rados.pyx2
-rw-r--r--src/rgw/driver/rados/rgw_data_sync.cc4
-rw-r--r--src/rgw/driver/rados/rgw_rest_log.cc2
-rw-r--r--src/rgw/radosgw-admin/sync_checkpoint.cc1
-rw-r--r--src/rgw/rgw_common.h1
-rw-r--r--src/rgw/rgw_op.cc23
-rw-r--r--src/rgw/rgw_rest_swift.cc1
-rw-r--r--src/rgw/services/svc_bucket_sobj.cc2
-rw-r--r--src/test/pybind/test_rados.py5
12 files changed, 42 insertions, 16 deletions
diff --git a/PendingReleaseNotes b/PendingReleaseNotes
index b4824a65584..d25acfa9c6d 100644
--- a/PendingReleaseNotes
+++ b/PendingReleaseNotes
@@ -60,6 +60,10 @@
fuse client for `fallocate` for the default case (i.e. mode == 0) since
CephFS does not support disk space reservation. The only flags supported are
`FALLOC_FL_KEEP_SIZE` and `FALLOC_FL_PUNCH_HOLE`.
+* pybind/rados: Fixes WriteOp.zero() in the original reversed order of arguments
+ `offset` and `length`. When pybind calls WriteOp.zero(), the argument passed
+ does not match rados_write_op_zero, and offset and length are swapped, which
+ results in an unexpected response.
* The HeadBucket API now reports the `X-RGW-Bytes-Used` and `X-RGW-Object-Count`
headers only when the `read-stats` querystring is explicitly included in the
diff --git a/debian/control b/debian/control
index a7d2dbb4c3a..a8c79f7a731 100644
--- a/debian/control
+++ b/debian/control
@@ -999,7 +999,8 @@ Depends: librados2 (= ${binary:Version}),
liblua5.3-0,
${misc:Depends},
${shlibs:Depends},
-Suggests: luarocks,
+Suggests: liblua5.3-dev,
+ luarocks,
Description: RADOS Gateway client library
RADOS is a distributed object store used by the Ceph distributed
storage system. This package provides a REST gateway to the
diff --git a/qa/suites/rgw/lua/tasks/0-install.yaml b/qa/suites/rgw/lua/tasks/0-install.yaml
index fa6e279145c..d85ebcc5998 100644
--- a/qa/suites/rgw/lua/tasks/0-install.yaml
+++ b/qa/suites/rgw/lua/tasks/0-install.yaml
@@ -3,7 +3,7 @@ tasks:
- ceph:
- openssl_keys:
- rgw: [client.0]
-- tox: [client.0]
+- tox: [client.0]
overrides:
ceph:
@@ -11,3 +11,11 @@ overrides:
global:
osd_min_pg_log_entries: 10
osd_max_pg_log_entries: 10
+ install:
+ ceph:
+ extra_system_packages:
+ rpm:
+ - luarocks
+ deb:
+ - liblua5.3-dev
+ - luarocks
diff --git a/src/pybind/rados/rados.pyx b/src/pybind/rados/rados.pyx
index b54ebb483c6..bcfa6777f3d 100644
--- a/src/pybind/rados/rados.pyx
+++ b/src/pybind/rados/rados.pyx
@@ -1870,7 +1870,7 @@ cdef class WriteOp(object):
uint64_t _offset = offset
with nogil:
- rados_write_op_zero(self.write_op, _length, _offset)
+ rados_write_op_zero(self.write_op, _offset, _length)
def truncate(self, offset: int):
"""
diff --git a/src/rgw/driver/rados/rgw_data_sync.cc b/src/rgw/driver/rados/rgw_data_sync.cc
index c0a9059a251..1302f278f59 100644
--- a/src/rgw/driver/rados/rgw_data_sync.cc
+++ b/src/rgw/driver/rados/rgw_data_sync.cc
@@ -3021,7 +3021,7 @@ public:
if (!dest_bucket_perms.verify_bucket_permission(dest_key.value_or(key), rgw::IAM::s3PutObject)) {
ldout(cct, 0) << "ERROR: " << __func__ << ": permission check failed: user not allowed to write into bucket (bucket=" << sync_pipe.info.dest_bucket.get_key() << ")" << dendl;
- return -EPERM;
+ return set_cr_error(-EPERM);
}
}
@@ -4520,7 +4520,7 @@ public:
}
tn->set_resource_name(SSTR(bucket_str_noinstance(bs.bucket) << "/" << key));
}
- if (retcode == -ERR_PRECONDITION_FAILED || retcode == -EPERM) {
+ if (retcode == -ERR_PRECONDITION_FAILED || retcode == -EPERM || retcode == -EACCES) {
pretty_print(sc->env, "Skipping object s3://{}/{} in sync from zone {}\n",
bs.bucket.name, key, zone_name);
set_status("Skipping object sync: precondition failed (object contains newer change or policy doesn't allow sync)");
diff --git a/src/rgw/driver/rados/rgw_rest_log.cc b/src/rgw/driver/rados/rgw_rest_log.cc
index 9315dfc0afd..72216a471b3 100644
--- a/src/rgw/driver/rados/rgw_rest_log.cc
+++ b/src/rgw/driver/rados/rgw_rest_log.cc
@@ -1061,7 +1061,7 @@ void RGWOp_BILog_Status::execute(optional_yield y)
if (!pipe.dest.bucket) {
/* Uh oh, something went wrong */
- ldpp_dout(this, 20) << "ERROR: RGWOp_BILog_Status::execute(optional_yield y): BUG: pipe.dest.bucket was not initialized" << pipe << dendl;
+ ldpp_dout(this, 0) << "ERROR: RGWOp_BILog_Status::execute(optional_yield y): BUG: pipe.dest.bucket was not initialized" << pipe << dendl;
op_ret = -EIO;
return;
}
diff --git a/src/rgw/radosgw-admin/sync_checkpoint.cc b/src/rgw/radosgw-admin/sync_checkpoint.cc
index 0303ed6c747..97da99bdc27 100644
--- a/src/rgw/radosgw-admin/sync_checkpoint.cc
+++ b/src/rgw/radosgw-admin/sync_checkpoint.cc
@@ -228,6 +228,7 @@ int rgw_bucket_sync_checkpoint(const DoutPrefixProvider* dpp,
}
auto& entry = sources.emplace_back();
entry.pipe = pipe;
+ entry.pipe.dest.bucket = info.bucket; // so it contains the bucket key (+bucket id)
// fetch remote markers
boost::asio::spawn(ioctx, [&] (boost::asio::yield_context yield) {
diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h
index 99f7db4f569..88f5f7a9c52 100644
--- a/src/rgw/rgw_common.h
+++ b/src/rgw/rgw_common.h
@@ -1428,6 +1428,7 @@ struct RGWBucketEnt {
size_t size;
size_t size_rounded;
ceph::real_time creation_time;
+ ceph::real_time modification_time;
uint64_t count;
/* The placement_rule is necessary to calculate per-storage-policy statics
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc
index 1793c0b8065..d6f846b0d2f 100644
--- a/src/rgw/rgw_op.cc
+++ b/src/rgw/rgw_op.cc
@@ -917,15 +917,20 @@ void handle_replication_status_header(
auto attr_iter = attrs.find(RGW_ATTR_OBJ_REPLICATION_STATUS);
if (attr_iter != attrs.end() && attr_iter->second.to_str() == "PENDING") {
if (s->object->is_sync_completed(dpp, obj_mtime)) {
- s->object->set_atomic();
- rgw::sal::Attrs setattrs, rmattrs;
- bufferlist bl;
- bl.append("COMPLETED");
- setattrs[RGW_ATTR_OBJ_REPLICATION_STATUS] = std::move(bl);
- int ret = s->object->set_obj_attrs(dpp, &setattrs, &rmattrs, s->yield, 0);
- if (ret == 0) {
- ldpp_dout(dpp, 20) << *s->object << " has amz-replication-status header set to COMPLETED" << dendl;
- }
+ s->object->set_atomic();
+ rgw::sal::Attrs setattrs, rmattrs;
+ bufferlist bl;
+ bl.append("COMPLETED");
+ setattrs[RGW_ATTR_OBJ_REPLICATION_STATUS] = bl;
+ int ret = s->object->set_obj_attrs(dpp, &setattrs, &rmattrs, s->yield, 0);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to set object replication status to COMPLETED ret=" << ret << dendl;
+ return;
+ }
+
+ ldpp_dout(dpp, 20) << *s->object << " has amz-replication-status header set to COMPLETED" << dendl;
+
+ attrs[RGW_ATTR_OBJ_REPLICATION_STATUS] = std::move(bl); // update the attrs so that the status is reflected in the response
}
}
}
diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc
index b8ff3ca2fe8..88af0fc9c27 100644
--- a/src/rgw/rgw_rest_swift.cc
+++ b/src/rgw/rgw_rest_swift.cc
@@ -361,6 +361,7 @@ void RGWListBuckets_ObjStore_SWIFT::dump_bucket_entry(const RGWBucketEnt& ent)
if (need_stats) {
s->formatter->dump_int("count", ent.count);
s->formatter->dump_int("bytes", ent.size);
+ dump_time(s, "last_modified", ent.modification_time);
}
s->formatter->close_section();
diff --git a/src/rgw/services/svc_bucket_sobj.cc b/src/rgw/services/svc_bucket_sobj.cc
index ca705c5a44d..0f4cd4e847b 100644
--- a/src/rgw/services/svc_bucket_sobj.cc
+++ b/src/rgw/services/svc_bucket_sobj.cc
@@ -556,7 +556,7 @@ int RGWSI_Bucket_SObj::read_bucket_stats(const rgw_bucket& bucket,
const DoutPrefixProvider *dpp)
{
RGWBucketInfo bucket_info;
- int ret = read_bucket_info(bucket, &bucket_info, nullptr, nullptr, boost::none, y, dpp);
+ int ret = read_bucket_info(bucket, &bucket_info, &ent->modification_time, nullptr, boost::none, y, dpp);
if (ret < 0) {
return ret;
}
diff --git a/src/test/pybind/test_rados.py b/src/test/pybind/test_rados.py
index 25423bd8dcb..881b29c9152 100644
--- a/src/test/pybind/test_rados.py
+++ b/src/test/pybind/test_rados.py
@@ -516,6 +516,11 @@ class TestIoctx(object):
eq(self.ioctx.read('write_ops'), b'12\x00\x005')
write_op.write_full(b'12345')
+ write_op.zero(0, 2)
+ self.ioctx.operate_write_op(write_op, "write_ops")
+ eq(self.ioctx.read('write_ops'), b'\x00\x00345')
+
+ write_op.write_full(b'12345')
write_op.truncate(2)
self.ioctx.operate_write_op(write_op, "write_ops")
eq(self.ioctx.read('write_ops'), b'12')