Control the contents of the disk cache in io-blk.so


#include <sys/dcmd_blk.h>

#define DCMD_FSYS_PGCACHE_CTL   __DIOTF(_DCMD_FSYS, 36, struct pgcache_ctl)

Arguments to devctl():

Argument Value
filedes A file descriptor that you obtained by opening the device
dev_data_ptr A pointer to a struct pgcache_ctl
n_bytes sizeof(struct pgcache_ctl)
dev_info_ptr NULL


This command controls the contents of the disk cache in io-blk.so. The calling program must run with superuser privileges on the local node in order to use this command. The device can be a physical disk or a partition.


A pgcache_ctl_t structure that specifies the details of the operation. This structure is defined in <sys/dcmd_blk.h> as follows:

typedef struct pgcache_ctl {
    uint32_t  op;                   /* DCMD_FSYS_PGCACHE_CTL_OP_... command code */
    union {
        uint8_t data[60];           /* overall struct size is 64 bytes */
        struct {
            uint32_t  flags;
            off64_t   start_addr;
            off64_t   end_addr;
        } discard;
        struct {
            uint32_t  flags;        /* PGCACHE_CTL_RESIZE_.. flags */
            off64_t   nbytes;
            uint64_t  curr_size;
        } resize;
} pgcache_ctl_t;

The op member indicates the operation, and the other fields are specific to the operation:

Discarding the contents of the disk cache

The DCMD_FSYS_PGCACHE_CTL_OP_DISCARD operation walks the page cache, finds all cached device pages that contain disk blocks from the specified disk range, and attempts to discard them. It's careful not to discard “dirty” blocks (which are waiting to be written out to disk), locked blocks (which are being worked on by other threads, and may have in-progress I/O on them), and blocks that are being waited for by other threads (to avoid the need to wake up these waiters, and possible races that may arise from that). All such sectors are termed “busy.” This command returns EAGAIN if it encounters any busy cache pages.

The disk range is defined by the starting and ending offsets (given in bytes, and measured from the start of the device) specified in the start_addr and end_addr members of discard in the pgcache_ctl_t structure. There are currently no flags defined, so you should set flags to zero.

It's safe to call this devctl() on a mounted partition or a physical disk that's being actively used by any type of mounted filesystem(s). The disk cache is locked for the duration of this operation.

Resizing the disk cache

The DCMD_FSYS_PGCACHE_CTL_OP_RESIZE operation dynamically resizes the disk cache in block I/O (devb-*) drivers. You can do this even while the disk driver is actively handling I/O requests of all types (file I/O, direct I/O, and so on). There's no need to pause I/O or unmount mounted volumes in order to resize the disk cache.

The size of disk cache can be reduced (deflating the disk cache) or increased (inflating the disk cache) to any value between 1 MB and 512 MB.

The flags member controls the operation:

In order to avoid long delays in I/O caused by locking the disk cache for extended periods of time, a single DCMD_FSYS_PGCACHE_CTL operation is limited to deflating disk cache by at most 15 MB, or to inflating it by at most 4 MB. For larger changes, make multiple devctl() calls.

Note: By default, a disk driver fully preallocates the disk cache when the driver starts, to a maximum size specified by the blk cache=max-size. It isn't possible to resize a fully preallocated disk cache; in this case, devctl() returns ENOTSUP.

In order to resize the disk cache, you must specify the blk alloc=demand option on the disk driver's command line. This option makes the driver dynamically allocate disk cache in incremental fashion as needed by I/O (to a maximum size specified by the blk cache=max-size option).


The output depends on the operation:

The curr_size member contains the current size of disk cache (in bytes), and nbytes contains the change in the disk cache's size.
Note: Since the size of disk cache varies with I/O, and because there could be multiple processes calling this devctl() concurrently, you should consider the returned size of the disk cache to be a reasonably accurate estimate rather than an exact value.


The devctl() function can return the following, in addition to the error codes listed in its entry in the C Library Reference:

The DCMD_FSYS_PGCACHE_CTL_OP_DISCARD operation encountered some busy cache pages.
You tried to do a DCMD_FSYS_PGCACHE_CTL operation on a fully preallocated disk cache.

See also:

io-blk.so in the Utilities Reference

devctl() in the QNX Neutrino C Library Reference