The iofunc_attr_t (attribute) structure

The iofunc_attr_t structure defines the characteristics of the device that you're supplying the resource manager for. This is used in conjunction with the OCB structure.

The attribute structure contains at least the following:

typedef struct _iofunc_attr {
    IOFUNC_MOUNT_T            *mount;
    uint32_t                  flags;
    int32_t                   lock_tid;
    uint16_t                  lock_count;
    uint16_t                  count;
    uint16_t                  rcount;
    uint16_t                  wcount;
    uint16_t                  rlocks;
    uint16_t                  wlocks;
    struct _iofunc_mmap_list  *mmap_list;
    struct _iofunc_lock_list  *lock_list;
    void                      *list;
    uint32_t                  list_size;
    off_t                     nbytes;
    ino_t                     inode;
    uid_t                     uid;
    gid_t                     gid;
    time_t                    mtime;
    time_t                    atime;
    time_t                    ctime;
    mode_t                    mode;
    nlink_t                   nlink;
    dev_t                     rdev;
    unsigned                  mtime_ns;
    unsigned                  atime_ns;
    unsigned                  ctime_ns;
} iofunc_attr_t;

The fields include:

A pointer to the mount structure (see below).
The bit-mapped flags member can contain the following flags:
The access time is no longer valid. Typically set on a read from the resource.
The change of status time is no longer valid. Typically set on a file info change.
The number of links has changed.
The mode has changed.
The uid or the gid has changed.
The rdev member has changed, e.g., mknod().
The size has changed.
One or more of mtime, atime, or ctime has changed.
The modification time is no longer valid. Typically set on a write to the resource.
(QNX Neutrino 7.0 or later) The attributes structure includes the fields used for nanosecond-resolution timestamps, mtime_ns, atime_ns, and ctime_ns.

Since your resource manager uses these flags, you can tell right away which fields of the attribute structure have been modified by the various iofunc-layer helper routines. That way, if you need to write the entries to some medium, you can write just those that have changed. The user-defined area for flags is IOFUNC_ATTR_PRIVATE (see <sys/iofunc.h>).

For details on updating your attribute structure, see the section on Updating the time for reads and writes in the Handling Read and Write Messages chapter.

lock_tid and lock_count
To support multiple threads in your resource manager, you'll need to lock the attribute structure so that only one thread at a time is allowed to change it. The resource manager layer automatically locks the attribute (using iofunc_attr_lock()) for you when certain handler functions are called (i.e., IO_*).

The lock_tid member holds the thread ID; the lock_count member holds the number of times the thread has locked the attribute structure. For more information, see the iofunc_attr_lock() and iofunc_attr_unlock() functions in the QNX Neutrino C Library Reference.)

count, rcount, wcount, rlocks and wlocks
Several counters are stored in the attribute structure and are incremented/decremented by some of the iofunc layer helper functions. Both the functionality and the actual contents of the message received from the client determine which specific members are affected.
This counter: Tracks the number of:
count OCBs using this attribute in any manner. When this count goes to zero, it means that no one is using this attribute.
rcount OCBs using this attribute for reading
wcount OCBs using this attribute for writing
rlocks Read locks currently registered on the attribute
wlocks Write locks currently registered on the attribute

These counts aren't exclusive. For example, if an OCB has specified that the resource is opened for reading and writing, then count, rcount, and wcount are all incremented. (See the iofunc_attr_init(), iofunc_lock_default(), iofunc_lock(), iofunc_ocb_attach(), and iofunc_ocb_detach() functions.)

mmap_list and lock_list
To manage their particular functionality on the resource, the mmap_list member is used by the iofunc_mmap() and iofunc_mmap_default() functions; the lock_list member is used by the iofunc_lock_default() function. Generally, you shouldn't need to modify or examine these members.
Reserved for future use.
The size of the reserved list area; reserved for future use.
The number of bytes in the resource. Your resource manager can modify this member. For a file, this would contain the file's size. For special devices (e.g., /dev/null) that don't support lseek() or have a radically different interpretation for lseek(), this field isn't used (because you wouldn't use any of the helper functions, but would supply your own instead.) In these cases, we recommend that you set this field to zero, unless there's a meaningful interpretation that you care to put to it.
This is a mountpoint-specific inode that must be unique per mountpoint. You can specify your own value, or 0 to have the process manager fill it in for you. For filesystem resource managers, this may correspond to some on-disk structure. In any case, the interpretation of this field is up to you.
uid and gid
The user ID and group ID of the owner of this resource. These fields are updated automatically by the chown() helper functions (e.g., iofunc_chown_default()) and are referenced in conjunction with the mode member for access-granting purposes by the open() help functions (e.g., iofunc_open_default()).
mtime, atime, and ctime
The three POSIX time members:
  • mtime — modification time (write() updates this)
  • atime — access time (read() updates this)
  • ctime — change of status time (write(), chmod(), and chown() update this)
Note: One or more of the time members may be invalidated as a result of calling an iofunc-layer function. This is to avoid having each and every I/O message handler go to the kernel and request the current time of day, just to fill in the attribute structure's time member(s).

POSIX states that these times must be valid when the fstat() is performed, but they don't have to reflect the actual time that the associated change occurred. Also, the times must be updated between fstat() invocations if the associated change occurred between fstat() invocations. If the associated change never occurred between fstat() invocations, then the time returned should be the same as returned last time. Furthermore, if the associated change occurred multiple times between fstat() invocations, then the time need only be different from the previously returned time.

There's a helper function that fills the members with the correct time; you may wish to call it in the appropriate handlers to keep the time up-to-date on the device—see the iofunc_time_update() function.

Contains the resource's mode (e.g., type, permissions). Valid modes may be selected from the S_* series of constants in <sys/stat.h>; see struct stat.
The number of links to this particular name. For names that represent a directory, this value must be at least 2 (one for the directory itself, one for the ./ entry in it). Your resource manager can modify this member.
Contains the device number for a character special device and the rdev number for a named special device.
mtime_ns, atime_ns, and ctime_ns
(QNX Neutrino 7.0 or later) The nanosecond values for the POSIX time members, mtime, atime, and ctime.

These fields are included if you compile for a 64-bit architecture, or if you define IOFUNC_NS_TIMESTAMP_SUPPORT before including <sys/iofunc.h> when you compile for a 32-bit architecture.