write(int sg_fd, const void * buffer, size_t count)。在之前的文档中讨论了基于 struct sg_header 的控制块的 write() 操作:www.torque.net/sg/p/scsi-generic.txt(即 sg 版本 2 文档)。本节介绍当给定基于 struct sg_io_hdr 的控制块时 write() 的操作。
“buffer”应该指向 sg_io_hdr_t 类型的对象,“count”应该是 sizeof(sg_io_hdr_t) [它可以更大,但多余的部分将被忽略]。如果 write() 调用成功,则“count”将作为结果返回。
在通过 read() 完成任何已完成的请求之前,最多可以排队 SG_MAX_QUEUE (16) 个 write()。尝试排队超过此数量将导致 EDOM 错误。[1] write() 命令应该或多或少立即返回。[2]
版本 2 sg 驱动程序将最大队列长度默认为 1(并提供 SG_SET_COMMAND_Q ioctl() 以将其切换到 SG_MAX_QUEUE)。因此,为了向后兼容,仅在其 write() 中接收 sg_header 结构的文件描述符将具有默认的“最大”队列长度 1。一旦 write() 看到 sg_io_hdr_t 结构,则该文件描述符上的最大队列长度将切换到 SG_MAX_QUEUE。
sg 驱动程序尊重 'buffer' 指针上的 “const”。数据是从指向的 sg_io_hdr 对象中读取的。重要的是,这是在内部记录 'sbp' 和 'dxferp' 的时候(即不是从提供给相应 read() 的 sg_io_hdr 对象中读取)。
[1] | 还应考虑 SCSI 设备和适配器驱动程序的命令队列功能。为此,ioctl(SG_GET_SCSI_ID) 返回的 sg_scsi_id::h_cmd_per_lun 和 sg_scsi_id::d_queue_depth 值可能很有用。此外,一些在其 INQUIRY 响应中表明它们可以接受命令队列的设备在实际尝试排队时反应不佳。 |
[2] | 它有很小的可能性会花费一些时间等待命令块变为可用。在这种情况下,等待是可中断的。如果 O_NONBLOCK 处于活动状态,则这种情况将导致 EAGAIN。 |