This is an automated email from the ASF dual-hosted git repository.

arafat2198 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 926da32c0d0 HDDS-14552. [Recon] Improve Ozone Capacity Reporting with 
Reserved Space and FS Capacity Breakdown (#9742)
926da32c0d0 is described below

commit 926da32c0d0b336c639967e6daf90d42ea90f974
Author: Priyesh Karatha <[email protected]>
AuthorDate: Sat Feb 28 16:39:44 2026 +0530

    HDDS-14552. [Recon] Improve Ozone Capacity Reporting with Reserved Space 
and FS Capacity Breakdown (#9742)
---
 .../recon/TestStorageDistributionEndpoint.java     |  23 +++
 .../recon/api/StorageDistributionEndpoint.java     |  22 +--
 .../ozone/recon/api/types/GlobalStorageReport.java | 182 ++++++++++++++++++---
 .../ozone/recon/api/types/UsedSpaceBreakDown.java  |  10 +-
 .../webapps/recon/ozone-recon-web/api/db.json      |  12 +-
 .../mocks/capacityMocks/capacityResponseMocks.ts   |  12 +-
 .../src/v2/constants/capacity.constants.tsx        |  13 +-
 .../src/v2/pages/capacity/capacity.less            |   8 +
 .../src/v2/pages/capacity/capacity.tsx             |  53 ++++--
 .../ozone-recon-web/src/v2/types/capacity.types.ts |  11 +-
 .../recon/api/TestStorageDistributionEndpoint.java |   8 +-
 11 files changed, 274 insertions(+), 80 deletions(-)

diff --git 
a/hadoop-ozone/integration-test-recon/src/test/java/org/apache/hadoop/ozone/recon/TestStorageDistributionEndpoint.java
 
b/hadoop-ozone/integration-test-recon/src/test/java/org/apache/hadoop/ozone/recon/TestStorageDistributionEndpoint.java
index 2a3ca2bb91a..983dbf178e8 100644
--- 
a/hadoop-ozone/integration-test-recon/src/test/java/org/apache/hadoop/ozone/recon/TestStorageDistributionEndpoint.java
+++ 
b/hadoop-ozone/integration-test-recon/src/test/java/org/apache/hadoop/ozone/recon/TestStorageDistributionEndpoint.java
@@ -257,6 +257,15 @@ private boolean 
verifyStorageDistributionAfterKeyCreation() {
       List<DatanodeStorageReport> reports = storageResponse.getDataNodeUsage();
       List<HddsProtos.DatanodeUsageInfoProto> scmReports =
           scm.getClientProtocolServer().getDatanodeUsageInfo(true, 3, 1);
+
+      long totalReserved = 0;
+      long totalMinFreeSpace = 0;
+      long totalPreAllocated = 0;
+      long totalFileSystemCapacity = 0;
+      long totalOzoneCapacity = 0;
+      long totalOzoneUsedSpace = 0;
+      long totalRemaining = 0;
+
       for (DatanodeStorageReport report : reports) {
         for (HddsProtos.DatanodeUsageInfoProto scmReport : scmReports) {
           if (scmReport.getNode().getUuid().equals(report.getDatanodeUuid())) {
@@ -268,9 +277,23 @@ private boolean 
verifyStorageDistributionAfterKeyCreation() {
             assertEquals(scmReport.getCommitted(), report.getCommitted());
             assertEquals(scmReport.getFsAvailable(), 
report.getFilesystemAvailable());
             assertEquals(scmReport.getFsCapacity(), 
report.getFilesystemCapacity());
+            totalReserved += scmReport.getReserved();
+            totalMinFreeSpace += scmReport.getFreeSpaceToSpare();
+            totalPreAllocated += scmReport.getCommitted();
+            totalFileSystemCapacity += scmReport.getFsCapacity();
+            totalOzoneCapacity += scmReport.getCapacity();
+            totalOzoneUsedSpace += scmReport.getUsed();
+            totalRemaining += scmReport.getRemaining();
           }
         }
       }
+      assertEquals(totalReserved, 
storageResponse.getGlobalStorage().getTotalReservedSpace());
+      assertEquals(totalMinFreeSpace, 
storageResponse.getGlobalStorage().getTotalMinimumFreeSpace());
+      assertEquals(totalPreAllocated, 
storageResponse.getGlobalStorage().getTotalOzonePreAllocatedContainerSpace());
+      assertEquals(totalOzoneCapacity, 
storageResponse.getGlobalStorage().getTotalOzoneCapacity());
+      assertEquals(totalOzoneUsedSpace, 
storageResponse.getGlobalStorage().getTotalOzoneUsedSpace());
+      assertEquals(totalFileSystemCapacity, 
storageResponse.getGlobalStorage().getTotalFileSystemCapacity());
+      assertEquals(totalRemaining, 
storageResponse.getGlobalStorage().getTotalOzoneFreeSpace());
       return true;
     } catch (Exception e) {
       LOG.debug("Waiting for storage distribution assertions to pass", e);
diff --git 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/StorageDistributionEndpoint.java
 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/StorageDistributionEndpoint.java
index 2cfc64dd68a..34b21167f91 100644
--- 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/StorageDistributionEndpoint.java
+++ 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/StorageDistributionEndpoint.java
@@ -222,21 +222,26 @@ public Response downloadDataNodeStorageDistribution() {
   }
 
   private GlobalStorageReport calculateGlobalStorageReport() {
+    GlobalStorageReport.Builder globalStorageBuilder = 
GlobalStorageReport.newBuilder();
     try {
       SCMNodeStat stats = nodeManager.getStats();
       if (stats == null) {
         LOG.warn("Node manager stats are null, returning default values");
-        return new GlobalStorageReport(0L, 0L, 0L);
+        return globalStorageBuilder.build();
       }
 
-      long scmUsed = stats.getScmUsed() != null ? stats.getScmUsed().get() : 
0L;
-      long remaining = stats.getRemaining() != null ? 
stats.getRemaining().get() : 0L;
-      long capacity = stats.getCapacity() != null ? stats.getCapacity().get() 
: 0L;
+      return globalStorageBuilder
+          .setTotalOzoneCapacity(stats.getCapacity() != null ? 
stats.getCapacity().get() : 0L)
+          .setTotalReservedSpace(stats.getReserved() != null ? 
stats.getReserved().get() : 0L)
+          .setTotalOzoneFreeSpace(stats.getRemaining() != null ? 
stats.getRemaining().get() : 0L)
+          .setTotalOzoneUsedSpace(stats.getScmUsed() != null ? 
stats.getScmUsed().get() : 0L)
+          .setTotalOzonePreAllocatedContainerSpace(stats.getCommitted() != 
null ? stats.getCommitted().get() : 0L)
+          .setTotalMinimumFreeSpace(stats.getFreeSpaceToSpare() != null ? 
stats.getFreeSpaceToSpare().get() : 0L)
+          .build();
 
-      return new GlobalStorageReport(scmUsed, remaining, capacity);
     } catch (Exception e) {
       LOG.error("Error calculating global storage report", e);
-      return new GlobalStorageReport(0L, 0L, 0L);
+      return globalStorageBuilder.build();
     }
   }
 
@@ -278,9 +283,6 @@ private StorageCapacityDistributionResponse 
buildStorageDistributionResponse(
     Long totalUsedNamespace = namespaceMetrics.get("totalUsedNamespace");
     Long totalCommittedSize = namespaceMetrics.get("totalCommittedSize");
     Long totalKeys = namespaceMetrics.get("totalKeys");
-    Long totalContainerPreAllocated = nodeStorageReports.stream()
-        .map(DatanodeStorageReport::getCommitted)
-        .reduce(0L, Long::sum);
 
     return StorageCapacityDistributionResponse.newBuilder()
             .setDataNodeUsage(nodeStorageReports)
@@ -289,7 +291,7 @@ private StorageCapacityDistributionResponse 
buildStorageDistributionResponse(
                     totalUsedNamespace != null ? totalUsedNamespace : 0L,
                     totalKeys != null ? totalKeys : 0L))
             .setUsedSpaceBreakDown(new UsedSpaceBreakDown(
-                    totalOpenKeySize, totalCommittedSize != null ? 
totalCommittedSize : 0L, totalContainerPreAllocated))
+                    totalOpenKeySize, totalCommittedSize != null ? 
totalCommittedSize : 0L))
             .build();
   }
 
diff --git 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/GlobalStorageReport.java
 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/GlobalStorageReport.java
index 7be066ef15f..35311847606 100644
--- 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/GlobalStorageReport.java
+++ 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/GlobalStorageReport.java
@@ -22,40 +22,180 @@
 /**
  * Represents a report detailing global storage usage metrics.
  *
- * This class provides information about the total used space,
- * total free space, and the total storage capacity. It is used
- * to encapsulate and transport these metrics, which can assist
- * in monitoring and analyzing storage allocation and usage.
+ * <p>This class encapsulates aggregated storage metrics across the cluster
+ * and defines the relationship between filesystem capacity, reserved space,
+ * and Ozone-managed storage.</p>
+ *
+ * <h3>Storage Hierarchy</h3>
+ *
+ * <pre>
+ * {@code
+ * Global Storage Layout
+ *
+ * |<------------------------ totalFileSystemCapacity 
------------------------->|
+ * |<-- totalReservedSpace -->|<----------- totalOzoneCapacity 
---------------->|
+ *                            |<-totalOzoneUsedSpace->|<- totalOzoneFreeSpace 
->|
+ *
+ *
+ * Relationships:
+ *
+ * totalFileSystemCapacity = totalOzoneCapacity + totalReservedSpace
+ *
+ * totalOzoneCapacity = totalOzoneUsedSpace + totalOzoneFreeSpace
+ * }
+ * </pre>
+ *
+ * <h3>Metric Definitions</h3>
+ *
+ * <ul>
+ *   <li><b>totalFileSystemCapacity</b>:
+ *       Total OS-reported filesystem capacity across all datanodes.</li>
+ *
+ *   <li><b>totalReservedSpace</b>:
+ *       Space reserved and not available for Ozone allocation.</li>
+ *
+ *   <li><b>totalOzoneCapacity</b>:
+ *       Portion of filesystem capacity available for Ozone
+ *       (i.e., filesystem capacity minus reserved space).</li>
+ *
+ *   <li><b>totalOzoneUsedSpace</b>:
+ *       Space currently consumed by Ozone data.</li>
+ *
+ *   <li><b>totalOzoneFreeSpace</b>:
+ *       Remaining allocatable space within Ozone capacity.</li>
+ *
+ *   <li><b>totalOzonePreAllocatedContainerSpace</b>:
+ *       Space pre-allocated for containers but not yet fully utilized.</li>
+ *
+ *   <li><b>totalMinimumFreeSpace</b>:
+ *       Minimum free space that must be maintained as per configuration.</li>
+ * </ul>
+ *
+ * <p>This differentiation helps in understanding how raw filesystem capacity
+ * is divided between reserved space and Ozone-managed space, and further how
+ * Ozone capacity is split between used and free storage.</p>
  */
 public class GlobalStorageReport {
 
-  @JsonProperty("totalUsedSpace")
-  private long totalUsedSpace;
+  @JsonProperty("totalFileSystemCapacity")
+  private long totalFileSystemCapacity;
 
-  @JsonProperty("totalFreeSpace")
-  private long totalFreeSpace;
+  @JsonProperty("totalReservedSpace")
+  private long totalReservedSpace;
 
-  @JsonProperty("totalCapacity")
-  private long totalCapacity;
+  @JsonProperty("totalOzoneCapacity")
+  private long totalOzoneCapacity;
 
-  public GlobalStorageReport() {
+  @JsonProperty("totalOzoneUsedSpace")
+  private long totalOzoneUsedSpace;
+
+  @JsonProperty("totalOzoneFreeSpace")
+  private long totalOzoneFreeSpace;
+
+  @JsonProperty("totalOzonePreAllocatedContainerSpace")
+  private long totalOzonePreAllocatedContainerSpace;
+
+  @JsonProperty("totalMinimumFreeSpace")
+  private long totalMinimumFreeSpace;
+
+  public long getTotalFileSystemCapacity() {
+    return totalFileSystemCapacity;
   }
 
-  public GlobalStorageReport(long totalUsedSpace, long totalFreeSpace, long 
totalCapacity) {
-    this.totalUsedSpace = totalUsedSpace;
-    this.totalFreeSpace = totalFreeSpace;
-    this.totalCapacity = totalCapacity;
+  public long getTotalReservedSpace() {
+    return totalReservedSpace;
   }
 
-  public long getTotalUsedSpace() {
-    return totalUsedSpace;
+  public long getTotalOzoneCapacity() {
+    return totalOzoneCapacity;
   }
 
-  public long getTotalFreeSpace() {
-    return totalFreeSpace;
+  public long getTotalOzoneUsedSpace() {
+    return totalOzoneUsedSpace;
   }
 
-  public long getTotalCapacity() {
-    return totalCapacity;
+  public long getTotalOzoneFreeSpace() {
+    return totalOzoneFreeSpace;
+  }
+
+  public long getTotalOzonePreAllocatedContainerSpace() {
+    return totalOzonePreAllocatedContainerSpace;
+  }
+
+  public long getTotalMinimumFreeSpace() {
+    return totalMinimumFreeSpace;
+  }
+
+  public GlobalStorageReport() {
+  }
+
+  public GlobalStorageReport(Builder builder) {
+    this.totalFileSystemCapacity = builder.totalReservedSpace + 
builder.totalOzoneCapacity;
+    this.totalReservedSpace = builder.totalReservedSpace;
+    this.totalOzoneCapacity = builder.totalOzoneCapacity;
+    this.totalOzoneUsedSpace = builder.totalOzoneUsedSpace;
+    this.totalOzoneFreeSpace = builder.totalOzoneFreeSpace;
+    this.totalOzonePreAllocatedContainerSpace = 
builder.totalOzonePreAllocatedContainerSpace;
+    this.totalMinimumFreeSpace = builder.totalMinimumFreeSpace;
+  }
+
+  public static Builder newBuilder() {
+    return new Builder();
+  }
+
+  /**
+   * Builder class for creating an instance of GlobalStorageReport.
+   * Provides a fluent interface to set various storage parameters.
+   */
+  public static final class Builder {
+    private long totalReservedSpace;
+    private long totalOzoneCapacity;
+    private long totalOzoneUsedSpace;
+    private long totalOzoneFreeSpace;
+    private long totalOzonePreAllocatedContainerSpace;
+    private long totalMinimumFreeSpace;
+
+    public Builder() {
+      totalReservedSpace = 0;
+      totalOzoneCapacity = 0;
+      totalOzoneUsedSpace = 0;
+      totalOzoneFreeSpace = 0;
+      totalOzonePreAllocatedContainerSpace = 0;
+      totalMinimumFreeSpace = 0;
+    }
+
+    public Builder setTotalReservedSpace(long totalReservedSpace) {
+      this.totalReservedSpace = totalReservedSpace;
+      return this;
+    }
+
+    public Builder setTotalOzoneCapacity(long totalOzoneCapacity) {
+      this.totalOzoneCapacity = totalOzoneCapacity;
+      return this;
+    }
+
+    public Builder setTotalOzoneUsedSpace(long totalOzoneUsedSpace) {
+      this.totalOzoneUsedSpace = totalOzoneUsedSpace;
+      return this;
+    }
+
+    public Builder setTotalOzoneFreeSpace(long totalOzoneFreeSpace) {
+      this.totalOzoneFreeSpace = totalOzoneFreeSpace;
+      return this;
+    }
+
+    public Builder setTotalOzonePreAllocatedContainerSpace(long 
totalOzonePreAllocatedContainerSpace) {
+      this.totalOzonePreAllocatedContainerSpace = 
totalOzonePreAllocatedContainerSpace;
+      return this;
+    }
+
+    public Builder setTotalMinimumFreeSpace(long totalMinimumFreeSpace) {
+      this.totalMinimumFreeSpace = totalMinimumFreeSpace;
+      return this;
+    }
+
+    public GlobalStorageReport build() {
+      return new GlobalStorageReport(this);
+    }
   }
 }
diff --git 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/UsedSpaceBreakDown.java
 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/UsedSpaceBreakDown.java
index c7c6d2aa7f8..a72117598aa 100644
--- 
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/UsedSpaceBreakDown.java
+++ 
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/types/UsedSpaceBreakDown.java
@@ -50,16 +50,12 @@ public class UsedSpaceBreakDown {
   @JsonProperty("committedKeyBytes")
   private long committedKeyBytes;
 
-  @JsonProperty("preAllocatedContainerBytes")
-  private long preAllocatedContainerBytes;
-
   public UsedSpaceBreakDown() {
   }
 
-  public UsedSpaceBreakDown(OpenKeyBytesInfo openKeyBytes, long 
committedKeyBytes, long preAllocatedContainerBytes) {
+  public UsedSpaceBreakDown(OpenKeyBytesInfo openKeyBytes, long 
committedKeyBytes) {
     this.openKeyBytes = openKeyBytes;
     this.committedKeyBytes = committedKeyBytes;
-    this.preAllocatedContainerBytes = preAllocatedContainerBytes;
   }
 
   public OpenKeyBytesInfo getOpenKeyBytes() {
@@ -69,8 +65,4 @@ public OpenKeyBytesInfo getOpenKeyBytes() {
   public long getCommittedKeyBytes() {
     return committedKeyBytes;
   }
-
-  public long getPreAllocatedContainerBytes() {
-    return preAllocatedContainerBytes;
-  }
 }
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
index 7b1bf48bf32..c586f662ed8 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/api/db.json
@@ -6869,9 +6869,12 @@
   },
   "utilization": {
     "globalStorage": {
-        "totalUsedSpace": 30679040,
-        "totalFreeSpace": 539776978944,
-        "totalCapacity": 879519597390
+      "totalFileSystemCapacity": 879788032846,
+      "totalReservedSpace": 268435456,
+      "totalOzoneCapacity": 879519597390,
+      "totalOzoneFreeSpace": 539776978944,
+      "totalOzoneUsedSpace": 30679040,
+      "totalOzonePreAllocatedContainerSpace":1022024
     },
     "globalNamespace": {
         "totalUsedSpace": 12349932,
@@ -6883,8 +6886,7 @@
           "openKeyAndFileBytes": 19255266,
           "multipartOpenKeyBytes": 0
         },
-        "committedKeyBytes": 1249923,
-        "preAllocatedContainerBytes": 1022024
+        "committedKeyBytes": 1249923
     },
     "dataNodeUsage": [
         {
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/__tests__/mocks/capacityMocks/capacityResponseMocks.ts
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/__tests__/mocks/capacityMocks/capacityResponseMocks.ts
index 2459fdbd69e..807fefdc5d5 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/__tests__/mocks/capacityMocks/capacityResponseMocks.ts
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/__tests__/mocks/capacityMocks/capacityResponseMocks.ts
@@ -18,9 +18,12 @@
 
 export const StorageDistribution = {
   globalStorage: {
-    totalUsedSpace: 4096,
-    totalFreeSpace: 4096,
-    totalCapacity: 10240
+    totalFileSystemCapacity: 11264,
+    totalOzoneUsedSpace: 4096,
+    totalOzoneFreeSpace: 4096,
+    totalOzoneCapacity: 10240,
+    totalReservedSpace: 1024,
+    totalOzonePreAllocatedContainerSpace: 1024
   },
   globalNamespace: {
     totalUsedSpace: 4096,
@@ -32,8 +35,7 @@ export const StorageDistribution = {
       openKeyAndFileBytes: 512,
       multipartOpenKeyBytes: 512
     },
-    committedKeyBytes: 2048,
-    preAllocatedContainerBytes: 1024
+    committedKeyBytes: 2048
   },
   dataNodeUsage: [
     {
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/constants/capacity.constants.tsx
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/constants/capacity.constants.tsx
index 3f51c0879c5..b07c384b8b0 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/constants/capacity.constants.tsx
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/constants/capacity.constants.tsx
@@ -20,9 +20,13 @@ import { UtilizationResponse, SCMPendingDeletion, 
OMPendingDeletion, DNPendingDe
 
 export const DEFAULT_CAPACITY_UTILIZATION: UtilizationResponse = {
   globalStorage: {
-    totalUsedSpace: 0,
-    totalFreeSpace: 0,
-    totalCapacity: 0
+    totalFileSystemCapacity: 0,
+    totalReservedSpace: 0,
+    totalOzoneCapacity: 0,
+    totalOzoneFreeSpace: 0,
+    totalOzoneUsedSpace: 0,
+    totalOzonePreAllocatedContainerSpace: 0,
+    totalMinimumFreeSpace: 0
   },
   globalNamespace: {
     totalUsedSpace: 0,
@@ -34,8 +38,7 @@ export const DEFAULT_CAPACITY_UTILIZATION: 
UtilizationResponse = {
       openKeyAndFileBytes: 0,
       multipartOpenKeyBytes: 0
     },
-    committedKeyBytes: 0,
-    preAllocatedContainerBytes: 0
+    committedKeyBytes: 0
   },
   dataNodeUsage: []
 };
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.less
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.less
index abe26f953f0..5a1e9b0443f 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.less
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.less
@@ -68,6 +68,14 @@
   }
 }
 
+.capacity-info {
+  width: 300px;
+  white-space: normal;
+  word-wrap: break-word;
+  margin: 5px 0 0 1px;
+  padding: 5px 0 0 1px;
+}
+
 .openkeys-space-breakdown {
   display: grid;
   grid-template-columns: 150px auto;
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.tsx
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.tsx
index d9b5f093eac..23159dec1e9 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.tsx
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.tsx
@@ -29,8 +29,7 @@ import {
   datanodesPendingDeletionDesc,
   nodeSelectorMessage,
   otherUsedSpaceDesc,
-  ozoneUsedSpaceDesc,
-  totalCapacityDesc
+  ozoneUsedSpaceDesc
 } from '@/v2/pages/capacity/constants/descriptions.constants';
 import WrappedInfoIcon from '@/v2/pages/capacity/components/WrappedInfoIcon';
 import filesize from 'filesize';
@@ -253,6 +252,31 @@ const Capacity: React.FC<object> = () => {
     </span>
   );
 
+  const totalCapacityDesc = (
+    <span>
+      TOTAL CAPACITY
+      <Popover
+        title="Capacity Breakdown"
+        placement="topLeft"
+        content={
+            <>
+              <div className='unused-space-breakdown'>
+                File System Capacity
+                <Tag 
color='blue'>{filesize(storageDistribution.data.globalStorage.totalFileSystemCapacity,
 { round: 1 })}</Tag>
+                Reserved Space
+                <Tag 
color='orange'>{filesize(storageDistribution.data.globalStorage.totalReservedSpace,
 { round: 1 })}</Tag>
+              </div>
+              <div className="capacity-info">
+                Ozone Capacity shows how much usable space is available after 
subtracting the reserved space from the file system capacity.
+              </div>
+            </>
+        }
+      >
+        <InfoCircleOutlined style={{ color: '#2f84d8', fontSize: 12, 
marginLeft: 4 }} />
+      </Popover>
+    </span>
+  );
+
   const dnSelectorTitle = (
     <span>
       Node Selector <WrappedInfoIcon title={nodeSelectorMessage} />
@@ -295,16 +319,11 @@ const Capacity: React.FC<object> = () => {
           title='Ozone Capacity'
           loading={storageDistribution.loading}
           items={[{
-            title: (
-              <span>
-                TOTAL
-                <WrappedInfoIcon title={totalCapacityDesc} />
-              </span>
-            ),
-            value: storageDistribution.data.globalStorage.totalCapacity,
+            title: totalCapacityDesc,
+            value: storageDistribution.data.globalStorage.totalOzoneCapacity,
           }, {
-            title: 'OZONE USED SPACE',
-            value: storageDistribution.data.globalStorage.totalUsedSpace,
+            title: 'USED SPACE',
+            value: storageDistribution.data.globalStorage.totalOzoneUsedSpace,
             color: '#f4a233'
           }, {
             title: (
@@ -314,18 +333,18 @@ const Capacity: React.FC<object> = () => {
               </span>
             ),
             value: (
-              storageDistribution.data.globalStorage.totalCapacity
-              - storageDistribution.data.globalStorage.totalFreeSpace
-              - storageDistribution.data.globalStorage.totalUsedSpace
+              storageDistribution.data.globalStorage.totalOzoneCapacity
+              - storageDistribution.data.globalStorage.totalOzoneFreeSpace
+              - storageDistribution.data.globalStorage.totalOzoneUsedSpace
             ),
             color: '#11073a'
           }, {
             title: 'CONTAINER PRE-ALLOCATED',
-            value: 
storageDistribution.data.usedSpaceBreakdown.preAllocatedContainerBytes,
+            value: 
storageDistribution.data.globalStorage.totalOzonePreAllocatedContainerSpace,
             color: '#f47b2d'
           }, {
             title: 'REMAINING SPACE',
-            value: storageDistribution.data.globalStorage.totalFreeSpace,
+            value: storageDistribution.data.globalStorage.totalOzoneFreeSpace,
             color: '#4553ee'
           }]}
         />
@@ -340,7 +359,7 @@ const Capacity: React.FC<object> = () => {
           loading={storageDistribution.loading}
           items={[{
             title: 'TOTAL',
-            value: storageDistribution.data.globalStorage.totalUsedSpace
+            value: storageDistribution.data.globalStorage.totalOzoneUsedSpace
           }, {
             title: openKeyUsageBreakdown,
             value: 
storageDistribution.data.usedSpaceBreakdown.openKeyBytes?.totalOpenKeyBytes ?? 
0,
diff --git 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/capacity.types.ts
 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/capacity.types.ts
index b399b36e8b8..c03f8a6c8b7 100644
--- 
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/capacity.types.ts
+++ 
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/types/capacity.types.ts
@@ -17,9 +17,13 @@
  */
 
 type GlobalStorage = {
-  totalUsedSpace: number;
-  totalFreeSpace: number;
-  totalCapacity: number;
+  totalFileSystemCapacity: number;
+  totalReservedSpace: number;
+  totalOzoneCapacity: number;
+  totalOzoneUsedSpace: number;
+  totalOzoneFreeSpace: number;
+  totalOzonePreAllocatedContainerSpace: number;
+  totalMinimumFreeSpace: number;
 };
 
 type GlobalNamespace = {
@@ -30,7 +34,6 @@ type GlobalNamespace = {
 type UsedSpaceBreakdown = {
   openKeyBytes: OpenKeyBytesInfo;
   committedKeyBytes: number;
-  preAllocatedContainerBytes: number;
 };
 
 type OpenKeyBytesInfo = {
diff --git 
a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestStorageDistributionEndpoint.java
 
b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestStorageDistributionEndpoint.java
index d6a1ab80581..cb514c463a3 100644
--- 
a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestStorageDistributionEndpoint.java
+++ 
b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestStorageDistributionEndpoint.java
@@ -126,9 +126,9 @@ public void testStorageDistributionApiReturnsSuccess() 
throws Exception {
     long totalNameSpace = PENDING_KEY_SIZE + PENDING_DIRECTORY_SIZE + 
OPEN_KEY_BYTES +
         OPEN_MPU_KEY_BYTES + EXPECTED_COMMITTED_KEY_BYTES;
 
-    assertEquals(OZONE_USED * 3, 
distributionResponse.getGlobalStorage().getTotalUsedSpace());
-    assertEquals(OZONE_REMAINING * 3, 
distributionResponse.getGlobalStorage().getTotalFreeSpace());
-    assertEquals(OZONE_CAPACITY * 3, 
distributionResponse.getGlobalStorage().getTotalCapacity());
+    assertEquals(OZONE_USED * 3, 
distributionResponse.getGlobalStorage().getTotalOzoneUsedSpace());
+    assertEquals(OZONE_REMAINING * 3, 
distributionResponse.getGlobalStorage().getTotalOzoneFreeSpace());
+    assertEquals(OZONE_CAPACITY * 3, 
distributionResponse.getGlobalStorage().getTotalOzoneCapacity());
     assertEquals(totalNameSpace, 
distributionResponse.getGlobalNamespace().getTotalUsedSpace());
     assertEquals(EXPECTED_GLOBAL_TOTAL_KEYS, 
distributionResponse.getGlobalNamespace().getTotalKeys());
     assertEquals(OPEN_KEY_BYTES,
@@ -140,7 +140,7 @@ public void testStorageDistributionApiReturnsSuccess() 
throws Exception {
     assertEquals(EXPECTED_COMMITTED_KEY_BYTES,
         distributionResponse.getUsedSpaceBreakDown().getCommittedKeyBytes());
     assertEquals(COMMITTED * 3,
-        
distributionResponse.getUsedSpaceBreakDown().getPreAllocatedContainerBytes());
+        
distributionResponse.getGlobalStorage().getTotalOzonePreAllocatedContainerSpace());
     for (int i = 0; i < 3; i++) {
       DatanodeStorageReport report = 
distributionResponse.getDataNodeUsage().get(i);
       assertEquals(OZONE_CAPACITY, report.getCapacity());


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to