Commit Graph

173 Commits

Author SHA1 Message Date
houseme 25193ee6cf feat(listobjects): add guarded metadata-fast listing (#4311)
* feat(listobjects): add phase 0 observability metrics

* perf(listobjects): reduce gather metadata decoding

* test(listobjects): add adversarial listing coverage

* feat(listobjects): add source-aware cursor fields

* feat(listobjects): define index source modes

* feat(listobjects): model index rebuild health

* feat(listobjects): add opt-in index fallback gate

* feat(listobjects): verify index candidate pages

* docs(listobjects): add rollout runbook

* docs(listobjects): untrack baseline fixtures

* feat(listobjects): add opt-in key-only provider

* feat(listobjects): add index verification metrics

* perf(listobjects): gate list metrics on get stage switch

* feat(listobjects): bind provider health generation

* feat(listobjects): add persistent key-only provider

* feat(listobjects): bind persistent provider lifecycle

* feat(listobjects): track persistent index mutations

* feat(listobjects): persist index mutation checkpoints

* fix(listobjects): aggregate benchmark metric snapshots

* feat(listobjects): store journal in system namespace

* chore(listobjects): report fallback reasons in bench

* test(listobjects): verify metadata-fast stale fallbacks

* feat(listobjects): serve metadata-fast snapshots behind guardrails

* test(listobjects): add metadata-fast chaos bench

* fix(listobjects): attribute metadata-fast fallback metrics

* test(listobjects): add metadata-fast fallback chaos probes

* test(listobjects): add quorum journal chaos guardrails

* fix(listobjects): satisfy pre-pr clippy gate

* docs(listobjects): untrack rollout runbook

* fix(ecstore): remove redundant heal error conversion

* test(filemeta): satisfy replication info clippy

----

Co-Authored-By: heihutu <heihutu@gmail.com>
2026-07-07 01:38:52 +08:00
Zhengchao An 31c6859965 chore: converge stale TODOs and apply safe fills (backlog#646) (#4322)
Second TODO-convergence round over the current tree (backlog#646). All
line numbers in the old inventory had gone stale after the set_disk /
diagnostics / cluster refactors, so this re-scans and reduces the marker
count from 144 to 99.

STALE removals (comment describes already-implemented behavior, or dead
commented-out blocks) across ecstore (set_disk ops/core, store,
cluster/rpc, bucket/metadata_sys, services), iam, filemeta, s3select and
rustfs auth/object_usecase. No behavior change.

Safe fills, each verified:
- filemeta: replication_info_equals now also compares
  replication_state_internal (function currently has no callers; adds a
  regression test).
- bitrot: drop the confirmed-unused `_want` parameter from bitrot_verify
  and the now-unused `sum` on LocalDisk::bitrot_verify, removing a
  Bytes::copy_from_slice allocation. Streaming verify uses the file's
  embedded per-shard hash, never the passed sum.
- signer: rename v4_ignored_headers -> V4_IGNORED_HEADERS and drop the
  non_upper_case_globals allow.
- admin/heal: test_decode was #[ignore]d and used serde_urlencoded on a
  JSON body (would panic); rewire to serde_json::from_slice to match the
  production decode path, add assertions, un-ignore.

Verified: cargo fmt; cargo check on touched crates; tests pass
(filemeta, signer, bitrot, heal::test_decode); arch guardrail scripts
pass.
2026-07-06 22:43:32 +08:00
Zhengchao An 7975f26b90 fix(ecstore): reach orphan-dir purge on nil-version delete miss (#4189) (#4307)
PR #4220 added a purge for orphan empty-directory trees (folder keys with
no xl.meta) on the delete path, but the guard only accepted
object-not-found. Over the real HTTP DELETE path the guard is never
reached: `del_opts` pins `version_id = Uuid::nil()` for directory keys, so
the missing dir object fails the specific-version lookup with
version-not-found (FileVersionNotFound), not object-not-found. The guard
short-circuits, the store returns the error, and the API layer turns it
into a fake 204 — the ghost folder survives, exactly the #4189 symptom.

The existing unit tests passed because they call
`purge_orphan_dir_object` directly, bypassing the nil-version lookup.

Accept both misses in the guard (extracted as
`should_purge_orphan_dir_on_missing`) so the folder delete actually takes
effect. Non-directory keys and non-miss errors (e.g. quorum failures) are
unaffected; the cross-disk data-safety refusal in
`purge_orphan_dir_object` is unchanged.

Verified end-to-end against a running 4-disk erasure server: DELETE of a
planted orphan `ghost/` tree now purges it on all drives and clears the
listing, a real object under the same prefix is untouched, and a prefix
holding real data on any drive is refused (all drives preserved).

Adds predicate regression tests covering version-not-found /
object-not-found on directory keys, and the negative cases.
2026-07-06 20:47:04 +08:00
cxymds 2585855d23 fix(ecstore): hide deleted versioned folder prefixes (#4296) 2026-07-06 14:04:53 +08:00
houseme 76124423a4 fix: stabilize s3-tests delete key-limit coverage (#4283)
* fix: tighten list handling and s3 test support

* chore: tidy imports and metric updates

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zhengchao An <anzhengchao@gmail.com>

* fix: address s3tests review follow-ups

---------

Signed-off-by: Zhengchao An <anzhengchao@gmail.com>
Co-authored-by: Zhengchao An <anzhengchao@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-05 20:35:32 +08:00
Ramakrishna Chilaka eb85607e37 fix(s3): allow CopyObject to restore a historical object version (#4250) 2026-07-04 10:36:42 +08:00
Zhengchao An 3d4fb532e5 refactor(replication): own filemeta wire contracts (#4254) 2026-07-04 06:39:54 +08:00
Zhengchao An 6a81445a96 refactor(replication): isolate ecstore owner contracts (#4239) 2026-07-03 21:42:45 +08:00
houseme 25d80d7c60 feat(storage): harden internode data-path controls (#4224)
* fix(rio): propagate http writer shutdown errors

* fix(ecstore): unify remote lock rpc deadlines

* fix(storage): reject corrupt read multiple payloads

* feat(rio): add internode http tuning profiles

* feat(metrics): add internode baseline signals

* feat(ecstore): observe shard locality topology

* feat(ecstore): gate shard locality scheduling

* feat(ecstore): gate batch read version rpc

* feat(ecstore): observe batch processor adaptation

* feat(ecstore): gate batch processor observation

* docs: add get benchmark regression analysis

* docs: add issue 797 execution plan status

* fix(ecstore): require explicit batch rpc support

* fix(ecstore): honor documented batch read gate

* fix(ecstore): keep batch read gate stable per call

* chore: update workspace dependencies

* feat(ecstore): log batch read gate decisions

* feat(ecstore): count batch read gate decisions

* test(issue-797): add local internode A/B runner

* test(rio): fix tuning profile spelling fixture

* fix(protocols): adapt sftp channel open callbacks

* fix(metrics): wrap batch processor observation args

* chore(docs): keep issue notes local only

* fix(storage): address internode review feedback

* fix(storage): address internode data-path review findings

- Run the BatchReadVersion auto-mode unary fallback outside the batch
  RPC deadline so each read_version keeps its own per-op timeout and
  health accounting instead of racing the whole batch against one
  drive timeout.
- Cap adaptive batch-processor concurrency growth at a hard multiple
  of the configured baseline so sustained fast batches cannot ratchet
  past the configured limit.
- Parse RUSTFS_INTERNODE_HTTP_* tuning, RUSTFS_BATCH_PROCESSOR_ADAPTIVE,
  and RUSTFS_METADATA_BATCH_READ once per process instead of re-reading
  the environment on hot paths.
- Skip shard read-cost collection in observe mode when stage metrics
  are disabled, and cache the local endpoint host list instead of
  rebuilding it on every read.
- Allow --warp-extra-args values starting with -- and drop the unused
  warp_hosts_csv helper in the issue-797 A/B runner.

* fix(storage): address internode data-path review findings

- Run the BatchReadVersion auto-mode unary fallback outside the batch
  RPC deadline so each read_version keeps its own per-op timeout and
  health accounting instead of racing the whole batch against one
  drive timeout.
- Cap adaptive batch-processor concurrency growth at a hard multiple
  of the configured baseline so sustained fast batches cannot ratchet
  past the configured limit.
- Parse RUSTFS_INTERNODE_HTTP_* tuning, RUSTFS_BATCH_PROCESSOR_ADAPTIVE,
  and RUSTFS_METADATA_BATCH_READ once per process instead of re-reading
  the environment on hot paths.
- Skip shard read-cost collection in observe mode when stage metrics
  are disabled, and cache the local endpoint host list instead of
  rebuilding it on every read.
- Allow --warp-extra-args values starting with -- and drop the unused
  warp_hosts_csv helper in the issue-797 A/B runner.

Co-Authored-By: heihutu<heihutu@gmail.com>

* fix(storage): align buffer clamp test with media cap

* fix(ecstore): release optimized read locks before streaming

---------

Co-authored-by: Zhengchao An <anzhengchao@gmail.com>
2026-07-03 17:08:15 +08:00
Zhengchao An e9af89b40d fix(ecstore): purge orphan empty-directory trees on folder delete (#4220)
fix(ecstore): purge orphan empty-directory trees on folder delete (#4189)

Empty "phantom" folders — on-disk directory trees with no xl.meta
anywhere — show up in listings as common prefixes but cannot be removed
by any S3 call: DeleteObject on the folder key encodes it to __XLDIR__,
finds no metadata, and returns NotFound, which the API layer masks as a
fake 204 while the tree survives on disk.

Make handle_delete_object attempt a guarded purge when a dir-object key
resolves to NotFound:

- sweep every erasure set of every pool (orphan fragments can sit on
  any set, left behind by whichever sets stored the deleted children)
- per set, refuse if ANY disk holds a regular file under the prefix,
  so degraded/healable objects are never destroyed
- remove empty directories children-first with non-recursive deletes;
  a racing PutObject makes the rmdir fail with DirectoryNotEmpty and
  the entry is skipped

This state is unrepresentable on AWS S3 (CommonPrefixes derive only
from real keys; DeleteObject is an idempotent 204), so the purge moves
visible behavior closer to S3. It deliberately goes beyond MinIO, whose
DeleteObject leaves these trees stranded and whose heal only removes
dangling (minority-presence) dirs — a long-standing complaint
(minio/minio#15257, #19516, #18444).

Also move the test-only content_matches_by_etag import in
replication_target_boundary.rs into the cfg(test) module; it failed
cargo clippy -D warnings and blocked the pre-PR gate.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 11:34:43 +08:00
Zhengchao An dd6b5525e4 fix(ecstore): remove reachable panics in tiering, replication, and heal paths (#4205)
* fix(ecstore): remove reachable panics in tiering, replication, and heal paths

- Parse x-amz-expiration leniently in tier PUT responses; any lifecycle
  rule on the remote tier bucket returns an RFC1123 date that the previous
  ISO8601 unwrap turned into a panic of the ILM transition worker
- Skip invalid user-metadata header values (with a warning) when building
  tier and replication PUT headers instead of panicking on non-ASCII input
- Heal: tolerate absent data_dir for delete markers and remote objects
- transition_object: don't unwrap version_id on unversioned buckets when
  recording partial writes for offline disks
- Admin server info: use port_or_known_default() so default-port (80/443)
  endpoints don't panic is_server_resolvable
- Tier ListObjectsV2 client: decode response body with from_utf8_lossy
- walk_internal: log merge_entry_channels errors instead of dropping them

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ecstore): fail heal explicitly when data_dir is missing

Address review feedback: unwrap_or_default() silently substituted a nil
UUID when latest metadata lacked data_dir. Delete markers and remote
objects legitimately have no data_dir and skip the data-heal block, but
for a regular object a missing data_dir means corrupt metadata — return
FileCorrupt with a descriptive log instead of building part paths under
a nil UUID directory.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 00:14:11 +08:00
cxymds cf33bcc742 fix(ecstore): hold read locks for streaming readers (#4195) 2026-07-02 22:36:12 +08:00
Zhengchao An 18b79ccc2a refactor(replication): route filemeta paths through crate (#4161) 2026-07-02 09:08:47 +08:00
GatewayJ 7728c9f203 fix(ecstore): require commit quorum for latest metadata (#4117) 2026-07-02 00:41:11 +08:00
houseme b16120dbcc feat: optimize small GET read paths (#4022) 2026-07-01 15:40:00 +08:00
Zhengchao An 055d3ad825 refactor(ecstore): scope dead code allowances (#4098) 2026-06-30 06:07:45 +08:00
houseme 3d868cb6e8 perf: add list objects quorum tuning knob (#4072) 2026-06-30 03:41:29 +08:00
GatewayJ 14e9fa2c8d fix(ecstore): avoid startup pool meta locks (#4056) 2026-06-29 20:19:38 +08:00
Zhengchao An ecbc5385d3 refactor(runtime): hide local disk id global (#4047) 2026-06-29 16:33:36 +08:00
Zhengchao An f5d7fea7a4 fix(ecstore): remove unused mirror fields (#4019) 2026-06-28 22:31:37 +08:00
Zhengchao An 710ae74cde perf: add S3 operations benchmark framework (#738) (#4005) 2026-06-28 18:02:41 +08:00
Zhengchao An 05d201679c fix: replace unwrap() with expect() in more files (#729 batch 13) (#3993) 2026-06-28 11:45:13 +08:00
Zhengchao An f0ab812213 fix: replace unwrap() with expect() in remaining files (#729 batch 12) (#3992) 2026-06-28 11:45:03 +08:00
GatewayJ 675597ec16 fix(ecstore): handle stalled recovery reads and listings (#3790)
* fix(ecstore): handle stalled recovery reads and listings

* fix(rio): start HTTP stall timeout on read

* fix(ecstore): handle stalled reads and partial lists

* fix(ecstore): retire stalled shards and list errors

* fix(ecstore): preserve list merge lookahead entries

* fix(ecstore): bound zero-copy shard reads

* fix(ecstore): hedge stalled shard reads

* fix(ecstore): retire abandoned shard reads

* fix(ecstore): include part identity in metadata quorum

* fix(ecstore): validate heal shard sources

* fix(ecstore): verify reconstructed read shards

* chore(ecstore): log slow object read stages

* fix(heal): throttle auto heal during recovery

* fix(scanner): yield to foreground reads

* fix(scanner): track streaming object reads

* fix(ecstore): avoid false read heal fanout

* fix(ecstore): verify codec streaming reconstruction sources

* fix(ecstore): preserve quorum progress on slow shards

* fix(storage): restore read timeout facade

* fix(ecstore): retain fallback readers after quorum

* chore: allow decode helper argument lists

---------

Co-authored-by: overtrue <anzhengchao@gmail.com>
2026-06-27 10:21:09 +08:00
Zhengchao An 0a5b1b1b3a refactor: consolidate ecstore owner module layout (#3934)
* refactor: shrink ecstore root owner facades

* refactor: remove ecstore core store root shims

* refactor: move ecstore erasure owner modules

* refactor: remove ecstore root rpc facade

* refactor: move ecstore services domain modules
2026-06-27 09:03:20 +08:00
Zhengchao An 61b1296972 refactor: move ecstore store init support (#3931) 2026-06-27 05:05:01 +08:00
Zhengchao An bdfcde1866 refactor: move ecstore store support modules (#3930) 2026-06-27 03:51:11 +08:00
Zhengchao An 07428c8a34 refactor: move ecstore store owner roots (#3929) 2026-06-27 02:25:04 +08:00
Zhengchao An b38976d5ee refactor: segment ECStore storage contracts by domain (#3910) 2026-06-26 17:47:36 +08:00
Zhengchao An c9614eb7cb refactor: route ecstore storage api boundaries (#3892) 2026-06-26 09:35:18 +08:00
cxymds 57e12e56d2 fix(admin): correct pool lifecycle status mapping (#3823) 2026-06-24 17:05:07 +08:00
Zhengchao An aa089f18f2 refactor: centralize ecstore accessor runtime sources (#3813) 2026-06-24 11:05:30 +08:00
Zhengchao An 1a8ff1ea3e refactor: centralize ecstore setup runtime sources (#3812) 2026-06-24 10:41:33 +08:00
Zhengchao An 7e60432588 refactor: centralize ecstore runtime owner sources (#3798) 2026-06-24 06:34:06 +08:00
houseme 583a23bdf2 fix(ecstore): replace panic-driven pool and set stubs (#3753)
* fix(ecstore): replace panic-driven pool and set stubs

* test(runtime): tolerate restricted local bind checks

* fix(ecstore): remove remaining trait stub placeholders

* fix(ecstore): tighten trait stub follow-up semantics

* chore: ignore local worktrees

* chore: update layer dependency baseline for resolve_* context entries

Add 7 accepted infra->app dependency entries introduced by recent
refactoring PRs (#3770, #3771, #3772) that route global state lookups
through app::context::resolve_* functions.

Co-Authored-By: heihutu <heihutu@gmail.com>

---------

Co-authored-by: heihutu <heihutu@gmail.com>
2026-06-23 12:31:17 +08:00
cxymds 2f25cf606e fix(storage): harden rebalance decommission state (#3515) 2026-06-22 12:03:13 +08:00
安正超 0985225448 refactor: consolidate ecstore public facade (#3678)
* refactor: expand ecstore compatibility facade

* test: enforce ecstore api facade imports

* refactor: hide legacy ecstore layout modules

* refactor: hide ecstore facade root modules
2026-06-21 09:09:11 +08:00
安正超 f5bd31173d refactor: move ecstore pool-space builder (#3651) 2026-06-20 15:38:49 +08:00
安正超 1d9fd3d7ac refactor: move ecstore rebalance support helpers (#3650) 2026-06-20 13:34:23 +08:00
安正超 b1c6578df1 refactor: narrow test harness compatibility surfaces (#3592) 2026-06-19 07:10:52 +08:00
安正超 57403525ee refactor: move heal and namespace contracts (#3560) 2026-06-18 11:00:21 +08:00
安正超 e5cad7ed20 refactor: move object operation contracts (#3559) 2026-06-18 09:48:13 +08:00
cxymds 0f37c5675e fix(ecstore): bound decommission bucket concurrency (#3498) 2026-06-16 15:11:54 +08:00
cxymds 339a192a09 fix(ecstore): preserve bucket visibility during rebalance (#3418)
Co-authored-by: houseme <housemecn@gmail.com>
2026-06-14 03:37:54 +08:00
houseme 82af181dcf refactor(logging): unify governance runtime events (#3367) 2026-06-11 22:26:02 +08:00
houseme 0a987d870b refactor(logging): reduce runtime noise (#3363) 2026-06-11 19:49:01 +08:00
安正超 6b86e3875c refactor(storage): remove old admin surfaces (#3340) 2026-06-11 11:28:09 +08:00
安正超 f325b9f714 refactor(ecstore): route admin read internals (#3336) 2026-06-11 08:43:42 +08:00
Henry Guo 0cdcd1eb7b feat(table-catalog): internalize catalog backing paths (#3295)
* feat(table-catalog): internalize catalog backing paths

* fix(table-catalog): clean internal catalog on bucket delete

---------

Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
2026-06-09 12:01:25 +00:00
cxymds 9504dff595 fix(ecstore): harden rebalance data movement (#3234)
* fix(ecstore): harden rebalance data movement

* fix(ecstore): preserve failed rebalance status

* fix(ecstore): avoid rebalance walkdir total timeout

* fix(ecstore): retry rebalance listing timeouts

* fix(ecstore): restrict data movement resume target

* refactor(ecstore): simplify multipart movement target

* fix(ecstore): restore resume target checks

* perf(ecstore): speed up rebalance bucket merges

* fix: keep rebalance listing alive on transient failures

---------

Co-authored-by: houseme <housemecn@gmail.com>
2026-06-08 10:40:26 +00:00