bufinfo_t 结构简要介绍了 I/O 请求。start、done、wait-start 和 wait-done 探测器中的 args[0] 指向对应于 I/O 请求的缓冲区。bufinfo_t 结构定义如下所示:
typedef struct bufinfo { int b_flags; /* flags */ size_t b_bcount; /* number of bytes */ caddr_t b_addr; /* buffer address */ uint64_t b_blkno; /* expanded block # on device */ uint64_t b_lblkno; /* block # on device */ size_t b_resid; /* # of bytes not transferred */ size_t b_bufsize; /* size of allocated buffer */ caddr_t b_iodone; /* I/O completion routine */ dev_t b_edev; /* extended device */ } bufinfo_t;
b_flags 成员指示 I/O 缓冲区的状态,它由不同状态值的按位或的结果组成。表 27–3 中介绍了有效的状态值。
表 27–3 b_flags 值
B_DONE |
指示数据传送已完成。 |
B_ERROR |
指示 I/O 传送错误。它与 b_error 字段一起设置。 |
B_PAGEIO |
指示分页的 I/O 请求中正在使用该缓冲区。有关更多信息,请参见 b_addr 字段的说明。 |
B_PHYS |
指示正在对指向用户数据区的物理(直接)I/O 使用该缓冲区。 |
B_READ |
指示将从外围设备中读取数据到主内存中。 |
B_WRITE |
指示将数据从主内存传送到外围设备。 |
B_ASYNC |
I/O 请求为异步请求,不会被等待。wait-start 和 wait-done 探测器不会对异步 I/O 请求触发。请注意,定向为异步的某些 I/O 可能不会设置 B_ASYNC:异步 I/O 子系统可能通过使单独的工作线程执行同步 I/O 操作来实现异步请求。 |
b_bcount 字段表示要作为 I/O 请求一部分进行传送的字节数。
除非设置了 B_PAGEIO,否则 b_addr 字段表示 I/O 请求的虚拟地址。除非设置了 B_PHYS(此情况下该地址为用户虚拟地址),否则该地址为内核虚拟地址。如果设置了 B_PAGEIO,则 b_addr 字段将包含内核专用数据。仅能设置 B_PHYS 和 B_PAGEIO 的其中之一,否则将不会设置任何标志。
b_lblkno 字段标识设备上要访问的逻辑块。逻辑块到物理块(如柱面、磁轨等)的映射由设备定义。
b_resid 字段设置为由于发生错误而未传送的字节数。
b_bufsize 字段包含分配的缓冲区大小。
b_iodone 字段标识 I/O 完成时内核中调用的特定例程。
b_error 字段可能包含发生 I/O 错误时从驱动程序返回的错误代码。b_error 将与在 b_flags 成员中设置的 B_ERROR 位一起设置。
b_edev 字段包含所访问设备的主要和次要设备编号。使用者可使用 D 子例程 getmajor() 和 getminor() 从 b_edev 字段中提取主要和次要设备编号。