Skip to content

fix(storage): for differences to main pool sizes#2657

Open
SimonFair wants to merge 4 commits into
unraid:masterfrom
SimonFair:feature/os-297-dashboard-shows-incorrect-cache-pool-sizeusage-for-btrfs
Open

fix(storage): for differences to main pool sizes#2657
SimonFair wants to merge 4 commits into
unraid:masterfrom
SimonFair:feature/os-297-dashboard-shows-incorrect-cache-pool-sizeusage-for-btrfs

Conversation

@SimonFair
Copy link
Copy Markdown
Contributor

@SimonFair SimonFair commented Jun 2, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Corrected cache and mounted-device calculations so free/used values and aggregate totals display accurately, including proper handling of Btrfs (and LUKS-wrapped Btrfs).
    • Fixed real-time dashboard updates so pool usage values refresh reliably in the UI.
  • New Features

    • Added per-pool usage indicators and localized "Used … of … (%)" strings in live updates for clearer pool readouts.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c0a717a3-11c6-43e5-9eb3-cfce64d67848

📥 Commits

Reviewing files that changed from the base of the PR and between fddb8fc and 01b9958.

📒 Files selected for processing (1)
  • emhttp/plugins/dynamix/nchan/device_list
🚧 Files skipped from review as they are similar to previous changes (1)
  • emhttp/plugins/dynamix/nchan/device_list

Walkthrough

Normalize effective Btrfs filesystem size, compute pool-aware cache usage and a localized pool usage string in the backend, append that string to per-pool JSON, and render/update a dedicated pool usage span in the DashStats frontend.

Changes

Pool Usage Dashboard Feature

Layer / File(s) Summary
Filesystem size normalization and helper
emhttp/plugins/dynamix/nchan/device_list
Strip luks: from fsType, add effective_fs_size() (Btrfs: fsUsed+fsFree when numeric), and use it in boot metrics, pool metrics, fs_info(), array_online(), and show_totals(); replace used/free bar math with clamped percentages and remove duplicated device_info() cell in DISK_NP.
Pool usage computation and payload
emhttp/plugins/dynamix/nchan/update_2
device_usage() becomes pool-aware (derive cache-root usage from parent pool stats with Btrfs-aware size handling); add pool_usage($pool) to format a localized "Used: X of Y (Z%)" string; append that string as an extra element to each $echo['pool'][$p++] entry.
Frontend pool usage rendering and updates
emhttp/plugins/dynamix/DashStats.page
Adjust cache pool size computation for Btrfs in the dashboard loop; render pool usage inside a dedicated <span id="pool_usage{$i}">…</span> and update it on WebSocket messages when the payload includes the new index.

Sequence Diagram

sequenceDiagram
  participant DeviceList as device_list (effective_fs_size)
  participant Backend as update_2 (backend)
  participant Payload as JSON payload
  participant Frontend as DashStats (frontend)
  participant WS as WebSocket client

  DeviceList->>Backend: provide effective_fs_size() and normalized fsType
  Backend->>Backend: device_usage() computes pool-aware usage (Btrfs-adjusted)
  Backend->>Backend: pool_usage() formats localized "Used X of Y (Z%)"
  Backend->>Payload: append pool usage string into pool array (index 6)
  Payload->>Frontend: initial render includes pool array with usage string
  WS->>Frontend: realtime pool update with pool array (may include index 6)
  Frontend->>Frontend: set `#pool_usage{n}` to payload.pool[n][6] when present
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble bytes in Btrfs light,
Adding free and used to get it right,
Pools now speak their used-of tune,
WebSocket hums beneath the moon,
A dashboard carrot gleams tonight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is vague and incomplete, using the phrase 'for differences to main pool sizes' which is unclear and grammatically awkward. Revise the title to be more specific and clear, such as 'fix(storage): correct btrfs cache pool size calculations' or 'fix(storage): fix cache pool usage display for btrfs filesystems'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

🔧 PR Test Plugin Available

