
浅谈POSIX 层数据结构1.在POSIX 层数据结构iofunc_ocb_t开放控制块结构用于跟踪客户端对资源管理器提供的特定服务的访问。此信息通常以每次开放为基础。iofunc_attr_t属性结构包含每个资源的信息iofunc_mount_t挂载结构包含每个挂载点的信息三者关系图POSIX 层数据结构2.OCB structure(iofunc_ocb_t) 是什么2.1iofunc_ocb_t 结构体iofunc_ocb_t 其结构如下C#include sys/iofunc.htypedef struct _iofunc_ocb {IOFUNC_ATTR_T *attr;int32_t ioflag;off_t offset; //根据宏的不同会有不一样的定义uint16_t sflag;uint16_t flags;void *reserved;} iofunc_ocb_t;attr指向属性结构的指针如上图该结构是iofunc_attr_t。当然你也可以自己定义结构对定义IOFUNC_ATTR_T修改即可ioflag打开资源的模式eg. 读取、写入、阻塞。打开模式传递给客户端的open() 与ioflag值相对应。如下所示信息继承自传递给打开处理程序的消息中 的 io_connect_t 结构offset资源中的读/写偏移量例如我们在文件中的当前lseek()位置以多种方式定义以适应 32 位和 64 位偏移量。资源管理器可以修改此偏移量sflag定义共享模式。此信息继承自传递给io_open处理程序的消息中可用的io_connect_t结构flags以下位中的零个或多个的组合IOFUNC_OCB_PRIVILEGED -执行open的特权进程即rootIOFUNC_OCB_MMAP -客户端的mmap调用正在使用此OCBIOFUNC_OCB_MMAP_UNIQUE -mmap处理程序的提示以提供唯一的映射3.iofunc_attr_t 是什么可以看到标准 iofunc_ocb_t OCB 有一个名为 attr 的成员 它是指向属性结构的指针。这样做是为了让 OCB 能够访问有关设备的信息3.1iofunc_attr_t 结构体C#include sys/iofunc.htypedef 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;uint16_t reserved;off_t nbytes; //同iofunc_ocb_t结构体中的offsetino_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指向挂载结构的指针此指针的使用方式与从 OCB 指向属性结构的指针的使用方式相同不同之处在于此值可以为NULL**mmap_list**被POSIX的iofunc_mmap_default()和iofunc_mmap_default_ext()内部使用lock_list被POSIX的iofunc_lock_default()内部使用lockobj和lock供锁定属性结构的方法。要支持资源管理器中的多线程您需要锁定属性结构以便每次只允许一个线程更改它。可以递归锁定属性结构默认行为是使用lock成员这是一个内置的锁互斥锁。如果您使用 iofunc_attr_init() 初始化结构它会使用静态锁初始化程序 初始化内置锁互斥锁 ( lock )。当调用某些处理函数即IO_* 时 资源管理器层会自动锁定属性结构使用 iofunc_attr_lock() 。您可以通过调用iofunc_attr_lock() 或 iofunc_attr_trylock()来锁定属性结构 您可以通过调用iofunc_attr_unlock()来解锁它 。如果要使用外部锁对象请通过将lockobj成员指向外部锁对象来覆盖内置锁 。您还需要提供自己的函数来锁定和解锁属性结构并在iofunc_mount_t结构中设置funcs结构的相应成员flags**count**表示因任何原因打开该属性结构的OCB数量。例如如果一个客户端有一个OCB用于读取打开另一个客户端有另一个OCB用于读/写打开并且这两个OCB都指向该属性结构那么计数值将为2表示有两个客户端打开了这个资源。**rcount**读者数量。在给定的示例中对于计数rcount的值也将为2因为有两个客户端正在读取资源。-**wcount**写入者数量。在为count给出的示例中wcount的值为1因为只有一个客户端打开了此资源以供写入。rlocks表示在特定资源上具有读锁的OCB的数量。如果为零则表示没有读锁但可能有写锁。wlocks与rlock相同但用于写锁。nbytes资源的大小以字节为单位。例如如果此资源描述了一个特定文件并且该文件的大小为7756字节则nbytes成员将包含数字7756。inode包含每个挂载点必须唯一的文件或资源序列号。inode不应为零因为零传统上表示未使用的文件uid此资源所有者的用户IDgid此资源所有者的组IDmtime文件修改时间每当处理客户端write时更新或至少失效。atime文件访问时间每当处理返回超过零字节的客户端read时更新或至少失效ctime文件更改时间每当处理客户端write、chown或chmod时更新或至少失效。mode文件模式。这些是来自sys/stat. h的标准S_*值例如S_IFCHR或者八进制表示例如0664表示所有者和组的读/写权限以及其他的只读权限。nlink客户端的stat函数调用返回的文件链接数。rdev对于字符特殊设备该字段由主要和次要设备代码组成最低有效位置的10位次要设备代码接下来的6位是主要设备编号。对于其他类型的设备它包含设备编号。有关设备编号inode和我们的朋友rdev更多讨论请参见下文。**mtime_ns, atime_ns, and ctime_ns**POSIX时间成员、mtime、atime和ctime的纳秒值。4.iofunc_mount_t 是什么安装结构包含多个属性结构所共有的信息4.1iofunc_mount_t 结构体Ctypedef struct _iofunc_mount {uint32_t flags;uint32_t conf;dev_t dev;int32_t blocksize;iofunc_funcs_t *funcs;} iofunc_mount_t;The flags member contains at least one flag, IOFUNC_MOUNT_32BIT. This flag indicates that offset in the OCB, and nbytes and inode in the attributes structure, are 32-bit. Note that you can define your own flags in flags, using any of the bits from the constant IOFUNC_MOUNT_FLAGS_PRIVATE.flag标志成员至少包含一个标志IOFUNC_MOUNT_32BIT。该标志表示OCB中的偏移量以及属性结构中的nbytes和inode是32位。请注意您可以使用常量IOFUNC_MOUNT_FLAGS_PRIVATE中的任何位在标志中定义自己的标志。confIOFUNC_PC_CHOWN_RESTRICTED- 指示文件系统是否以受chown限制的方式运行这意味着是否只允许root来chown文件。IOFUNC_PC_NO_TRUNC- 表示文件系统不截断名称。IOFUNC_PC_SYNC_IO- 表示文件系统支持同步I/O操作。如果未设置此位可能会发生以下情况默认的iofunc层_IO_OPEN处理程序iofunc_open_default失败如果客户端指定O_DSYNC O_RSYNC, or O_SYNC.iofunc_sync_verify函数返回EINVAL尝试使用fcntl或devctl命令设置O_DSYNC、O_RSYNC或O_SYNCDCMD_ALL_SETFLAGS失败。IOFUNC_PC_LINK_DIR- 表示允许链接/取消链接目录。IOFUNC_PC_ACL- 指示资源管理器是否支持权限改造列表。有关ACL的详细信息请参阅QNXOS程序员指南中的使用访问控制列表ACL。devdev成员包含设备号如 Of device numbers, inodes, and our friend rdev.。blocksize块大小成员以字节为单位描述设备的本机块大小。例如在典型的 rotating-medium 存储系统上值为512Ctypedef 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);} iofunc_funcs_t;nfuncs与连接和I/O功能表一样nfuncs成员应该被填充为表的当前大小。请使用常量 _IOFUNC_NFUNCS。ocb_calloc 和 ocb_free 函数指针可以填充为函数的地址以便在分配或取消分配 OCB 时调用。我们将在后面讨论为什么要使用这些功能当我们谈论扩展 OCB 时。