The iofunc_attr_t attributes structure
The attributes structure is a per-resource (e.g., 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.
typedef struct _iofunc_attr {
IOFUNC_MOUNT_T *mount;
struct _iofunc_mmap_list *mmap_list;
struct _iofunc_lock_list *lock_list;
void *acl;
union {
void *lockobj;
pthread_mutex_t lock;
};
uint32_t flags;
uint16_t count;
uint16_t rcount;
uint16_t wcount;
uint16_t rlocks;
uint16_t wlocks;
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 boundby hand
into the attributes structure in code that you supply for your resource manager initialization. - mmap_list
- Used internally by POSIX iofunc_mmap_default() and iofunc_mmap_default_ext().
- lock_list
- Used internally by POSIX iofunc_lock_default().
- acl
- Access control lists.
- lockobj and lock
- Members of a union that provide a way to lock the attribute structure.
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 attribute structure can be locked recursively.
- The default behavior is to use the lock member, which is a built-in lock mutex.
If you use
iofunc_attr_init()
to initialize the structure, it initializes the built-in lock mutex (lock)
using a static lock initializer.
The resource manager layer automatically locks the attribute structure (using iofunc_attr_lock()) for you when certain handler functions are called (i.e., IO_*). You can lock the attribute structure by calling iofunc_attr_lock() or iofunc_attr_trylock(); you can unlock it by calling iofunc_attr_unlock().
- If you want to use an external lock object, override the built-in lock by pointing the
lockobj member to the external lock object.
You also need to provide your own functions to lock and unlock the attribute structure and set the
appropriate members of the funcs structure in the iofunc_mount_t structure.
For more information, see
The iofunc_mount_t mount structure
in this chapter.
- The default behavior is to use the lock member, which is a built-in lock mutex.
If you use
iofunc_attr_init()
to initialize the structure, it initializes the built-in lock mutex (lock)
using a static lock initializer.
- flags
- Contains flags that describe the state of other attributes structure fields. We'll discuss these shortly.
- 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 of 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 of 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, it means there are no read locks, but there may be write locks.
- wlocks
- Same as rlocks but for write locks.
- 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, it 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
- The nanosecond values for the POSIX time members, mtime, atime, and ctime.
As with the OCB, you can extend the normal
attributes structure with your own data.
See the Extending the attributes structure
section.