A test plugin has been generated for this PR that includes the modified files.

Version: 2026.06.02.1907
Build: View Workflow Run

📥 Installation Instructions:

Install via Unraid Web UI:

  1. Go to Plugins → Install Plugin
  2. Copy and paste this URL:
https://preview.dl.unraid.net/pr-plugins/pr-2657/webgui-pr-2657.plg
  1. Click Install

Alternative: Direct Download

⚠️ Important Notes:

  • Testing only: This plugin is for testing PR changes
  • Backup included: Original files are automatically backed up
  • Easy removal: Files are restored when plugin is removed
  • Conflicts: Remove this plugin before installing production updates
  • Post-merge behavior: This preview stays available after merge until preview storage expires or it is manually cleaned up

📝 Modified Files:

Click to expand file list
emhttp/plugins/dynamix/DashStats.page
emhttp/plugins/dynamix/nchan/device_list
emhttp/plugins/dynamix/nchan/update_2

🔄 To Remove:

Navigate to Plugins → Installed Plugins and remove webgui-pr-2657, or run:

plugin remove webgui-pr-2657

🤖 This comment is automatically generated and will be updated with each new push to this PR.

@SimonFair SimonFair added the 7.3 label Jun 2, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@emhttp/plugins/dynamix/DashStats.page`:
- Around line 1194-1195: The code incorrectly checks $pool == "flash" when
deciding to use boot vs cache arrays, causing wrong text and undefined-index
notices; change the branch to detect boot pools (e.g., in_array($pool,
$bootpools) or use the disk type variable used elsewhere) instead of the literal
"flash" so the block uses $boot_used/$boot_size/$boot_rate for actual boot pools
and $cache_used/$cache_size/$cache_rate for others; update the conditional
around the echo that references $pool to use that boot-pool check (and ensure
the variable name you use matches the existing symbol holding boot pool
membership).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a2c46460-6230-4cae-a162-44622d176045

📥 Commits

Reviewing files that changed from the base of the PR and between 982b3c2 and 88cd3b5.

📒 Files selected for processing (2)
  • emhttp/plugins/dynamix/DashStats.page
  • emhttp/plugins/dynamix/nchan/update_2

Comment thread emhttp/plugins/dynamix/DashStats.page
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
emhttp/plugins/dynamix/DashStats.page (1)

1197-1198: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use pool type here, not the literal flash name.

Line 1176 merges both $pools and $bootpools, so this loop processes all pool types. Any boot pool with a name other than "flash" (e.g., "efi", "boot", "usb") will fall into the else branch and attempt to access $cache_used[$pool], $cache_size[$pool], and $cache_rate[$pool]. However, boot pool data is stored in the $boot_* arrays (populated at lines 94-103), not the $cache_* arrays. This causes undefined-index notices and displays incorrect usage information until the WebSocket refresh corrects it. Check the disk type instead of hardcoding the pool name.

🔧 Proposed fix
+                                                    <?
                                                     if ($pool == "flash") echo sprintf(_("Used: %s of %s (%s %%)"),my_scale($boot_used[$pool]*1024,$unit)." $unit",my_scale($boot_size[$pool]*1024,$unit,-1,-1)." $unit",$boot_rate[$pool]);
-                                                    else echo sprintf(_("Used: %s of %s (%s %%)"),my_scale($cache_used[$pool]*1024,$unit)." $unit",my_scale($cache_size[$pool]*1024,$unit,-1,-1)." $unit",$cache_rate[$pool])
+                                                    if ($poolType === 'boot') {
+                                                      echo sprintf(_("Used: %s of %s (%s %%)"),my_scale($boot_used[$pool]*1024,$unit)." $unit",my_scale($boot_size[$pool]*1024,$unit,-1,-1)." $unit",$boot_rate[$pool]);
+                                                    } else {
+                                                      echo sprintf(_("Used: %s of %s (%s %%)"),my_scale($cache_used[$pool]*1024,$unit)." $unit",my_scale($cache_size[$pool]*1024,$unit,-1,-1)." $unit",$cache_rate[$pool]);
+                                                    }
+                                                    ?>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@emhttp/plugins/dynamix/DashStats.page` around lines 1197 - 1198, The code
incorrectly checks if ($pool == "flash") to decide whether to use $boot_* vs
$cache_* arrays; instead detect whether this pool has boot data (e.g., use
isset($boot_used[$pool]) or another pool-type flag) and branch accordingly so
boot pools use $boot_used/$boot_size/$boot_rate and non-boot pools use
$cache_used/$cache_size/$cache_rate; update the echo logic around $pool to
reference the appropriate arrays based on that check rather than the literal
"flash".
🧹 Nitpick comments (1)
emhttp/plugins/dynamix/nchan/device_list (1)

