diff --git a/crates/ecstore/src/bucket/bucket_target_sys.rs b/crates/ecstore/src/bucket/bucket_target_sys.rs index c6bcc5742..0a9b0f41c 100644 --- a/crates/ecstore/src/bucket/bucket_target_sys.rs +++ b/crates/ecstore/src/bucket/bucket_target_sys.rs @@ -82,7 +82,6 @@ use tracing::warn; use url::Url; use uuid::Uuid; -const DEFAULT_HEALTH_CHECK_RELOAD_DURATION: Duration = Duration::from_secs(30 * 60); const MAX_CONCURRENT_TARGET_HEALTH_CHECKS: usize = 16; const REDACTED_CREDENTIAL: &str = ""; diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index e0849a637..c74451095 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -126,11 +126,23 @@ const EVENT_LIFECYCLE_EXPIRED_DETECTED: &str = "lifecycle_expired_detected"; const EVENT_LIFECYCLE_NOT_ENQUEUED: &str = "lifecycle_not_enqueued"; const EVENT_LIFECYCLE_DELETE_DISPATCHED: &str = "lifecycle_delete_dispatched"; const EVENT_LIFECYCLE_DELETE_COMPLETED: &str = "lifecycle_delete_completed"; +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] const EVENT_LIFECYCLE_TIER_AUDIT: &str = "lifecycle_tier_audit"; const EVENT_LIFECYCLE_TIER_OPERATION_FAILED: &str = "lifecycle_tier_operation_failed"; const EVENT_LIFECYCLE_DELETE_FAILED: &str = "lifecycle_delete_failed"; +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub type TimeFn = Arc Pin + Send>> + Send + Sync + 'static>; +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub type TraceFn = Arc) -> Pin + Send>> + Send + Sync + 'static>; pub type ExpiryOpType = Box; @@ -140,9 +152,21 @@ static TIER_FREE_VERSION_RECOVERY_STARTED: OnceLock<()> = OnceLock::new(); static MANUAL_TRANSITION_JOB_RECOVERY_STARTED: OnceLock<()> = OnceLock::new(); pub const AMZ_OBJECT_TAGGING: &str = "X-Amz-Tagging"; +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub const AMZ_TAG_COUNT: &str = "x-amz-tagging-count"; +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub const AMZ_TAG_DIRECTIVE: &str = "X-Amz-Tagging-Directive"; pub const AMZ_ENCRYPTION_AES: &str = "AES256"; +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub const AMZ_ENCRYPTION_KMS: &str = "aws:kms"; pub const ERR_INVALID_STORAGECLASS: &str = "invalid tier."; @@ -280,6 +304,10 @@ impl LifecycleSys { } } + #[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" + )] pub fn trace(oi: &ObjectInfo) -> TraceFn { let bucket = oi.bucket.clone(); let name = oi.name.clone(); @@ -570,6 +598,10 @@ async fn delete_free_version_remote_object( Ok(()) } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] async fn delete_free_version_remote_object_then( oi: &ObjectInfo, tier_config_mgr: &Arc>, @@ -2868,6 +2900,10 @@ fn stale_upload_default_due(initiated: OffsetDateTime, default_expiry: StdDurati initiated + time::Duration::seconds(default_expiry.as_secs() as i64) } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] async fn stale_upload_current_size(set: &Arc, metadata: &HashMap, upload_dir: &str) -> Option { stale_upload_current_size_with_opts(set, metadata, upload_dir, false).await } @@ -3352,6 +3388,10 @@ pub async fn validate_transition_tier(lc: &BucketLifecycleConfiguration) -> Resu Ok(()) } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] fn mark_delete_opts_skip_decommissioned_on_remote_success(opts: &mut ObjectOptions, remote_delete_succeeded: bool) { if remote_delete_succeeded { opts.skip_decommissioned = true; @@ -4373,6 +4413,10 @@ pub async fn transition_object(api: Arc, oi: &ObjectInfo, lae: LcAuditE result } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub fn audit_tier_actions(_tier: &str, bytes: i64) -> TimeFn { let tier = _tier.to_string(); Arc::new(move || { @@ -4391,6 +4435,10 @@ pub fn audit_tier_actions(_tier: &str, bytes: i64) -> TimeFn { }) } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn get_transitioned_object_reader( bucket: &str, object: &str, @@ -5145,6 +5193,10 @@ async fn lifecycle_delete_config_snapshot(api: &ECStore, oi: &ObjectInfo) -> Res ReplicationObjectBridge::delete_request_config(api, &oi.bucket).await } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn apply_lifecycle_action(event: &lifecycle::Event, src: &LcEventSrc, oi: &ObjectInfo) -> bool { let mut success = false; match event.action { @@ -7422,6 +7474,10 @@ mod tests { // process environment while `env::set_var`/`env::remove_var` is active. // SAFETY: keep this note adjacent to the allowance for the repository guard. #[allow(unsafe_code)] + #[allow( + dead_code, + reason = "transition-queue env fixture kept for tests that scope those vars; no test uses it today (backlog#1823)" + )] async fn with_transition_queue_env_async(capacity: Option<&str>, timeout_ms: Option<&str>, test_fn: F) where F: FnOnce() -> Fut, diff --git a/crates/ecstore/src/bucket/lifecycle/manual_transition_job.rs b/crates/ecstore/src/bucket/lifecycle/manual_transition_job.rs index 448ae2230..b1fe45cad 100644 --- a/crates/ecstore/src/bucket/lifecycle/manual_transition_job.rs +++ b/crates/ecstore/src/bucket/lifecycle/manual_transition_job.rs @@ -759,6 +759,10 @@ pub struct ManualTransitionWorkerResultRecord { } impl ManualTransitionWorkerResultRecord { + #[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" + )] pub fn new(job_id: Uuid, task_key: impl Into, result: ManualTransitionWorkerResult) -> Self { Self::new_with_reason(job_id, task_key, result, None) } @@ -1257,6 +1261,10 @@ pub(crate) async fn save_manual_transition_task_if_absent( } } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn load_manual_transition_task_record( api: Arc, job_id: Uuid, @@ -1320,6 +1328,10 @@ async fn scan_manual_transition_task_journal(api: Arc, job_id: Uuid) -> } } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn load_manual_transition_worker_result_stats( api: Arc, job_id: Uuid, @@ -1455,6 +1467,10 @@ async fn scan_manual_transition_worker_result_journal( } } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn reconcile_manual_transition_worker_results( api: Arc, job_id: Uuid, diff --git a/crates/ecstore/src/bucket/lifecycle/replication_sink.rs b/crates/ecstore/src/bucket/lifecycle/replication_sink.rs index a965988e1..32cd6b57a 100644 --- a/crates/ecstore/src/bucket/lifecycle/replication_sink.rs +++ b/crates/ecstore/src/bucket/lifecycle/replication_sink.rs @@ -15,25 +15,35 @@ use rustfs_common::metrics::IlmAction; use crate::bucket::lifecycle::lifecycle::ObjectOpts; +use crate::bucket::replication::ReplicationLifecycleBridge; pub(crate) use crate::bucket::replication::ReplicationStatusType; #[cfg(test)] pub(crate) use crate::bucket::replication::VersionPurgeStatusType; pub(crate) use crate::bucket::replication::{ DeleteReplicationConfigSnapshot, ReplicationObjectBridge, replication_state_to_filemeta, }; -use crate::bucket::replication::{ReplicationLifecycleBridge, ReplicationLifecycleConfig}; use crate::storage_api_contracts::object::DeletedObject; -pub(crate) type LifecycleReplicationConfig = ReplicationLifecycleConfig; - +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) fn has_pending_version_purge(obj: &ObjectOpts) -> bool { obj.version_purge_status.is_pending() } +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) fn has_pending_object_replication(obj: &ObjectOpts) -> bool { replication_status_blocks_lifecycle(&obj.replication_status) } +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) fn has_pending_lifecycle_replication(obj: &ObjectOpts) -> bool { has_pending_object_replication(obj) || has_pending_version_purge(obj) } diff --git a/crates/ecstore/src/bucket/lifecycle/tagging_boundary.rs b/crates/ecstore/src/bucket/lifecycle/tagging_boundary.rs index 03e57def1..ff200c98a 100644 --- a/crates/ecstore/src/bucket/lifecycle/tagging_boundary.rs +++ b/crates/ecstore/src/bucket/lifecycle/tagging_boundary.rs @@ -14,6 +14,10 @@ use std::collections::HashMap; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) fn decode_tags_to_map(tags: &str) -> HashMap { crate::bucket::tagging::decode_tags_to_map(tags) } diff --git a/crates/ecstore/src/bucket/lifecycle/tier_delete_journal.rs b/crates/ecstore/src/bucket/lifecycle/tier_delete_journal.rs index 6542e88b8..ee05be7c7 100644 --- a/crates/ecstore/src/bucket/lifecycle/tier_delete_journal.rs +++ b/crates/ecstore/src/bucket/lifecycle/tier_delete_journal.rs @@ -331,6 +331,10 @@ where persist_tier_delete_journal_entry(api, &committed).await } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn abort_tier_delete_journal_entry(api: Arc, je: &Jentry) -> std::io::Result<()> where S: ObjectOperations< diff --git a/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs b/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs index ac45de861..0bcae9dc6 100644 --- a/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs +++ b/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs @@ -148,6 +148,10 @@ struct RecoveryCursor { object: String, } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn recover_tier_free_versions( api: Arc, limit: usize, diff --git a/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs b/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs index a934cdb11..2ce68fd03 100644 --- a/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs +++ b/crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs @@ -385,6 +385,10 @@ impl ExpiryOp for Jentry { } } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn delete_object_from_remote_tier(obj_name: &str, rv_id: &str, tier_name: &str) -> Result<(), std::io::Error> { let result = delete_object_from_remote_tier_raw(obj_name, rv_id, tier_name).await; if let Err(err) = &result @@ -395,6 +399,10 @@ pub async fn delete_object_from_remote_tier(obj_name: &str, rv_id: &str, tier_na result } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] async fn delete_object_from_remote_tier_raw(obj_name: &str, rv_id: &str, tier_name: &str) -> Result<(), std::io::Error> { #[cfg(test)] if let Some(result) = run_remote_tier_delete_test_hook(obj_name, rv_id, tier_name) { @@ -405,6 +413,10 @@ async fn delete_object_from_remote_tier_raw(obj_name: &str, rv_id: &str, tier_na delete_object_from_remote_tier_raw_with_manager(obj_name, rv_id, tier_name, &tier_config_mgr).await } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] async fn delete_object_from_remote_tier_raw_with_manager( obj_name: &str, rv_id: &str, @@ -485,6 +497,10 @@ pub enum RemoteTierDeleteOutcome { AlreadyRemoved, } +#[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" +)] pub async fn delete_object_from_remote_tier_idempotent( obj_name: &str, rv_id: &str, diff --git a/crates/ecstore/src/bucket/lifecycle/transition_transaction.rs b/crates/ecstore/src/bucket/lifecycle/transition_transaction.rs index 9549d231c..7fc231281 100644 --- a/crates/ecstore/src/bucket/lifecycle/transition_transaction.rs +++ b/crates/ecstore/src/bucket/lifecycle/transition_transaction.rs @@ -50,8 +50,16 @@ pub type Result = std::result::Result; #[derive(Debug, thiserror::Error)] pub enum TransitionTransactionError { #[error("transition transaction already exists")] + #[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" + )] AlreadyExists, #[error("transition transaction is not found")] + #[allow( + dead_code, + reason = "MinIO-parity tier/lifecycle entry point that this port never wired (backlog#1823)" + )] NotFound, #[error("transition transaction is corrupt: {0}")] Corrupt(&'static str), diff --git a/crates/ecstore/src/bucket/metadata_sys.rs b/crates/ecstore/src/bucket/metadata_sys.rs index 94709e4ed..96b35e206 100644 --- a/crates/ecstore/src/bucket/metadata_sys.rs +++ b/crates/ecstore/src/bucket/metadata_sys.rs @@ -60,12 +60,14 @@ struct ConfigWriteLockProbeState { static CONFIG_WRITE_LOCK_PROBES: std::sync::OnceLock>>> = std::sync::OnceLock::new(); #[cfg(any(test, feature = "test-util"))] +#[allow(dead_code, reason = "installed by tests behind `--features test-util` (backlog#1823)")] pub struct ConfigWriteLockProbe { state: Arc, } #[cfg(any(test, feature = "test-util"))] impl ConfigWriteLockProbe { + #[allow(dead_code, reason = "installed by tests behind `--features test-util` (backlog#1823)")] pub fn install(bucket: &str) -> Self { let state = Arc::new(ConfigWriteLockProbeState { bucket: bucket.to_string(), @@ -84,6 +86,7 @@ impl ConfigWriteLockProbe { Self { state } } + #[allow(dead_code, reason = "installed by tests behind `--features test-util` (backlog#1823)")] pub async fn wait_until_attempted(&self) { tokio::time::timeout(Duration::from_secs(30), self.state.arrived.notified()) .await @@ -890,6 +893,10 @@ pub async fn get_bucket_policy_raw(bucket: &str) -> Result<(String, OffsetDateTi bucket_meta_sys.get_bucket_policy_raw(bucket).await } +#[allow( + dead_code, + reason = "free-function facade over the live BucketMetadataSys::get_bucket_acl_config; no caller in this port (backlog#1823)" +)] pub async fn get_bucket_acl_config(bucket: &str) -> Result<(String, OffsetDateTime)> { let bucket_meta_sys_lock = get_bucket_metadata_sys()?; let bucket_meta_sys = bucket_meta_sys_lock.read().await; @@ -1104,6 +1111,10 @@ pub async fn get_config_from_disk(bucket: &str) -> Result { bucket_meta_sys.get_config_from_disk(bucket).await } +#[allow( + dead_code, + reason = "ambient-facade variant of the live created_at_in; no caller in this port (backlog#1823)" +)] pub async fn created_at(bucket: &str) -> Result { let bucket_meta_sys_lock = get_bucket_metadata_sys()?; let bucket_meta_sys = bucket_meta_sys_lock.read().await; @@ -1617,6 +1628,7 @@ impl BucketMetadataSys { /// [`Self::update`], with the payload computed from the loaded metadata /// instead of supplied up front. Loads through this system's own store so /// the read and the persisted write target the same instance. + #[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] async fn update_config_with(&self, bucket: &str, config_file: &str, mutate: F) -> Result where F: FnOnce(&BucketMetadata) -> Result> + Send, @@ -1721,6 +1733,7 @@ impl BucketMetadataSys { /// A miss is never published as an authoritative default, and a snapshot /// read before delete plus same-name recreation cannot replace the new /// generation. + #[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] pub(crate) async fn reload_from_store(&self, bucket: &str) -> Result<()> { if is_meta_bucketname(bucket) { return Err(Error::other("errInvalidArgument")); diff --git a/crates/ecstore/src/bucket/mod.rs b/crates/ecstore/src/bucket/mod.rs index 4f04755e1..54306247a 100644 --- a/crates/ecstore/src/bucket/mod.rs +++ b/crates/ecstore/src/bucket/mod.rs @@ -13,7 +13,6 @@ // limitations under the License. // #730: bucket subsystems still contain staged ECStore migration code. -#![allow(dead_code)] pub mod bandwidth; pub mod bucket_target_sys; diff --git a/crates/ecstore/src/bucket/object_lock/objectlock_sys.rs b/crates/ecstore/src/bucket/object_lock/objectlock_sys.rs index b85c6976b..c8ca80288 100644 --- a/crates/ecstore/src/bucket/object_lock/objectlock_sys.rs +++ b/crates/ecstore/src/bucket/object_lock/objectlock_sys.rs @@ -136,6 +136,7 @@ pub fn add_years(dt: OffsetDateTime, years: i32) -> OffsetDateTime { /// Check if an object has legal hold enabled. /// Returns true if legal hold is ON. +#[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] fn has_legal_hold(user_defined: &std::collections::HashMap) -> bool { let lhold = objectlock::get_object_legalhold_meta(user_defined); matches!(lhold.status, Some(ref st) if st.as_str() == ObjectLockLegalHoldStatus::ON) @@ -151,6 +152,7 @@ fn has_legal_hold(user_defined: &std::collections::HashMap) -> b /// # Returns /// * `true` if the object is locked (cannot be deleted/modified) /// * `false` if the object is not locked +#[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] pub fn is_object_locked_by_metadata(user_defined: &std::collections::HashMap, is_delete_marker: bool) -> bool { // Delete markers are never locked if is_delete_marker { diff --git a/crates/ecstore/src/bucket/quota/mod.rs b/crates/ecstore/src/bucket/quota/mod.rs index 157c750e4..0ce5a3a52 100644 --- a/crates/ecstore/src/bucket/quota/mod.rs +++ b/crates/ecstore/src/bucket/quota/mod.rs @@ -193,6 +193,7 @@ pub enum QuotaError { } #[derive(Debug, Serialize)] +#[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] pub struct QuotaErrorResponse { #[serde(rename = "Code")] pub code: String, @@ -208,6 +209,7 @@ pub struct QuotaErrorResponse { } impl QuotaErrorResponse { + #[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] pub fn new(quota_error: &QuotaError, request_id: &str, host_id: &str) -> Self { match quota_error { QuotaError::QuotaExceeded { .. } => Self { diff --git a/crates/ecstore/src/bucket/quota/reservation.rs b/crates/ecstore/src/bucket/quota/reservation.rs index 175785487..33aa5c876 100644 --- a/crates/ecstore/src/bucket/quota/reservation.rs +++ b/crates/ecstore/src/bucket/quota/reservation.rs @@ -899,6 +899,7 @@ async fn save_ledger_locked( } #[cfg(any(test, feature = "test-util"))] +#[allow(dead_code, reason = "asserted by this file's tests (backlog#1823)")] pub fn fail_next_quota_ledger_save_for_test() { FAIL_NEXT_LEDGER_SAVE.store(true, std::sync::atomic::Ordering::SeqCst); } diff --git a/crates/ecstore/src/bucket/replication/mod.rs b/crates/ecstore/src/bucket/replication/mod.rs index 1c4ac52d4..d46f78eb3 100644 --- a/crates/ecstore/src/bucket/replication/mod.rs +++ b/crates/ecstore/src/bucket/replication/mod.rs @@ -60,7 +60,7 @@ pub use replication_filemeta_boundary::{ pub(crate) use replication_filemeta_boundary::{ replication_state_from_filemeta, replication_status_from_filemeta, version_purge_status_from_filemeta, }; -pub(crate) use replication_lifecycle_bridge::{ReplicationLifecycleBridge, ReplicationLifecycleConfig}; +pub(crate) use replication_lifecycle_bridge::ReplicationLifecycleBridge; pub(crate) use replication_migration_bridge::ReplicationMigrationBridge; pub use replication_object_bridge::ReplicationObjectBridge; pub use replication_object_config::{DeleteReplicationConfigSnapshot, ReplicationConfig}; diff --git a/crates/ecstore/src/bucket/replication/replication_config_store.rs b/crates/ecstore/src/bucket/replication/replication_config_store.rs index de0e14c61..5ac6a48af 100644 --- a/crates/ecstore/src/bucket/replication/replication_config_store.rs +++ b/crates/ecstore/src/bucket/replication/replication_config_store.rs @@ -37,6 +37,10 @@ impl ReplicationConfigStore { com::read_config_limited(api, file, max_bytes).await } + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] pub(crate) async fn read_no_lock(api: Arc, file: &str) -> Result> where S: ReplicationObjectIO, diff --git a/crates/ecstore/src/bucket/replication/replication_lifecycle_bridge.rs b/crates/ecstore/src/bucket/replication/replication_lifecycle_bridge.rs index 3908389ba..c35bf99c1 100644 --- a/crates/ecstore/src/bucket/replication/replication_lifecycle_bridge.rs +++ b/crates/ecstore/src/bucket/replication/replication_lifecycle_bridge.rs @@ -24,15 +24,27 @@ use super::replication_storage_boundary::{ DeletedObject, ObjectInfo, ObjectOptions, ObjectToDelete, deleted_object_for_replication, }; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) type ReplicationLifecycleConfig = ReplicationConfig; pub(crate) struct ReplicationLifecycleBridge; impl ReplicationLifecycleBridge { + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) fn new_config(config: ReplicationConfiguration) -> ReplicationLifecycleConfig { ReplicationConfig::new(Some(config), None) } + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) fn has_pending_version_purge( config: &ReplicationLifecycleConfig, object_name: &str, @@ -45,6 +57,10 @@ impl ReplicationLifecycleBridge { .is_some_and(|config| config.has_active_rules(object_name, true)) } + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) async fn check_delete_replication( bucket: &str, object: &ObjectToDelete, @@ -54,6 +70,10 @@ impl ReplicationLifecycleBridge { check_replicate_delete(bucket, object, source, opts, None).await } + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) fn version_delete_replication_state(decision: &ReplicateDecision) -> ReplicationState { let pending_status = decision.pending_status(); ReplicationState { diff --git a/crates/ecstore/src/bucket/replication/replication_msgp_boundary.rs b/crates/ecstore/src/bucket/replication/replication_msgp_boundary.rs index 48f0685b9..72622d6cf 100644 --- a/crates/ecstore/src/bucket/replication/replication_msgp_boundary.rs +++ b/crates/ecstore/src/bucket/replication/replication_msgp_boundary.rs @@ -19,17 +19,33 @@ use time::OffsetDateTime; use super::replication_error_boundary::Result; use crate::bucket::msgp_decode; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) struct ReplicationMsgpCodec; impl ReplicationMsgpCodec { + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) fn read_ext8_time(rd: &mut R) -> Result { msgp_decode::read_msgp_ext8_time(rd) } + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) fn skip_value(rd: &mut R) -> Result<()> { msgp_decode::skip_msgp_value(rd) } + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) fn write_time(wr: &mut W, time: OffsetDateTime) -> Result<()> { msgp_decode::write_msgp_time(wr, time) } diff --git a/crates/ecstore/src/bucket/replication/replication_object_bridge.rs b/crates/ecstore/src/bucket/replication/replication_object_bridge.rs index 07b126c42..1043c22cd 100644 --- a/crates/ecstore/src/bucket/replication/replication_object_bridge.rs +++ b/crates/ecstore/src/bucket/replication/replication_object_bridge.rs @@ -77,6 +77,10 @@ impl ReplicationObjectBridge { load_delete_request_config_in(ctx, bucket).await } + #[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" + )] pub(crate) async fn delete_config_snapshot_in( ctx: &ReplicationInstanceContext, bucket: &str, diff --git a/crates/ecstore/src/bucket/replication/replication_object_config.rs b/crates/ecstore/src/bucket/replication/replication_object_config.rs index e8dbe33e4..3f44a9d10 100644 --- a/crates/ecstore/src/bucket/replication/replication_object_config.rs +++ b/crates/ecstore/src/bucket/replication/replication_object_config.rs @@ -231,6 +231,10 @@ pub(crate) async fn load_delete_replication_config( delete_snapshot_from_metadata(ReplicationMetadataStore::delete_metadata(bucket).await?) } +#[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" +)] pub(crate) async fn load_delete_replication_config_in( ctx: &ReplicationInstanceContext, bucket: &str, diff --git a/crates/ecstore/src/bucket/replication/replication_pool.rs b/crates/ecstore/src/bucket/replication/replication_pool.rs index 76d807d75..58b3efdca 100644 --- a/crates/ecstore/src/bucket/replication/replication_pool.rs +++ b/crates/ecstore/src/bucket/replication/replication_pool.rs @@ -217,6 +217,10 @@ impl DurableMrfBacklogTracker { } } +#[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" +)] fn durable_mrf_backlog_tracker_from_entries(entries: &[MrfReplicateEntry]) -> DurableMrfBacklogTracker { let mut tracker = DurableMrfBacklogTracker { available: true, @@ -712,6 +716,10 @@ pub struct ReplicationPool { // MRF worker lifecycle mrf_worker_cancellations: Mutex>, + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] mrf_stop_tx: Sender<()>, // Worker size tracking @@ -940,6 +948,10 @@ impl ReplicationPool { } /// Resizes worker priority and counts + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] pub async fn resize_worker_priority( &self, pri: ReplicationPriority, @@ -1180,6 +1192,10 @@ impl ReplicationPool { } /// Queues an MRF save operation + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] async fn queue_mrf_save(&self, entry: MrfReplicateEntry) { let _ = self.queue_mrf_save_admission(entry, "mrf_worker").await; } @@ -1651,6 +1667,10 @@ impl ReplicationPool { } /// Worker function for handling regular replication operations + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] async fn add_worker( &self, mut rx: Receiver, @@ -1664,6 +1684,10 @@ impl ReplicationPool { } /// Worker function for handling large object replication operations + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] async fn add_large_worker( &self, mut rx: Receiver, @@ -1678,6 +1702,10 @@ impl ReplicationPool { } /// Worker function for handling MRF (Most Recent Failures) operations + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] async fn add_mrf_worker( &self, mut rx: Receiver, @@ -1691,6 +1719,10 @@ impl ReplicationPool { } /// Delete resync metadata from replication resync state in memory + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] pub async fn delete_resync_metadata(&self, bucket: &str) { let mut status_map = self.resyncer.status_map.write().await; status_map.remove(bucket); diff --git a/crates/ecstore/src/bucket/replication/replication_resync_boundary.rs b/crates/ecstore/src/bucket/replication/replication_resync_boundary.rs index c41c6ab79..3b6dcdf5d 100644 --- a/crates/ecstore/src/bucket/replication/replication_resync_boundary.rs +++ b/crates/ecstore/src/bucket/replication/replication_resync_boundary.rs @@ -21,11 +21,31 @@ pub(crate) use rustfs_replication::{ should_count_head_proxy_failure, }; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) const RESYNC_META_FORMAT: u16 = rustfs_replication::resync::RESYNC_META_FORMAT; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) const RESYNC_META_VERSION: u16 = rustfs_replication::resync::RESYNC_META_VERSION; pub(crate) const RESYNC_FILE_MAX_BYTES: usize = rustfs_replication::RESYNC_FILE_MAX_BYTES; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) const WIRE_ZERO_TIME_UNIX: i64 = rustfs_replication::resync::WIRE_ZERO_TIME_UNIX; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) const MRF_META_FORMAT: u16 = rustfs_replication::mrf::MRF_META_FORMAT; +#[allow( + dead_code, + reason = "declared boundary surface for the ECStore replication split plan; no caller in this port (backlog#1823)" +)] pub(crate) const MRF_META_VERSION: u16 = rustfs_replication::mrf::MRF_META_VERSION; fn map_replication_error(err: rustfs_replication::Error) -> Error { diff --git a/crates/ecstore/src/bucket/replication/replication_resyncer.rs b/crates/ecstore/src/bucket/replication/replication_resyncer.rs index c6cdbcb03..30198a75b 100644 --- a/crates/ecstore/src/bucket/replication/replication_resyncer.rs +++ b/crates/ecstore/src/bucket/replication/replication_resyncer.rs @@ -122,6 +122,10 @@ const REPLICATION_TARGET_OFFLINE_ERROR_MARKERS: &[&str] = &[ "tcp connect error", ]; +#[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" +)] const RESYNC_TIME_INTERVAL: TokioDuration = TokioDuration::from_secs(60); static WARNED_MONITOR_UNINIT: std::sync::Once = std::sync::Once::new(); @@ -328,6 +332,10 @@ fn bounded_resync_max_jobs(value: usize) -> usize { #[derive(Debug)] pub struct ReplicationResyncer { pub status_map: Arc>>, + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] pub worker_size: usize, pub(crate) cancel_tokens: Arc>>, resync_admission: Arc, @@ -544,6 +552,10 @@ impl ReplicationResyncer { .is_some_and(|status| status.failed_count > 0) } + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] pub async fn persist_to_disk(&self, cancel_token: CancellationToken, api: Arc) where S: ReplicationObjectIO, diff --git a/crates/ecstore/src/bucket/replication/replication_state.rs b/crates/ecstore/src/bucket/replication/replication_state.rs index cd0e303f3..acd4b696a 100644 --- a/crates/ecstore/src/bucket/replication/replication_state.rs +++ b/crates/ecstore/src/bucket/replication/replication_state.rs @@ -340,6 +340,10 @@ impl ReplicationStats { } /// Site replication update replica statistics + #[allow( + dead_code, + reason = "MinIO-parity replication surface with no caller in this port (backlog#1823)" + )] fn sr_update_replica_stat(&self, size: i64) { self.sr_stats.replica_size.fetch_add(size, Ordering::Relaxed); self.sr_stats.replica_count.fetch_add(1, Ordering::Relaxed); diff --git a/crates/ecstore/src/bucket/target/bucket_target.rs b/crates/ecstore/src/bucket/target/bucket_target.rs index f78a2e0ef..55e3d3e8a 100644 --- a/crates/ecstore/src/bucket/target/bucket_target.rs +++ b/crates/ecstore/src/bucket/target/bucket_target.rs @@ -59,6 +59,10 @@ impl fmt::Debug for Credentials { } #[derive(Debug, Deserialize, Serialize, Default, Clone)] +#[allow( + dead_code, + reason = "MinIO-parity bucket-target service discriminator with no caller in this port (backlog#1823)" +)] pub enum ServiceType { #[default] Replication, diff --git a/crates/ecstore/src/bucket/utils.rs b/crates/ecstore/src/bucket/utils.rs index fdd934dc6..d24ef95b5 100644 --- a/crates/ecstore/src/bucket/utils.rs +++ b/crates/ecstore/src/bucket/utils.rs @@ -73,23 +73,6 @@ pub fn check_valid_bucket_name_strict(bucket_name: &str) -> Result<()> { check_bucket_name_common(bucket_name, true) } -pub fn check_valid_object_name_prefix(object_name: &str) -> Result<()> { - if object_name.len() > 1024 { - return Err(Error::other("Object name cannot be longer than 1024 characters")); - } - if !object_name.is_ascii() { - return Err(Error::other("Object name with non-UTF-8 strings are not supported")); - } - Ok(()) -} - -pub fn check_valid_object_name(object_name: &str) -> Result<()> { - if object_name.trim().is_empty() { - return Err(Error::other("Object name cannot be empty")); - } - check_valid_object_name_prefix(object_name) -} - pub fn deserialize(input: &[u8]) -> xml::DeResult where T: for<'xml> xml::Deserialize<'xml>, @@ -100,6 +83,10 @@ where Ok(ans) } +#[allow( + dead_code, + reason = "xml serialize helper with no caller in this port; the live sibling is deserialize (backlog#1823)" +)] pub fn serialize_content(val: &T) -> xml::SerResult { let mut buf = Vec::with_capacity(256); { @@ -186,15 +173,27 @@ pub fn is_valid_object_name(object: &str) -> bool { /// Client-facing reason attached to rejections of object keys that Win32/NTFS /// cannot represent as file paths (issue #3299). Deployments on Linux/macOS /// accept the full S3 key character set. +#[allow( + dead_code, + reason = "live on Windows: callers sit inside the #[cfg(target_os = \"windows\")] block in check_object_name_for_length_and_slash (backlog#1823)" +)] pub const WINDOWS_RESERVED_CHARACTERS_REASON: &str = "object key contains characters unsupported on Windows hosts (one of ':', '*', '?', '\"', '|', '<', '>')"; /// Client-facing reason for path segments Windows can store but not address /// afterwards (issue #3449): trailing dot/space or reserved DOS device names. +#[allow( + dead_code, + reason = "live on Windows: callers sit inside the #[cfg(target_os = \"windows\")] block in check_object_name_for_length_and_slash (backlog#1823)" +)] pub const WINDOWS_RESERVED_SEGMENT_REASON: &str = "object key contains a path segment unsupported on Windows hosts (trailing dot or space, or a reserved device name such as NUL/CON/COM1)"; /// Reserved DOS device names that shadow regular files on Windows, even when /// an extension is appended (e.g. `NUL.txt` resolves to the `NUL` device). +#[allow( + dead_code, + reason = "live on Windows: callers sit inside the #[cfg(target_os = \"windows\")] block in check_object_name_for_length_and_slash (backlog#1823)" +)] const WINDOWS_RESERVED_NAMES: &[&str] = &[ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", @@ -204,6 +203,10 @@ const WINDOWS_RESERVED_NAMES: &[&str] = &[ /// the Win32 API cannot address afterwards (issue #3449): segments ending in a /// dot or a space, and reserved DOS device names — bare or with an extension /// (`NUL.txt`), matching classic Win32 path resolution semantics. +#[allow( + dead_code, + reason = "live on Windows: callers sit inside the #[cfg(target_os = \"windows\")] block in check_object_name_for_length_and_slash (backlog#1823)" +)] pub fn object_name_has_windows_incompatible_segment(object: &str) -> bool { object.split(['/', '\\']).any(|segment| { if segment.ends_with('.') || segment.ends_with(' ') { diff --git a/crates/ecstore/src/bucket/versioning_sys.rs b/crates/ecstore/src/bucket/versioning_sys.rs index 685e95af9..abc6fee6d 100644 --- a/crates/ecstore/src/bucket/versioning_sys.rs +++ b/crates/ecstore/src/bucket/versioning_sys.rs @@ -90,6 +90,10 @@ impl BucketVersioningSys { /// caller's own instance context so a second in-process store never /// answers with the first instance's versioning state; falls back to the /// ambient system when the instance cell is not initialized. + #[allow( + dead_code, + reason = "instance-scoped seam (backlog#1052) with no caller in this port (backlog#1823)" + )] pub(crate) async fn get_in(ctx: &crate::runtime::instance::InstanceContext, bucket: &str) -> Result { if bucket == RUSTFS_META_BUCKET || bucket.starts_with(RUSTFS_META_BUCKET) { return Ok(VersioningConfiguration::default());