From a3b177370a58d0acc18f6098ea18006723795a92 Mon Sep 17 00:00:00 2001 From: Rishabh Patel Date: Fri, 24 Apr 2026 16:52:09 -0700 Subject: [PATCH 1/2] HDDS-15112. Handle negative space usage values gracefully in `CachingSpaceUsageSource`. --- .../hadoop/hdds/fs/CachingSpaceUsageSource.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java index 27e6f7d4144..9cd192287cd 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java @@ -120,7 +120,11 @@ public void incrementUsedSpace(long usedSpace) { if (usedSpace == 0) { return; } - Preconditions.assertTrue(usedSpace > 0, () -> usedSpace + " < 0"); + if (usedSpace < 0) { + LOG.warn("Ignoring negative incrementUsedSpace({}) for {}", usedSpace, source); + return; + } + final long current, change; try (AutoCloseableLock ignored = lock.writeLock(null, null)) { current = cachedAvailable; @@ -140,7 +144,11 @@ public void decrementUsedSpace(long reclaimedSpace) { if (reclaimedSpace == 0) { return; } - Preconditions.assertTrue(reclaimedSpace > 0, () -> reclaimedSpace + " < 0"); + if (reclaimedSpace < 0) { + LOG.warn("Ignoring negative reclaimedSpace({}) for {}", reclaimedSpace, source); + return; + } + final long current, change; try (AutoCloseableLock ignored = lock.writeLock(null, null)) { current = cachedUsedSpace; From cb71f046237eac164acd9fc2f05609c1358277f9 Mon Sep 17 00:00:00 2001 From: Rishabh Patel Date: Tue, 28 Apr 2026 10:53:52 -0700 Subject: [PATCH 2/2] HDDS-15112. Add tests to validate handling of negative space usage values in `CachingSpaceUsageSource`. --- .../hdds/fs/TestCachingSpaceUsageSource.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java index db0a2c89c9e..f6b79830ceb 100644 --- a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java +++ b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java @@ -182,6 +182,41 @@ void decrementAvailableSpaceMoreThanCurrent() { assertSnapshotIsUpToDate(subject); } + // If negative values are passed, check that the state is unchanged + @Test + void incrementUsedSpaceIgnoresNegativeValue() { + SpaceUsageCheckParams params = paramsBuilder(new AtomicLong(50)) + .withRefresh(Duration.ZERO) + .build(); + CachingSpaceUsageSource subject = new CachingSpaceUsageSource(params); + SpaceUsageSource original = subject.snapshot(); + + subject.incrementUsedSpace(-1L); + + // negative value should be ignored, leaving cached state unchanged + assertEquals(original.getUsedSpace(), subject.getUsedSpace()); + assertEquals(original.getAvailable(), subject.getAvailable()); + assertEquals(original.getCapacity(), subject.getCapacity()); + assertSnapshotIsUpToDate(subject); + } + + @Test + void decrementUsedSpaceIgnoresNegativeValue() { + SpaceUsageCheckParams params = paramsBuilder(new AtomicLong(50)) + .withRefresh(Duration.ZERO) + .build(); + CachingSpaceUsageSource subject = new CachingSpaceUsageSource(params); + SpaceUsageSource original = subject.snapshot(); + + subject.decrementUsedSpace(-1L); + + // negative value should be ignored, leaving cached state unchanged + assertEquals(original.getUsedSpace(), subject.getUsedSpace()); + assertEquals(original.getAvailable(), subject.getAvailable()); + assertEquals(original.getCapacity(), subject.getCapacity()); + assertSnapshotIsUpToDate(subject); + } + private static void assertSnapshotIsUpToDate(SpaceUsageSource subject) { SpaceUsageSource snapshot = subject.snapshot(); assertEquals(subject.getCapacity(), snapshot.getCapacity());