如何使用 linux 本机 AIO 将数据写入不是 512*n 字节的偏移量?

How to write data into an offset which is not 512*n bytes using linux native AIO?

我正在编写一些像 Bittorrent 客户端这样的应用程序来从网上下载文件并将其写入本地文件。我将获取部分数据并写入文件。

比如我下载一个1GB的文件,我会得到offset 100, data: 312 bytes, offset 1000000, data: 12345, offset 4000000, data: 888 bytes.

我正在使用 Linux 原生 AIO(io_setupio_submitio_getevents),我找到了这个

When using linux kernel AIO, files are required to be opened in O_DIRECT mode. This introduces further requirements of all read and write operations to have their file offset, memory buffer and size be aligned to 512 bytes.

那么如何将数据写入非 512 对齐的偏移量?

例如,首先我将 4 个字节写入一个文件,所以我必须这样做:

fd = open("a.txt", O_CREAT | O_RDWR | O_DIRECT, 0666);
struct iocb cb;
char data[512] = "asdf";
cb.aio_buf = ALIGN(data, 512);
cb.aio_offset = 512;
cb.aio_nbytes = 512;

那我想在asdf之后追加数据:

struct iocb cb2;
char data2[512] = "ghij";
cb2.aio_buf = ALIGN(data2, 512);
cb2.aio_offset = 5;
cb2.aio_nbytes = 512;

写的时候会报错

Invalid argument (-22)

那么怎么做呢?

如果您不使用 O_DIRECT,您必须执行驱动程序会执行的操作。也就是说,读取整个块,更新你想要的部分,然后写回。块设备根本不允许较小的访问。

自己动手做效率会更高(比如你可以用一次读写的代价更新同一个block中多个断开连接的序列)。但是,由于您没有让驱动程序完成工作,因此您也无法在 read-modify-write 操作中获得任何原子性保证。

你不知道。 Linux AIO API 没有用,尤其是对于您正在尝试做的事情。它是为了 Oracle 的缘故而添加的,Oracle 想要绕过内核的文件系统和块设备缓冲层以实现 Reasons™。它与 POSIX AIO 或其他合理的人在谈论 "AIO".

时的意思没有任何关系