Writing a Resource Manager -- Chapter 4 :POSIX-Layer Data Structures
Chapter 4 :POSIX-Layer Data Structures
资源管理器库定义了(在<sys / iofunc.h>中)与POSIX层支持例程相关的几个关键结构:
iofunc_ocb_t (Open Control Block) structure
包含每个打开的数据,例如当前位置到文件中(lseek()偏移量)。
iofunc_attr_t (attribute) structure
由于资源管理器可能负责多个设备(例如,devc-ser*可能负责/dev/ser1,/dev/ser2,/dev/ser3等),因此属性结构将数据保存在per-name 基础。该结构包含诸如设备所有者的用户和组ID,最后修改时间等项目。
iofunc_mount_t (mount) structure
包含对整个mount device而言是全局的per-mountpoint数据项。文件系统(块I/O设备)管理器使用此结构;设备的资源管理器通常不具有mount结构。
这张照片可能有助于解释它们之间的相互关系:
如果三个客户端打开与资源管理器关联的两个路径,则数据结构链接如下:
The iofunc_ocb_t (Open Control Block) structure
开放控制块(OCB)维护涉及客户端和资源管理器的特定会话的状态信息。它是在open()处理期间创建的,并且一直存在直到执行close()。
iofunc层辅助函数使用此结构。(在扩展POSIX层数据结构一章中,我们将向您展示如何扩展它以包含您自己的数据)。
OCB结构至少包含以下内容:
typedef struct _iofunc_ocb { IOFUNC_ATTR_T *attr; int32_t ioflag; off_t offset; uint16_t sflag; uint16_t flags; } iofunc_ocb_t; |
值代表的地方:
attr
指向属性结构的指针(见下文)。
ioflag
包含打开资源的模式(例如,读取,写入,阻止)。 此信息继承自传递给io_open处理程序的消息中可用的io_connect_t结构。打开模式(传递给客户端的open())将转换为ioflag值,如下所示:
Offset
资源的read/write偏移量(例如,我们在文件中的当前lseek()位置)。您的资源管理器可以修改此成员。
sflag
定义共享模式。此信息继承自传递给io_open处理程序的消息中可用的io_connect_t结构。
flags
以下位中的零个或多个的组合:
-
IOFUNC_OCB_PRIVILEGED - 执行open()的特权进程(即root)
-
IOFUNC_OCB_MMAP - 客户端的mmap()调用正在使用此OCB
-
IOFUNC_OCB_MMAP_UNIQUE - mmap()处理程序的提示,以提供唯一的映射
此外,您可以在IOFUNC_OCB_FLAGS_PRIVATE定义的范围内使用标志(请参阅<sys/iofunc.h>)以用于您自己的目的。您的资源管理器可以修改这些标志。
The iofunc_attr_t (attribute) structure
iofunc_attr_t结构定义了您为其提供资源管理器的设备的特征。这与OCB结构一起使用。
属性结构至少包含以下内容:
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; |
这些领域包括:
-
mount
指向安装结构的指针(见下文)。 -
flags
位映射标志成员可以包含以下标志:
IOFUNC_ATTR_ATIME
访问时间不再有效。通常设置为从资源读取。
IOFUNC_ATTR_CTIME
状态时间的更改不再有效。通常设置文件信息更改。
IOFUNC_ATTR_DIRTY_NLINK
链接数已更改。
IOFUNC_ATTR_DIRTY_MODE
模式已经改变。
IOFUNC_ATTR_DIRTY_OWNER
uid或gid已经改变了。
IOFUNC_ATTR_DIRTY_RDEV
rdev成员已更改,例如mknod()。
IOFUNC_ATTR_DIRTY_SIZE
尺寸发生了变化。
IOFUNC_ATTR_DIRTY_TIME
mtime,atime或ctime中的一个或多个已更改。
IOFUNC_ATTR_MTIME
修改时间不再有效。通常设置对资源的写入。
IOFUNC_ATTR_NS_TIMESTAMPS
(QNX Neutrino 7.0或更高版本)属性结构包括用于纳秒分辨率时间戳的字段,mtime_ns,atime_ns和ctime_ns。
由于资源管理器使用这些标志,您可以立即告知属性结构的哪些字段已被各种iofunc层辅助例程修改。这样,如果您需要将条目写入某些介质,您可以只编写已更改的条目。用户定义的标志区域是IOFUNC_ATTR_PRIVATE(参见<sys/iofunc.h>)。
有关更新属性结构的详细信息,请参阅“Handling Read and Write Messages”一章中的“Updating the time for reads and writes”一节。
-
lock_tid和lock_count
要在资源管理器中支持多个线程,您需要锁定属性结构,以便一次只允许一个线程更改它。在调用某些处理函数(即IO_ *)时,资源管理器层会自动锁定属性(使用iofunc_attr_lock())。
lock_tid成员保存线程ID;lock_count成员保存线程锁定属性结构的次数。有关更多信息,请参阅QNX Neutrino C库参考中的iofunc_attr_lock()和iofunc_attr_unlock()函数。)
-
count, rcount,wcount,rlocks 和wlocks
几个计数器存储在属性结构中,并由一些iofunc层辅助函数递增/递减。从客户端收到的消息的功能和实际内容都决定了哪些特定成员受到影响。
这些计数并不是唯一的。例如,如果OCB指定打开资源进行读写,则count,rcount和wcount都会递增。(请参阅iofunc_attr_init(),iofunc_lock_default(),iofunc_lock(),iofunc_ocb_attach()和iofunc_ocb_detach()函数。)
-
mmap_list和lock_list
为了管理它们在资源上的特定功能,mof_list成员由iofunc_mmap()和iofunc_mmap_default()函数使用;lock_list成员由iofunc_lock_default()函数使用。通常,您不需要修改或检查这些成员。
-
List
保留供将来使用。
-
list_size
保留列表区域的大小;留作将来使用。
-
nbytes
资源中的字节数。您的资源管理器可以修改此成员。对于文件,这将包含文件的大小。对于不支持lseek()或对lseek()具有根本不同解释的特殊设备(例如/ dev / null),不使用此字段(因为您不会使用任何辅助函数,但是而是提供你自己的。)在这些情况下,我们建议你将这个字段设置为零,除非你有一个有意义的解释,你要放在它上面。
-
inode
这是一个特定于安装点的inode,每个mountpoint必须是唯一的。您可以指定自己的值,或者0以让进程管理器为您填写。对于文件系统资源管理器,这可能对应于某些磁盘上的结构。无论如何,这个领域的解释取决于你。
-
uid和gid
此资源所有者的用户标识和组标识。这些字段由chown()辅助函数(例如,iofunc_chown_default())自动更新,并且与open()帮助函数(例如,iofunc_open_default())一起用于访问授权目的的模式成员引用。
-
mtime,atime和ctime
三个POSIX时间成员:
-
mtime - 修改时间(write()更新此)
-
atime - 访问时间(read()更新此)
-
ctime - 更改状态时间(write(),chmod()和chown()更新此)
由于调用iofunc层功能,一个或多个时间成员可能无效。这是为了避免让每个I/O消息处理程序进入内核并请求当前时间,只是为了填写属性结构的时间成员。
POSIX声明这些时间在执行fstat()时必须有效,但它们不必反映相关更改发生的实际时间。此外,如果在fstat()调用之间发生关联的更改,则时间必须在fstat()调用之间更改。如果在fstat()调用之间从未发生相关更改,则返回的时间应与上次返回的时间相同。此外,如果关联的更改在fstat()调用之间多次发生,则时间只需要与先前返回的时间不同。
有一个辅助功能,可以给成员填充正确的时间;您可能希望在适当的处理程序中调用它以使设备上的时间保持最新 - 请参阅iofunc_time_update()函数。
-
mode
包含资源的模式(例如,类型,权限)。可以从<sys/stat.h>中的S_*系列常量中选择有效模式;请参阅struct stat。
-
nlink
此特定名称的链接数。对于表示目录的名称,此值必须至少为2(一个用于目录本身,一个用于其中的./条目)。您的资源管理器可以修改此成员。
-
RDEV
包含字符特殊设备的设备编号和命名特殊设备的rdev编号。
-
mtime_ns,atime_ns和ctime_ns
(QNX Neutrino 7.0或更高版本)POSIX时间成员的纳秒值,mtime,atime和ctime。
如果编译为64位体系结构,或者在编译32位体系结构时包含<sys/iofunc.h>之前定义IOFUNC_NS_TIMESTAMP_SUPPORT,则包括这些字段。
The optional iofunc_mount_t (mount) structure
mount结构的成员,特别是conf和flags成员,修改了一些iofunc层函数的行为。
如果需要修改安装结构的任何成员,请使用iofunc_mount_init()对其进行初始化。
例如,您的程序将文件保存到文件系统。您可以使用iofunc_mount_init()和iofunc_mount_set_time()为与文件系统使用的分辨率匹配的打开文件设置时间戳分辨率(POSIX要求)。
iofunc_mount_t结构是可选的,至少包含以下内容:
typedef struct _iofunc_mount { uint32_t flags; uint32_t conf; dev_t dev; int32_t blocksize; iofunc_funcs_t *funcs; void *power;
size_t size; uint32_t ex_flags; uint32_t timeres; uint64_t reserved[4]; } iofunc_mount_t; |
变量是:
-
flags
包含一个相关位(清单常量IOFUNC_MOUNT_32BIT),表示此资源管理器使用的偏移量为32位(与扩展的64位偏移量相反)。用户可修改的挂载标志定义为IOFUNC_MOUNT_FLAGS_PRIVATE(参见<sys/iofunc.h>)。
-
conf
包含几个位:
IOFUNC_PC_CHOWN_RESTRICTED
导致_IO_CHOWN消息的默认处理程序以POSIX定义的方式表现为“chown-restricted”。
IOFUNC_PC_NO_TRUNC
对iofunc层库没有影响,但是由iofunc层的默认_IO_PATHCONF处理程序返回。
IOFUNC_PC_SYNC_IO
表示文件系统支持同步I/O操作。如果未设置此位,可能会发生以下情况:O_DSYNC, O_RSYNC, or O_SYNC
IOFUNC_PC_LINK_DIR
控制是否允许root链接和取消链接目录。
IOFUNC_PC_ACL
指示资源管理器是否支持访问控制列表。有关ACL的更多信息,请参阅QNX Neutrino程序员指南中的使用访问控制列表(ACL)。
IOFUNC_PC_EXT
调用iofunc_mount_init()时自动设置以设置iofunc_mount_t结构。
请注意,上面提到的conf成员选项由iofunc层_IO_PATHCONF默认处理程序返回。
-
dev
包含文件系统的设备编号。此数字将返回到struct stat st_dev成员中的客户端stat()函数。
-
blocksize
包含设备的块大小。在资源管理器的文件系统类型上,这指示磁盘的本机块大小,例如512字节。
-
funcs
包含以下结构:
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); int (*attr_lock)(IOFUNC_ATTR_T *attr); int (*attr_unlock)(IOFUNC_ATTR_T *attr); int (*attr_trylock)(IOFUNC_ATTR_T *attr); }; |
哪里:
-
nfuncs
表示结构中存在的函数数量;你应该用清单常量_IOFUNC_NFUNCS填充它。
-
ocb_calloc()和ocb_free()
允许您基于每个挂载点覆盖OCB(请参阅“Extending the POSIX-Layer Data Structures”一章中的“Extending the OCB and attribute structures”)。如果这些成员为NULL,则使用默认库版本(iofunc_ocb_calloc()和iofunc_ocb_free())。您必须指定这两个函数中的两个或两个;它们作为匹配对运行。 -
attr_lock(),attr_unlock()和attr_trylock()
允许您创建锁定,解锁和尝试锁定属性结构的功能的自定义版本。
-
power
保留供将来使用。
-
size
包含iofunc_mount_t函数的大小。由iofunc_mount_init()设置。
-
ext_flags
扩展可能的标志值范围。
-
timers
包含iofunc函数和结构的时间戳分辨率。由iofunc_mount_set_time()设置。
-
reserved
保留供将来使用。