The iofunc_attr_t attributes structure

Whereas the OCB was a per-open or per-file-descriptor structure, the attributes structure is a per-device data structure. You saw that the standard iofunc_ocb_t OCB had a member called attr that's a pointer to the attribute structure. This was done so the OCB has access to information about the device. Let's take a look at the attributes structure (from <sys/iofunc.h>):

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;
  SEE_BELOW!!!             nbytes;
  SEE_BELOW!!!             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 nbytes and inode members have the same set of #ifdef conditionals as the offset member of the OCB (see “The strange case of the offset member” above).

Note that some of the fields of the attributes structure are useful only to the POSIX helper routines.

Let's look at the fields individually:

mount
A pointer to the optional iofunc_mount_t mount structure. This is used in the same way that the pointer from the OCB to the attribute structure was used, except that this value can be NULL in which case the mount structure defaults are used (see “The iofunc_mount_t mount structure” below). As mentioned, the mount structure is generally bound “by hand” into the attributes structure in code that you supply for your resource manager initialization.
flags
Contains flags that describe the state of other attributes structure fields. We'll discuss these shortly.
lock_tid
In order to prevent synchronization problems, multiple threads using the same attributes structure will be mutually exclusive. The lock_tid contains the thread ID of the thread that currently has the attributes structure locked.
lock_count
Indicates how many threads are trying to use this attributes structure. A value of zero indicates that the structure is unlocked. A value of one or more indicates that one or more threads are using the structure.
count
Indicates the number of OCBs that have this attributes structure open for any reason. For example, if one client has an OCB open for read, another client has another OCB open for read/write, and both OCBs point to this attribute structure, then the value of count would be 2, to indicate that two clients have this resource open.
rcount
Count readers. In the example given for count, rcount would also have the value 2, because two clients have the resource open for reading.
wcount
Count writers. In the example given for count, wcount would have the value 1, because only one of the clients has this resource open for writing.
rlocks
Indicates the number of OCBs that have read locks on the particular resource. If zero, means there are no read locks, but there may be write locks.
wlocks
Same as rlocks but for write locks.
mmap_list
Used internally by POSIX iofunc_mmap_default().
lock_list
Used internally by POSIX iofunc_lock_default().
list
Reserved for future use.
list_size
Size of area reserved by list.
nbytes
Size of the resource, in bytes. For example, if this resource described a particular file, and that file was 7756 bytes in size, then the nbytes member would contain the number 7756.
inode
Contains a file or resource serial number, that must be unique per mountpoint. The inode should never be zero, because zero traditionally indicates a file that's not in use.
uid
User ID of the owner of this resource.
gid
Group ID of the owner of this resource.
mtime
File modification time, updated or at least invalidated whenever a client write() is processed.
atime
File access time, updated or at least invalidated whenever a client read() that returns more than zero bytes is processed.
ctime
File change time, updated or at least invalidated whenever a client write(), chown(), or chmod() is processed.
mode
File's mode. These are the standard S_* values from <sys/stat.h>, such as S_IFCHR, or in octal representation, such as 0664 to indicate read/write permission for owner and group, and read-only permission for other.
nlink
Number of links to the file, returned by the client's stat() function call.
rdev
For a character special device, this field consists of a major and minor device code (10 bits minor in the least-significant positions; next 6 bits are the major device number). For other types of devices, contains the device number. (See below in “Of device numbers, inodes, and our friend rdev,” for more discussion.)
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.

As with the OCB, you can extend the “normal” attributes structure with your own data. See the “Advanced topics” section.