diff --git a/seaweed-volume/src/server/heartbeat.rs b/seaweed-volume/src/server/heartbeat.rs index fc95c6964b..e66999a5e4 100644 --- a/seaweed-volume/src/server/heartbeat.rs +++ b/seaweed-volume/src/server/heartbeat.rs @@ -1365,6 +1365,7 @@ fn build_heartbeat_with_ec_status( } let (remote_storage_name, remote_storage_key) = vol.remote_storage_name_key(); + let (read_only, read_only_can_delete) = vol.reported_read_only(); let volume_message = master_pb::VolumeInformationMessage { id: vol.id.0, size: volume_size, @@ -1372,8 +1373,8 @@ fn build_heartbeat_with_ec_status( file_count: vol.file_count() as u64, delete_count: vol.deleted_count() as u64, deleted_byte_count: vol.deleted_size(), - read_only: vol.is_read_only(), - read_only_can_delete: vol.is_no_write_can_delete(), + read_only, + read_only_can_delete, replica_placement: vol.super_block().replica_placement.to_byte() as u32, version: vol.super_block().version.0 as u32, ttl: vol.super_block().ttl.to_u32(), @@ -1819,6 +1820,43 @@ mod tests { ); } + #[test] + fn test_build_heartbeat_low_disk_volume_reports_can_delete() { + let temp_dir = tempfile::tempdir().unwrap(); + let dir = temp_dir.path().to_str().unwrap(); + + let mut store = Store::new(NeedleMapKind::InMemory); + store + .add_location( + dir, + dir, + 3, + DiskType::HardDrive, + MinFreeSpace::Percent(1.0), + vec![], + ) + .unwrap(); + store + .add_volume(VolumeId(7), DiskType::HardDrive, &VolumeSpec::default()) + .unwrap(); + store.locations[0] + .is_disk_space_low + .store(true, std::sync::atomic::Ordering::Relaxed); + + let heartbeat = build_heartbeat(&test_config(), &mut store); + assert!(heartbeat.volumes[0].read_only); + assert!(heartbeat.volumes[0].read_only_can_delete); + + store + .find_volume(VolumeId(7)) + .unwrap() + .1 + .set_no_write_or_delete(true); + let heartbeat = build_heartbeat(&test_config(), &mut store); + assert!(heartbeat.volumes[0].read_only); + assert!(!heartbeat.volumes[0].read_only_can_delete); + } + #[test] fn test_build_heartbeat_marks_empty_store_as_has_no_volumes() { let temp_dir = tempfile::tempdir().unwrap(); diff --git a/seaweed-volume/src/storage/volume.rs b/seaweed-volume/src/storage/volume.rs index 8fc3b7214a..369eb44e75 100644 --- a/seaweed-volume/src/storage/volume.rs +++ b/seaweed-volume/src/storage/volume.rs @@ -3490,6 +3490,13 @@ impl Volume { self.no_write_flags().1 } + /// What the master is told: low disk space still lets deletes through, + /// only no_write_or_delete refuses them. Mirrors Go's reportedReadOnly. + pub fn reported_read_only(&self) -> (bool, bool) { + let (read_only, no_write_or_delete, _, _) = self.read_only_reasons(); + (read_only, read_only && !no_write_or_delete) + } + pub fn last_compact_revision(&self) -> u16 { self.io.read().unwrap().last_compact_revision }