VxWorks: Check File System Capacity and Free Space
When a block device is mounted through a VxWorks file system such as dosFS or HRFS, built-in diagnostic commands can expose device and partition information without necessarily presenting the overall file-system capacity and available space in a convenient byte, KB, or MB format.
For applications and diagnostic utilities that need these values programmatically, the POSIX-like statfs() API provides a direct way to query file-system statistics.
This approach works at the file-system level, making it more useful than inspecting the underlying block-device geometry when the goal is to determine how much storage the mounted volume actually provides and how much space remains available.
🔍 Query File-System Statistics with statfs()
#
The basic interface is:
#include <sys/statfs.h>
struct statfs fs;
if (statfs("/sd0", &fs) != OK)
{
/* Handle error */
}
The path passed to statfs() should identify the mounted file-system volume being queried.
For example:
statfs("/tffs0", &fs);
statfs("/sd0", &fs);
The API retrieves statistics from the file-system implementation rather than requiring the application to calculate capacity from raw disk geometry.
Important struct statfs Fields
#
The following fields are particularly useful for calculating capacity and free space:
| Field | Type | Description |
|---|---|---|
f_bsize |
long |
Fundamental file-system block size in bytes |
f_blocks |
long |
Total number of file-system blocks |
f_bfree |
long |
Total number of free blocks |
f_bavail |
long |
Blocks available to unprivileged users |
The basic calculations are:
Total bytes = f_bsize × f_blocks
Available bytes = f_bsize × f_bavail
For diagnostic output in KB:
Total KB = Total bytes / 1024
Free KB = Available bytes / 1024
⚙️ How statfs() Reaches the File System
#
At a lower level, VxWorks can obtain file-system statistics through the ioctl() interface using the FIOFSTATFSGET command.
Conceptually:
#define FIOFSTATFSGET 46
ioctl(fd, FIOFSTATFSGET, (int)pStat);
This provides the underlying mechanism through which file-system statistics can be requested from the device or file-system layer.
Application code should normally prefer the higher-level statfs() interface instead of directly issuing FIOFSTATFSGET, unless there is a specific reason to work at the lower I/O layer.
🧮 Use 64-Bit Arithmetic for Capacity Calculations #
A common implementation mistake is performing the multiplication using the native width of the statfs fields before assigning the result to a larger integer type.
For example:
UINT64 totalSize = fs.f_bsize * fs.f_blocks;
Depending on the VxWorks architecture and compiler configuration, the multiplication may occur at a narrower integer width before the result is assigned to UINT64.
Instead, explicitly promote the block size before multiplication:
UINT64 totalSize =
((UINT64)fs.f_bsize * fs.f_blocks);
The same principle applies when calculating available space:
UINT64 freeSpace =
((UINT64)fs.f_bsize * fs.f_bavail);
This is particularly important for volumes larger than 4 GB and for legacy 32-bit targets where intermediate integer calculations can overflow.
🛠️ Implement a volumeShow() Utility
#
The following function provides a reusable VxWorks diagnostic command for displaying total file-system capacity and available space.
#include <vxWorks.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/statfs.h>
/*******************************************************************************
* volumeShow - Display total capacity and free space for a mounted volume
*
* RETURNS: OK on success, or ERROR if the file system cannot be queried.
*/
STATUS volumeShow(const char *devName)
{
struct statfs fs;
UINT64 totalSizeKB;
UINT64 freeSpaceKB;
if (devName == NULL)
{
printf("Error: NULL device name provided.\n");
return ERROR;
}
/* Query file-system statistics. */
if (statfs((char *)devName, &fs) != OK)
{
printf(
"Error: Unable to retrieve stats for device '%s'\n",
devName);
return ERROR;
}
/*
* Promote the block size to 64 bits before multiplication
* to avoid overflow in the intermediate calculation.
*/
totalSizeKB =
((UINT64)fs.f_bsize * fs.f_blocks) / 1024;
freeSpaceKB =
((UINT64)fs.f_bsize * fs.f_bavail) / 1024;
printf(
"%s: Total File System Size: %llu KB (%llu MB), "
"Free space: %llu KB (%llu MB).\n",
devName,
totalSizeKB,
totalSizeKB / 1024,
freeSpaceKB,
freeSpaceKB / 1024);
return OK;
}
The function performs four main operations:
- Validate the volume pathname.
- Call
statfs()to obtain file-system statistics. - Convert blocks into KB using 64-bit arithmetic.
- Print total and available capacity.
🖥️ Run volumeShow() from the VxWorks Shell
#
After compiling and loading the function, it can be invoked directly from the VxWorks shell.
For a TFFS volume:
-> volumeShow "/tffs0"
/tffs0: Total File System Size: 3824 KB (3 MB), Free space: 3821 KB (3 MB).
For an SD or block-device-backed volume:
-> volumeShow "/sd0"
/sd0: Total File System Size: 15686656 KB (15319 MB), Free space: 12435456 KB (12144 MB).
The exact values depend on the device capacity, file-system metadata, formatting parameters, and current allocation state.
📊 Understanding f_bfree vs. f_bavail
#
struct statfs provides both:
f_bfree
f_bavail
They are not necessarily interchangeable.
f_bfree represents the total number of free blocks, while f_bavail represents the blocks available to unprivileged users.
For a general application-facing available space calculation, f_bavail is usually the more appropriate field:
UINT64 freeSpaceKB =
((UINT64)fs.f_bsize * fs.f_bavail) / 1024;
If the diagnostic utility specifically needs to report all free blocks maintained by the file system, use:
UINT64 freeBlocksKB =
((UINT64)fs.f_bsize * fs.f_bfree) / 1024;
The distinction can matter on file systems that reserve space or enforce different allocation policies for privileged and unprivileged users.
💾 File-System Capacity vs. Physical Disk Capacity #
One important distinction is that statfs() reports file-system statistics, not necessarily the raw physical disk capacity.
For example, a storage device may contain:
Physical disk
+-------------------------------------------+
| Partition table |
+-------------------------------------------+
| File system partition |
| +---------------------------------------+ |
| | File-system metadata | |
| | User data | |
| | Free space | |
| +---------------------------------------+ |
+-------------------------------------------+
statfs() describes the mounted file system represented by the selected path.
Therefore:
statfs() capacity
≠
necessarily raw device capacity
The difference can result from partitioning, file-system metadata, reserved blocks, formatting overhead, or other storage-layout details.
If the application needs raw block-device geometry, a device-specific API or ioctl() is generally more appropriate.
⚠️ Validate the Path Before Querying #
statfs() should be given a valid mounted file-system path.
For example:
volumeShow("/sd0");
is meaningful when /sd0 represents a mounted file system.
If the path is unavailable or the file system has not been initialized, statfs() can fail:
Error: Unable to retrieve stats for device '/sd0'
For production diagnostics, distinguish between:
- Invalid path.
- Unmounted file system.
- File-system driver failure.
- Device I/O failure.
- Unsupported
statfs()operation.
This makes storage diagnostics considerably easier to troubleshoot.
🔬 Improve the Diagnostic Output #
For embedded diagnostics, it can be useful to report bytes as well as KB and MB.
For example:
UINT64 totalBytes;
UINT64 freeBytes;
totalBytes =
(UINT64)fs.f_bsize * fs.f_blocks;
freeBytes =
(UINT64)fs.f_bsize * fs.f_bavail;
printf("Volume: %s\n", devName);
printf("Block size: %ld bytes\n", fs.f_bsize);
printf("Total blocks: %ld\n", fs.f_blocks);
printf("Free blocks: %ld\n", fs.f_bfree);
printf("Available blocks: %ld\n", fs.f_bavail);
printf("Total bytes: %llu\n", totalBytes);
printf("Available bytes: %llu\n", freeBytes);
This is often more useful during troubleshooting because the raw values make it possible to verify the calculation independently.
📋 Minimal Implementation #
If only the total and available space are required, the implementation can be reduced to:
#include <vxWorks.h>
#include <stdio.h>
#include <sys/statfs.h>
STATUS volumeShow(const char *path)
{
struct statfs fs;
UINT64 totalKB;
UINT64 freeKB;
if (path == NULL)
return ERROR;
if (statfs((char *)path, &fs) != OK)
return ERROR;
totalKB =
((UINT64)fs.f_bsize * fs.f_blocks) / 1024;
freeKB =
((UINT64)fs.f_bsize * fs.f_bavail) / 1024;
printf(
"%s: total=%llu KB, available=%llu KB\n",
path,
totalKB,
freeKB);
return OK;
}
This version is suitable as a small shell diagnostic or as a building block for a larger storage-monitoring component.
🧠 Key Takeaways #
The statfs() API is the appropriate high-level interface when a VxWorks application needs to query the capacity and available space of a mounted file system.
The essential pattern is:
struct statfs fs;
statfs(path, &fs);
followed by:
totalBytes =
(UINT64)fs.f_bsize * fs.f_blocks;
freeBytes =
(UINT64)fs.f_bsize * fs.f_bavail;
The most important implementation considerations are:
- Use
statfs()against the mounted file-system path. - Use
f_bsize × f_blocksfor total file-system capacity. - Use
f_bsize × f_bavailfor space available to normal users. - Promote operands to
UINT64before multiplication. - Do not confuse file-system capacity with raw physical disk capacity.
- Use
FIOFSTATFSGETonly when directioctl()access is specifically required. - Validate the target path and handle
statfs()failures explicitly.
For VxWorks storage diagnostics, this approach provides a compact and reusable way to expose volume capacity and free-space information without depending on the internal formatting of commands such as dosFsShow.