Чтение файла с использованием libaio с флагом O_DIRECT

Я читаю файл с использованием асинхронного libaio.
Код ниже показывает, как я это делаю. Код работает нормально,
но теперь я хочу переключиться в режим O_DIRECT, чтобы избежать кеширования файлов.
Когда я изменяю строку 25 на fd = open («./ testfile», O_RDONLY | O_DIRECT);
программа перестает работать правильно. (io_getevents не возвращает данных).
Не могли бы вы помочь мне настроить программу так, чтобы она корректно работала также с флагом O_DIRECT?

заранее спасибо

ОС: Ubuntu 12.10 3.5.0-26-generic)

1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <sys/param.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <libaio.h>
10
11 int main(int argc, char* argv[]) {
12
13   struct iocb cb;
14   struct iocb* iocbs = &cb;
15   struct io_event events[1];
16   char data[4096];
17   io_context_t ctx;
18   int fd;
19   int res;
20
21   memset(&ctx, 0, sizeof(ctx));
22   memset(&cb, 0, sizeof(cb));
23   memset(&data, 0, sizeof(data));
24
25   fd = open("./testfile", O_RDONLY);
26
27   if(io_setup(1, &ctx) < 0) {
28     printf("io_setup error\n");
29     exit(-1);
30   }
31   printf("io_setup OK\n");
32
33   // submit read request
34   io_prep_pread(&cb, fd, &data, 1024, 0);
35   res = io_submit(ctx, 1, &iocbs);
36   if(res < 0) {
37     printf("io_submit error\n");
38     exit(-2);
39   }
40   printf("io_submit OK: %d\n", res);
41
42   // get events
43   res = io_getevents(ctx, 0, 1, events, NULL);
44   if(res < 0) {
44   if(res < 0) {
45     printf("io_getevents Error: %d", res);
46     exit(-3);
47   }
48   printf("io_getevents OK: %d %li %li\n", res, events[0].res, events[0].res2);
49
50   // dump data received
51   char data_prefix[16];
52   strncpy(data_prefix, data, 15);
53   data_prefix[15] = 0;
54   printf("data: %s\n", data_prefix);
55
56   res = io_destroy(ctx);
57   if(res < 0) {
58     printf("io_destroy Error: %d\n", res);
59     exit(-4);
60   }
61   printf("io_destroy OK: %d\n", res);
62
63   res = close(fd);
64   printf("close: %d\n", res);
65 }

0

Решение

Вам нужно выровнять буфер до 512 байт, чтобы O_DIRECT работал правильно. До io_prep_pread:

char *data;
posix_memalign(&data, 512, 1024);

Обратите внимание, что размер прочитанного должен быть кратным 512.

2

Другие решения

+ Изменить char *data; to void* data;

тогда делай
posix_memalign (&Данные, 512,1024);

0