The resource manager library defines several key structures that are
related to the POSIX-layer support routines:
- iofunc_ocb_t (Open Control Block)
structure
- Contains per-open data, such as the current position into
a file (the lseek() offset).
- iofunc_attr_t (attribute) structure
- Since a resource manager may be responsible for more than
one device (e.g. devc-ser* may be responsible for
/dev/ser1, /dev/ser2,
/dev/ser3, etc.), the attributes
structure holds data on a per-name basis.
This structure contains such items as the user and group ID of
the owner of the device, the last modification time, etc.
- iofunc_mount_t (mount) structure
- Contains per-mountpoint data items
that are global to the entire mount device.
Filesystem (block I/O device) managers use this structure;
a resource manager for a device typically won't have a mount structure.
This picture may help explain their interrelationships:
A resource manager is responsible for three data structures.
If three clients open two paths associated with a resource manager, the
data structures are linked like this:
Multiple clients with multiple OCBs, all linked to one mount structure.
The Open Control Block (OCB) maintains the state information about a particular session involving a client and a resource manager.
It's created during open() handling and exists until a
close() is performed.
This structure is used by the iofunc layer helper functions.
(In the
Extending the POSIX-Layer Data Structures
chapter, we'll show you how to extend this to include your own data).
The OCB structure contains at least the following:
typedef struct _iofunc_ocb {
IOFUNC_ATTR_T *attr;
int32_t ioflag;
off_t offset;
uint16_t sflag;
uint16_t flags;
} iofunc_ocb_t;
where the values represent:
- attr
- A pointer to the
attribute structure
(see below).
- ioflag
- Contains the mode (e.g. reading, writing, blocking) that the resource was opened with.
This information is inherited from the io_connect_t structure
that's available in the message passed to the io_open handler.
The open modes (as passed to open() on the client side)
are converted to the ioflag values as follows:
Open mode
|
ioflag value
|
O_RDONLY
|
_IO_FLAG_RD
|
O_RDWR
|
_IO_FLAG_RD | _IO_FLAG_WR
|
O_WRONLY
|
_IO_FLAG_WR
|
- offset
- The read/write offset into the resource (e.g. our current
lseek() position within a file).
Your resource manager can modify this member.
- sflag
- Defines the sharing mode.
This information is inherited from the io_connect_t structure
that's available in the message passed to the io_open handler.
- flags
- When the IOFUNC_OCB_PRIVILEGED bit is set,
a privileged process (i.e. root) performed the open().
Additionally, you can use flags in the range IOFUNC_OCB_FLAGS_PRIVATE
(see <sys/iofunc.h>) for your own purposes.
Your resource manager can modify this member.
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;
} iofunc_attr_t;
where the values represent:
- mount
- A pointer to the
mount structure
(see below).
- flags
- The bit-mapped flags member can contain the following flags:
- IOFUNC_ATTR_ATIME
- The access time is no longer valid.
Typically set on a read from the resource.
- IOFUNC_ATTR_CTIME
- The change of status time is no longer valid.
Typically set on a file info change.
- IOFUNC_ATTR_DIRTY_NLINK
- The number of links has changed.
- IOFUNC_ATTR_DIRTY_MODE
- The mode has changed.
- IOFUNC_ATTR_DIRTY_OWNER
- The uid or the gid has changed.
- IOFUNC_ATTR_DIRTY_RDEV
- The rdev member has changed, e.g. mknod().
- IOFUNC_ATTR_DIRTY_SIZE
- The size has changed.
- IOFUNC_ATTR_DIRTY_TIME
- One or more of mtime, atime, or ctime has changed.
- IOFUNC_ATTR_MTIME
- The modification time is no longer valid.
Typically set on a write to the resource.
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 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 will all be 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.
- list
- Reserved for future use.
- list_size
- The size of the reserved list area; reserved for future use.
- nbytes
- 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.
- inode
- 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)
|
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 change 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.
- mode
- Contains the resource's mode (e.g. type, permissions).
Valid modes may be selected from the S_* series
of constants in <sys/stat.h>.
- nlink
- 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.
- rdev
- Contains the device number for a character special device and the
rdev number for a named special device.
The members of the mount structure, specifically the conf and flags members,
modify the behavior of some of the iofunc layer functions.
This optional structure contains at least the following:
typedef struct _iofunc_mount {
uint32_t flags;
uint32_t conf;
dev_t dev;
int32_t blocksize;
iofunc_funcs_t *funcs;
} iofunc_mount_t;
The variables are:
- flags
- Contains one relevant bit (manifest constant IOFUNC_MOUNT_32BIT),
which indicates that the offsets used by this resource manager are 32-bit (as opposed to the extended 64-bit offsets).
The user-modifiable mount flags are defined as IOFUNC_MOUNT_FLAGS_PRIVATE
(see <sys/iofunc.h>).
- conf
- Contains several bits:
- IOFUNC_PC_CHOWN_RESTRICTED
- Causes the default handler for the _IO_CHOWN
message to behave in a manner defined by POSIX as
“chown-restricted”.
- IOFUNC_PC_NO_TRUNC
- Has no effect on the iofunc layer libraries,
but is returned by the iofunc layer's default _IO_PATHCONF handler.
- IOFUNC_PC_SYNC_IO
- If not set, causes the default iofunc layer _IO_OPEN
handler to fail if the client specified any one of
O_DSYNC, O_RSYNC, or O_SYNC.
- IOFUNC_PC_LINK_DIR
- Controls whether or not root is allowed to link and unlink directories.
Note that the options mentioned above for the conf
member are returned by the iofunc layer _IO_PATHCONF default handler.
- dev
- Contains the device number for the filesystem.
This number is returned to the client's stat() function
in the struct stat st_dev member.
- blocksize
- Contains the block size of the device.
On filesystem types of resource managers, this indicates the native blocksize of the disk, e.g. 512 bytes.
- funcs
- Contains the following structure:
struct _iofunc_funcs {
unsigned nfuncs;
IOFUNC_OCB_T *(*ocb_calloc) (resmgr_context_t *ctp,
IOFUNC_ATTR_T *attr);
void (*ocb_free) (IOFUNC_OCB_T *ocb);
};
where:
- nfuncs
- Indicates the number of functions present in the structure;
it should be filled with the manifest constant _IOFUNC_NFUNCS.
- ocb_calloc() and ocb_free()
- Allows you to override the OCBs on a per-mountpoint basis.
(See the section titled
“Extending the OCB and attribute structures”
in the Extending the POSIX-Layer Data Structures chapter.)
If these members are NULL, then the default library versions are used.
You must specify either both or neither of these functions —
they operate as a matched pair.