perf(hotpath): add fine-grained PUT-path stage guards (HP-14) (#4541)

Close the ~10ms instrumentation residual on the PUT success path that the
existing coarse writer_setup/encode/rename stage metrics do not attribute.
Adds `hp_guard!` measurement scopes to the previously uninstrumented
sub-stages called out in backlog#935 item 2:

- SetDisks::acquire_read_lock / acquire_write_lock (namespace lock acquire)
- S3::put_object_prelookup (pre-write get_object_info lookup)
- MultiWriter::shutdown (bitrot writer flush/close)
- SetDisks::commit_rename_data_dir (old data-dir reclaim)
- S3Access::put_object (S3 authorization segment)

Instrumentation only: `hp_guard!` expands to nothing without the `hotpath`
feature, so this is a pure-observation change with zero behavior impact and
zero cost in default builds. The pre-lookup site wraps only the lookup call
in a scoped block so the guard measures that slice exactly while preserving
the existing match and control flow.

Verified: cargo check -p rustfs-ecstore (default and --features hotpath) and
cargo check -p rustfs (default and --features hotpath) all pass.

Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-07-09 01:47:14 +08:00
committed by GitHub
parent 0866a8e6a0
commit f262fcfce0
5 changed files with 10 additions and 1 deletions
+5 -1
View File
@@ -3515,7 +3515,11 @@ impl DefaultObjectUsecase {
.await
.map_err(ApiError::from)?,
);
let previous_current_size = match store.get_object_info(&bucket, &key, &current_opts).await {
let previous_current_info = {
crate::hp_guard!("S3::put_object_prelookup");
store.get_object_info(&bucket, &key, &current_opts).await
};
let previous_current_size = match previous_current_info {
Ok(existing_obj_info) => {
validate_existing_object_lock_for_write(&existing_obj_info, &opts)?;
Some(existing_obj_info.size.max(0) as u64)
+1
View File
@@ -1869,6 +1869,7 @@ impl S3Access for FS {
///
/// This method returns `Ok(())` by default.
async fn put_object(&self, req: &mut S3Request<PutObjectInput>) -> S3Result<()> {
crate::hp_guard!("S3Access::put_object");
let req_info = ext_req_info_mut(&mut req.extensions)?;
req_info.bucket = Some(req.input.bucket.clone());
req_info.object = Some(req.input.key.clone());