diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java index 6f776072d9c3..b9a2f87a03da 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/fs/CachingSpaceUsageSource.java @@ -94,7 +94,19 @@ public void incrementUsedSpace(long usedSpace) { } public void decrementUsedSpace(long reclaimedSpace) { - cachedValue.addAndGet(-1 * reclaimedSpace); + cachedValue.updateAndGet(current -> { + long newValue = current - reclaimedSpace; + if (newValue < 0) { + if (current > 0) { + LOG.warn("Attempted to decrement used space to a negative value. " + + "Current: {}, Decrement: {}, Source: {}", + current, reclaimedSpace, source); + } + return 0; + } else { + return newValue; + } + }); } public void start() { diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java index 674c1233dee6..8523861000e7 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/fs/TestCachingSpaceUsageSource.java @@ -142,6 +142,20 @@ public void savesValueOnShutdown() { verify(executor).shutdown(); } + @Test + public void testDecrementDoesNotGoNegative() { + SpaceUsageCheckParams params = paramsBuilder(new AtomicLong(50)) + .withRefresh(Duration.ZERO) + .build(); + CachingSpaceUsageSource subject = new CachingSpaceUsageSource(params); + + // Try to decrement more than the current value + subject.decrementUsedSpace(100); + + // Check that the value has been set to 0 + assertEquals(0, subject.getUsedSpace()); + } + private static long missingInitialValue() { return 0L; }