Как записать данные в смещение, которое не составляет 512 * n байт, используя встроенный AIO Linux? - PullRequest
0 голосов
/ 23 мая 2019

Я пишу какое-то приложение, например, клиент Bittorrent, чтобы загрузить файл из сети и записать его в локальный файл. Я получу частичные данные и напишу в файл.

Например, я скачаю 1 ГБ файл, получу offset 100, data: 312 bytes, offset 1000000, data: 12345, offset 4000000, data: 888 bytes.

Я использую встроенный Linux AIO (io_setup, io_submit, io_getevents), я нашел это

При использовании AIO ядра Linux, файлы должны открываться в режиме O_DIRECT. Это вводит дополнительные требования ко всем операциям чтения и записи, чтобы их смещение файла, буфер памяти и размер были выровнены до 512 байт.

Так как я могу записать данные в какое-то смещение, которое не выровнено по 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)

Так как это сделать?

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Ты не. Linux AIO API бесполезен , особенно не для того, что вы пытаетесь сделать. Он был добавлен ради Oracle, который хотел обойти файловые системы ядра и заблокировать буферный слой устройства для Reasons ™. Он не имеет ничего общего с POSIX AIO или другими вещами, которые имеют в виду разумные люди, когда говорят о «AIO».

1 голос
/ 23 мая 2019

Вы должны сделать то, что сделал бы драйвер, если бы вы не использовали O_DIRECT.То есть прочитайте весь блок, обновите нужную часть и запишите ее обратно.Блочные устройства просто не разрешают меньший доступ.

Самостоятельное выполнение может быть более эффективным (например, вы можете обновить несколько отключенных последовательностей в одном блоке за одну операцию чтения и записи).Однако, поскольку вы не позволяете драйверу выполнять свою работу, вы также не получаете никаких гарантий атомарности при выполнении операции чтения-изменения-записи.

...