DCMD_FSYS_PGCACHE_CTL

QNX SDP8.0Devctl and Ioctl CommandsDeveloper

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

Synopsis:

#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
dcmd DCMD_FSYS_PGCACHE_CTL
dev_data_ptr A pointer to a struct pgcache_ctl
n_bytes sizeof(struct pgcache_ctl)
dev_info_ptr NULL

Description:

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.

Input:

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:

  • DCMD_FSYS_PGCACHE_CTL_OP_DISCARD — selectively discard the contents of the disk cache.
  • DCMD_FSYS_PGCACHE_CTL_OP_RESIZE — dynamically resize the disk cache in block I/O (devb-*) drivers.

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:

  • If PGCACHE_CTL_RESIZE_DIFF is set, nbytes is interpreted as the change (positive or negative) in the size of the disk cache. If this flag is clear, nbytes is interpreted as absolute size of the disk cache.
  • If PGCACHE_CTL_RESIZE_PERMANENT is clear, the limit on the size of disk cache (typically set via the blk cache=... command-line option) is honored, and the disk cache doesn't grow past it. If this flag is set, the limit on the size of disk cache is increased to accommodate nbytes.

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).

Output:

The output depends on the operation:

DCMD_FSYS_PGCACHE_CTL_OP_DISCARD
None.
DCMD_FSYS_PGCACHE_CTL_OP_RESIZE
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.

Errors:

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

EAGAIN
The DCMD_FSYS_PGCACHE_CTL_OP_DISCARD operation encountered some busy cache pages.
ENOTSUP
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 OS C Library Reference

Page updated: