Skip to main content

VxWorks: Check File System Capacity and Free Space

·1365 words·7 mins
VxWorks VxWorks File System DosFS HRFS Statfs Embedded Systems C Programming RTOS
Table of Contents

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:

  1. Validate the volume pathname.
  2. Call statfs() to obtain file-system statistics.
  3. Convert blocks into KB using 64-bit arithmetic.
  4. 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_blocks for total file-system capacity.
  • Use f_bsize × f_bavail for space available to normal users.
  • Promote operands to UINT64 before multiplication.
  • Do not confuse file-system capacity with raw physical disk capacity.
  • Use FIOFSTATFSGET only when direct ioctl() 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.

Related

VxWorks Programming Guide: Tasks, IPC, I/O, Semaphores
·2629 words·13 mins
VxWorks RTOS C Programming TaskLib SemLib MsgQLib Socket IPC Embedded Systems
PCI-Based CAN Card Design and VxWorks Driver Development
·683 words·4 mins
VxWorks CAN Bus PCI Device Drivers Embedded Systems RTOS Hardware Design C Programming
VxWorks Target Hardware Configuration: A Practical Guide
·482 words·3 mins
VxWorks RTOS Embedded Systems Hardware BSP