Commit Graph

7409 Commits

Author SHA1 Message Date
overtrue 7b1ff0da45 fix(scanner): retain the enabled supervisor task handle 2026-10-26 12:15:33 +08:00
overtrue 94f344a7d4 fix(rpc): budget namespace scanner responses 2026-10-26 11:15:13 +08:00
overtrue ff834ac98f feat(scanner): measure cache copy allocation requests 2026-10-26 08:55:50 +08:00
overtrue 3f0e592264 perf(rpc): reuse reserved response reader storage 2026-10-26 08:05:09 +08:00
overtrue c15af8e16d fix(rpc): reserve background scanner pipe storage 2026-10-26 07:37:15 +08:00
overtrue cc05fd0e37 perf(rio): reuse reserved HTTP writer storage 2026-10-26 06:58:11 +08:00
overtrue 083e7e7350 fix(storage): retain inline and HTTP writer memory reservations 2026-10-26 06:34:37 +08:00
overtrue 6f1875e021 test(scanner): verify samples and clean concurrent collectors 2026-10-26 05:52:11 +08:00
overtrue 9a03007726 fix(ecstore): account for heal and RPC reader buffers 2026-10-26 05:52:11 +08:00
overtrue 28cad76ce3 fix(storage): retain memory charges for direct-write buffers 2026-10-26 01:20:14 +08:00
overtrue d4d071869c fix(storage): account for native io_uring read allocations 2026-10-26 01:05:40 +08:00
overtrue 88cc1a3f54 fix(storage): retain memory charges for background read results 2026-10-26 00:44:26 +08:00
overtrue d6e8973e59 fix(storage): account for retained background stream buffers 2026-10-26 00:01:37 +08:00
overtrue 6845775668 fix(ecstore): retain physical ownership during durable rename sync 2026-10-25 22:05:26 +08:00
overtrue 0d28dcaf37 fix(ecstore): retain resources through whole-file native I/O 2026-10-25 21:35:12 +08:00
overtrue fbd2bd2ca1 fix(ecstore): enforce receiver-side background admission 2026-10-25 20:56:51 +08:00
overtrue 39ac7321aa fix(ecstore): retain native io_uring read ownership 2026-10-25 18:53:04 +08:00
overtrue e161e65147 fix(ecstore): retain staged metadata write ownership 2026-10-25 17:26:39 +08:00
overtrue 9bcc86f49f fix(ecstore): retain resources during positioned reads 2026-10-25 16:57:16 +08:00
overtrue 564c4354c9 fix(storage): retain physical ownership during bitrot reads 2026-10-25 16:32:08 +08:00
overtrue e07caee90c fix(storage): retain resources through native filesystem jobs 2026-10-25 16:12:13 +08:00
overtrue 4a41482a18 chore: align physical admission with the updated node base 2026-10-25 15:42:30 +08:00
overtrue 040720aa58 chore: sync node admission with current main 2026-10-25 15:42:11 +08:00
overtrue 136296c76b chore: integrate main disk dispatch with physical admission 2026-10-25 15:35:27 +08:00
overtrue 5158b16917 fix(storage): retain physical resources through streamed reads 2026-10-25 14:57:34 +08:00
Chris An 124cbfc00a feat(heal): read retained MRF lifecycle v2 checkpoints (#8913) 2026-10-25 14:34:57 +08:00
overtrue 3520821376 fix(storage): retain resources through buffered writer I/O 2026-10-25 14:32:29 +08:00
Jim Chen 3aa7964c58 fix(concurrency): prevent premature Workers::wait drain completion on slot handoff (#8892)
Workers::give() decrements in_use to 0 before calling semaphore.add_permits(1), while a queued Workers::take() task only increments in_use after its woken future is scheduled and polled, allowing Workers::wait() to return prematurely while a woken worker is still in flight.

Root Cause:
In crates/concurrency/src/workers.rs, Workers::give() decrements in_use inside self.in_use.send_modify() before calling self.semaphore.add_permits(1), while Workers::take() only increments in_use after self.semaphore.acquire().await returns and the woken task is scheduled and polled. During the handoff window when the last active worker calls give() and transfers its semaphore permit to a queued take() waiter (so semaphore.available_permits() < limit), in_use is 0, causing Workers::wait() (rx.wait_for(|&held| held == 0)) to complete prematurely while work is still in flight and Workers::available() to over-report available capacity.

Fix:
Require both held == 0 and self.semaphore.available_permits() == self.limit in Workers::wait(), notify self.in_use watchers after self.semaphore.add_permits(1) in Workers::give() and via an AcquireCancelGuard in Workers::take(), and bound Workers::available() by self.semaphore.available_permits().

Signed-off-by: czcbangkai <czcbangkai@google.com>
Co-authored-by: Hauser <housemecn@gmail.com>
2026-10-25 14:22:35 +08:00
Ramakrishna Chilaka 42d376c6b7 perf(ecstore): isolate durable I/O and streamline disk dispatch (#8902)
* perf(ecstore): unify per-disk blocking workers with spin keep-alive and coalesce DELETE hops

Unify per-disk blocking I/O and fsync workers under a 3-lane DiskBlockingQueue
(Foreground, Isolated, Fsync) with MAX_NAMESPACE_WORKERS_PER_DISK = 1 and a
bounded user-space spin/yield keep-alive (WORKER_IDLE_SPIN_ITERS = 256), and
coalesce redundant blocking dispatches along the DELETE hot path:

- Expand DiskBlockingQueue to 3 lanes (Foreground, Isolated, Fsync) with 1
  warm worker per disk/lane and a 256-iteration spin/yield keep-alive before
  exiting spawn_blocking, preventing Tokio BlockingPool shared.idle futex
  wake/wait thrashing between back-to-back stages of PUT and DELETE.
- Route fsync_dir, fsync_dir_with_owner, and namespace file-sync barriers
  through the per-disk Fsync lane on FSYNC_RUNTIME, and replace LocalDisk's
  duplicate MetadataReadQueue with LocalDisk::run_metadata_read backed by
  self.blocking_queue.
- Route write_all_internal(Owned), open_file(O_TRUNC), remove_file_with_owner,
  and remove_dir_with_owner through DiskBlockingQueue with pre-execution
  cancellation checks.
- Coalesce DELETE directory scans in commit_reserved_version_delete and
  finish_version_delete into single blocking passes with periodic cancellation
  polling, batch rollback file writes in write_delete_rollback_files, batch
  rollback unlinks + directory fsync in remove_files_and_fsync_with_owner, and
  coalesce post-rename directory fsyncs in activate_delete_preparation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d85aaf47-2a4b-4c2c-97a3-dbe8c7717e2a

* perf(ecstore): isolate durable work and reduce idle queue locking

Route coalesced writes and delete settlement through the fsync lane while preserving namespace leases, cancellation ownership, and durability ordering. Keep relaxed work on the foreground lane and replace idle mutex polling with an advisory atomic hint; dequeue and worker retirement remain mutex-protected.

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

* fix(ecstore): yield disk workers across shared blocking pools

Limit each draining task to 64 completed jobs and reuse the worker guard to reschedule remaining work behind other disks. Preserve per-disk FIFO, worker limits, and per-operation ownership. Add a deterministic two-disk regression with one blocking thread.

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

* fix(ecstore): release queued jobs when workers cannot start

Construct the worker guard before submission and track whether execution began. Release pending jobs outside the lane mutex when the last worker is rejected, so waiters, resource units, and self-owning namespace leases cannot remain stranded. Cover closed runtimes and shutdown during batch handoff.

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

* test(connect): synchronize restart with observed inventory

Wait for the received POST instead of treating transport backoff as proof of delivery. Inject a pre-HTTP connection drop and use a verified loopback IP fixture without changing timeout or replay assertions.

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

* refactor(ecstore): unify disk worker lifecycle and drain loop

Represent submitted, running, and retired workers explicitly. Share dequeue, execution, idle recheck, and retirement in one loop while preserving bounded handoff and rejected-task ownership cleanup.

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

* test(storage): separate real I/O from paused-clock assertions

Complete durable fixtures before pausing virtual time, drive the immediate scanner tick before freezing time during filesystem waits, and keep checkpoint-backed retry accounting on a real clock. Preserve default fsync isolation, disk deadlines, retry counts, and all outcome assertions.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Hauser <housemecn@gmail.com>
Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Copilot-Session: d85aaf47-2a4b-4c2c-97a3-dbe8c7717e2a
2026-10-25 14:22:27 +08:00
Hauser 017b85a5bf fix(ecstore): preserve inactive multipart abort authority (#8920)
Retain per-disk recovery metadata through partial publication and require write-quorum proof for completion replay. Keep completed uploads terminal and strengthen RPC recovery acceptance.

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-25 14:05:19 +08:00
overtrue 2924e37351 fix(storage): retain resources through direct writer I/O 2026-10-25 14:04:56 +08:00
overtrue cedaa66673 fix(storage): retain resources during native format probes 2026-10-25 13:30:07 +08:00
overtrue 723e6fa58e feat(heal): admit physical resources before object repair 2026-10-25 13:04:18 +08:00
overtrue 058699c57a feat(storage): admit auxiliary physical resources without waiting 2026-10-25 12:35:48 +08:00
overtrue 1c7d0d057e fix(storage): retain only native disk resource subsets 2026-10-25 12:12:41 +08:00
Chris An 55023ecd86 fix(rebalance): move a version a delete-all expiry would apply inline (#8917)
A delete-all lifecycle expiry is a prefix delete that takes the bucket
lifecycle write lock, while the rebalance entry holds that lock for read
through the inline apply and its bucket incarnation fence. The write
waited out the lock timeout, stalled every lifecycle read in the bucket,
and failed the entry on every retry.

Like decommission (#8777), rebalance now moves such a version live and
lifecycle expires it on the target.

Refs rustfs/backlog#2873
2026-10-25 11:41:31 +08:00
overtrue 23c62f5dd7 feat(scanner): share physical topology across disk plans 2026-10-25 11:19:36 +08:00
overtrue 95f21f0267 feat(concurrency): combine preallocated resource selections 2026-10-25 11:19:36 +08:00
overtrue 49eb74f209 feat(scanner): gate background reads by physical device 2026-10-25 11:19:31 +08:00
overtrue d954886cef feat(concurrency): acquire physical groups before node work 2026-10-25 11:19:31 +08:00
overtrue 1fd619992f fix(scanner): retain resource ownership in native filesystem jobs 2026-10-25 11:19:31 +08:00
overtrue 7947978a45 feat(concurrency): retain bounded physical resource subsets 2026-10-25 11:19:31 +08:00
overtrue b2006b78e3 fix(concurrency): declare Tokio time dependency 2026-10-25 11:19:24 +08:00
overtrue 1123029eda test(scanner): attest adaptive admission in process receipts 2026-10-25 11:19:24 +08:00
overtrue 529b440f67 fix(scanner): yield cache leases for shared node admission 2026-10-25 11:19:24 +08:00
overtrue 4ed33f68a8 fix(scanner): drain candidates after listing completion 2026-10-25 11:19:24 +08:00
overtrue 28fbe69909 feat(scanner): share node admission with background heal 2026-10-25 11:19:24 +08:00
Chris An 1cd62c4249 fix(listing): make page exhaustion explicit, carry limit stops in-band (#8908)
The listing pipeline signalled "this page exhausted the namespace" by
setting `MetaCacheEntriesSortedResult.err = Some(Error::Unexpected)` and
had every consumer filter that variant, so any future `Unexpected` on the
producer path would have been read as a complete listing. A second truth
source, the shared `producer_limit_reached` atomic, was last-writer-wins
across the disks of a page and was never serialized to remote peers.

Collectors now return `ListPage { entries, exhausted }`, errors surface as
errors, and the early empty-listing exits return an exhausted empty page.
The producer's stop reason travels in the metacache stream itself:
`MetacacheWriter::close_with_limit_reached` appends it after the `false`
terminator as repeated terminator markers (the only trailing bytes a
deployed reader tolerates, because `list_path_raw_inner` keeps polling
readers after EOF), `MetacacheReader::limit_reached` decodes it, and
`list_path_raw_inner` folds every reader's trailer into a
`ListPathRawOutcome` that reaches the collector. Remote disks therefore
report their per-disk limit stops as well, and the `producer_limit_reached`
fields on `WalkDirOptions`, `ListPathRawOptions` and `ListPathOptions` are
removed.
2026-10-25 11:07:32 +08:00
Hauser 0f24511535 test(e2e): harden multipart fault and TLS acceptance (#8907)
* test(e2e): tighten scoped multipart fault acceptance

Target Abort root deletion instead of child transaction cleanup, require
actual metadata peer hits, and keep faulted APIs single-attempt. Validate
bounded ordinary recovery and safe quorum refusal for partial mutations,
with the recovery enhancement tracked in backlog#2940.

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

* fix(e2e): drive concurrent TLS reads independently

Give each coordinator its own supervised task and cooperative polling
budget while retaining the existing workload, deadline and byte/hash
assertions. Preserve node logs after fixture teardown and report the
operation, response phase and received bytes when a transfer times out.

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

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-25 04:54:35 +08:00
Hauser 9517db6cf7 fix(listing): honor per-object quorum with borrowed metadata (#8901)
* fix(listing): honor persisted erasure quorum

Separate metadata admission and primary-reader sizing from each version's
persisted erasure requirements. Propagate agreed-entry uncertainty and
report LIST read-quorum failures as storage unavailability.

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

* perf(listing): borrow metadata during quorum resolution

Keep validated metadata inspection and agreed-version selection in
filemeta. Resolve independent reader votes through borrowed slots and
retain owned buffers until a filtered result is required.

Preserve fixed-baseline legacy comparisons, cached latest fast paths,
quorum policy, and disk fan-out. Add ownership regressions and paired
release benchmarks for cold and cached version histories.

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

* test(ecstore): remove redundant fallback clone

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

---------

Co-authored-by: heihutu <heihutu@gmail.com>
Co-authored-by: zhi22915 <qiuzgang@gmail.com>
2026-10-25 04:49:31 +08:00