668-674: 💤 Low value

Consider adding inline documentation for Btrfs special handling.

The helper function correctly implements Btrfs size normalization, but would benefit from a brief comment explaining why Btrfs requires used + free instead of the reported fsSize (Btrfs reports raw device size, but actual capacity depends on RAID level and metadata overhead).

📝 Suggested documentation
+/**
+ * Get effective filesystem size, with Btrfs normalization.
+ * For Btrfs, returns used+free instead of reported fsSize because
+ * Btrfs reports raw device size, but actual capacity depends on
+ * RAID level and metadata overhead.
+ */
 function effective_fs_size(&$disk) {
   $size = _var($disk,'fsSize',0);
   $used = _var($disk,'fsUsed',null);
   $free = _var($disk,'fsFree',null);
   $fsType = str_replace('luks:','',_var($disk,'fsType',''));
   return ($fsType=='btrfs' && is_numeric($used) && is_numeric($free)) ? $used+$free : $size;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@emhttp/plugins/dynamix/nchan/device_list` around lines 668 - 674, Add a short
inline comment above or inside the effective_fs_size function explaining the
Btrfs special-case: when $fsType == 'btrfs' use $used + $free because Btrfs
reports raw device size (including RAID/multi-device and metadata overhead) in
fsSize, so actual usable capacity must be computed from reported used + free;
reference the function name effective_fs_size and the $disk keys
'fsSize','fsUsed','fsFree','fsType' in the comment for clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@emhttp/plugins/dynamix/nchan/device_list`:
- Around line 248-250: The three functions get_pool_boot_metrics,
get_boot_pool_metrics, and get_pool_data_metrics duplicate Btrfs size
normalization logic; replace the inline logic that computes $size when
$fsType=='btrfs' (the code that strips 'luks:' and sums $used+$free when
numeric) with a call to the existing helper effective_fs_size() so those
functions pass the same inputs to effective_fs_size() and use its returned size,
removing the duplicated conditional and str_replace logic and ensuring
consistent behavior across all three functions.

---

Duplicate comments:
In `@emhttp/plugins/dynamix/DashStats.page`:
- Around line 1197-1198: The code incorrectly checks if ($pool == "flash") to
decide whether to use $boot_* vs $cache_* arrays; instead detect whether this
pool has boot data (e.g., use isset($boot_used[$pool]) or another pool-type
flag) and branch accordingly so boot pools use $boot_used/$boot_size/$boot_rate
and non-boot pools use $cache_used/$cache_size/$cache_rate; update the echo
logic around $pool to reference the appropriate arrays based on that check
rather than the literal "flash".

---

Nitpick comments:
In `@emhttp/plugins/dynamix/nchan/device_list`:
- Around line 668-674: Add a short inline comment above or inside the
effective_fs_size function explaining the Btrfs special-case: when $fsType ==
'btrfs' use $used + $free because Btrfs reports raw device size (including
RAID/multi-device and metadata overhead) in fsSize, so actual usable capacity
must be computed from reported used + free; reference the function name
effective_fs_size and the $disk keys 'fsSize','fsUsed','fsFree','fsType' in the
comment for clarity.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1be4f721-30bb-4146-9d39-d877c52d8a97

📥 Commits

Reviewing files that changed from the base of the PR and between 88cd3b5 and 3c8d8af.

📒 Files selected for processing (3)
  • emhttp/plugins/dynamix/DashStats.page
  • emhttp/plugins/dynamix/nchan/device_list
  • emhttp/plugins/dynamix/nchan/update_2
🚧 Files skipped from review as they are similar to previous changes (1)
  • emhttp/plugins/dynamix/nchan/update_2

Comment thread emhttp/plugins/dynamix/nchan/device_list Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
emhttp/plugins/dynamix/nchan/device_list (1)

271-282: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: condition checks overwritten $size variable.

Identical issue to get_pool_boot_metrics above. Line 281 overwrites $size with effective_fs_size() result (always numeric), then line 282 checks $size !== null (always true).

🐛 Proposed fix
     foreach ($bootDisks as $disk) {
       if (prefix(_var($disk,'name','')) !== $bootPoolName) continue;
-      $size = _var($disk,'fsSize',null);
+      $origSize = _var($disk,'fsSize',null);
       $used = _var($disk,'fsUsed',null);
       $free = _var($disk,'fsFree',null);
-      $fsDisk = [
-        'fsSize' => $size ?? 0,
-        'fsUsed' => $used ?? 0,
-        'fsFree' => $free ?? 0,
-        'fsType' => _var($disk,'fsType',''),
-      ];
-      $size = effective_fs_size($fsDisk);
+      $size = effective_fs_size($disk);
-      if ($size !== null || $used !== null || $free !== null) {
+      if ($origSize !== null || $used !== null || $free !== null) {
         return [
           'fsSize' => $size ?? 0,
           'fsUsed' => $used ?? 0,
           'fsFree' => $free ?? 0,
         ];
       }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@emhttp/plugins/dynamix/nchan/device_list` around lines 271 - 282, The
condition check is broken because you overwrite $size with
effective_fs_size($fsDisk) before testing for null; instead, keep the original
raw $size/$used/$free and store the computed effective size in a new variable
(e.g., $effectiveSize) so the subsequent if uses the original null checks (or
checks against $effectiveSize explicitly if intended). Update the block around
effective_fs_size(...) to assign to a new symbol rather than reusing $size and
adjust the if(...) to reference the correct variables (retain references to
effective_fs_size, $fsDisk, $size, $used, $free).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@emhttp/plugins/dynamix/nchan/device_list`:
- Around line 248-256: The condition that decides whether to return an empty
array is being evaluated against the value overwritten by effective_fs_size(),
because $size is reassigned; capture the original filesystem size before calling
effective_fs_size (e.g., store $size into $origSize or $rawSize), then call
effective_fs_size($fsDisk) into $sizeOnly (or reuse $size) and use the preserved
original ($origSize/$rawSize) in the conditional (the check that currently reads
$size !== null || $used !== null || $free !== null) so the condition reflects
the original input rather than the computed effective size.

---

Outside diff comments:
In `@emhttp/plugins/dynamix/nchan/device_list`:
- Around line 271-282: The condition check is broken because you overwrite $size
with effective_fs_size($fsDisk) before testing for null; instead, keep the
original raw $size/$used/$free and store the computed effective size in a new
variable (e.g., $effectiveSize) so the subsequent if uses the original null
checks (or checks against $effectiveSize explicitly if intended). Update the
block around effective_fs_size(...) to assign to a new symbol rather than
reusing $size and adjust the if(...) to reference the correct variables (retain
references to effective_fs_size, $fsDisk, $size, $used, $free).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a4f391eb-edae-4f6b-97f4-055f5b1dde7b

📥 Commits

Reviewing files that changed from the base of the PR and between 3c8d8af and fddb8fc.

📒 Files selected for processing (1)
  • emhttp/plugins/dynamix/nchan/device_list

Comment thread emhttp/plugins/dynamix/nchan/device_list Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant