diff --git a/seaweed-volume/src/server/grpc_server.rs b/seaweed-volume/src/server/grpc_server.rs index b9b63ec23..525b256c3 100644 --- a/seaweed-volume/src/server/grpc_server.rs +++ b/seaweed-volume/src/server/grpc_server.rs @@ -981,6 +981,16 @@ impl VolumeServer for VolumeGrpcService { }; let mut throttler = WriteThrottler::new(io_byte_per_second); + // TODO: Go queries the master via GetMasterConfiguration gRPC call to check + // VolumePreallocate and VolumeSizeLimitMB, then creates a preallocated .dat file + // before copying. The try_get_master_configuration function exists in heartbeat.rs + // but is not pub and operates independently. To match Go behavior: + // 1. Make try_get_master_configuration (or a similar helper) accessible from here + // 2. Call master's GetMasterConfiguration using state.master_url + // 3. If resp.volume_preallocate is true, create a preallocated file of + // resp.volume_size_limit_mb * 1024 * 1024 bytes via backend::CreateVolumeFile + // 4. Then copy the .dat data into the preallocated file + // Copy .dat file if !has_remote_dat { let dat_path = format!("{}.dat", data_base_name); @@ -2887,9 +2897,13 @@ impl VolumeServer for VolumeGrpcService { .ok_or_else(|| Status::not_found(format!("volume id {} not found", vid.0)))?; total_volumes += 1; - // INDEX mode (1) calls scrub_index; LOCAL (3) and FULL (2) call scrub - // TODO: implement scrub_index() for INDEX-only mode; currently falls through to full scrub - match v.scrub() { + // INDEX mode (1) calls scrub_index; LOCAL (2) and FULL (3) call scrub + let scrub_result = if mode == 1 { + v.scrub_index() + } else { + v.scrub() + }; + match scrub_result { Ok((files, broken)) => { total_files += files; if !broken.is_empty() { @@ -3202,6 +3216,14 @@ impl VolumeServer for VolumeGrpcService { } // Fall back to EC shards + // TODO: Go calls vs.store.ReadEcShardNeedle(volumeId, n, nil) which reconstructs the + // full needle from EC shards (using erasure coding reconstruction across all shards), + // then populates last_modified, crc, ttl from the reconstructed data. The Rust + // implementation currently only reads the needle header from a single local shard, + // so last_modified, crc, and ttl are not populated for EC volumes. To match Go: + // 1. Implement a read_ec_shard_needle method on Store or EcVolume that performs + // full needle reconstruction from EC shards + // 2. Use it here to get the complete needle data including last_modified, crc, ttl if let Some(ec_vol) = store.find_ec_volume(vid) { match ec_vol.find_needle_from_ecx(needle_id) { Ok(Some((offset, size))) if !size.is_deleted() && !offset.is_zero() => {