O_DIRECT模式引入了所有读和写的进一步要求 写操作以使其文件偏移,内存缓冲区和大小为 对齐为512个字节。
这到底是什么意思?
例如
struct iocb cb;
char data[4096];
cb.aio_buf = (uint64_t)data;
cb.aio_offset = 512;
cb.aio_nbytes = 4096;
这是否意味着数据大小应为512 * n?且偏移量应为512 * n?
我将4096更改为7777,将偏移量更改为333,看来工作正常。
答案 0 :(得分:1)
偏移量,缓冲区地址,大小必须对齐512字节,否则它将报告 无效的参数(errno = -22)
下面是测试用例
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdint.h>
#include <errno.h>
#include <linux/aio_abi.h>
#include <syscall.h>
#define align(p, a) (((long)(p) + (a - 1)) & ~(a - 1))
static inline int io_setup(unsigned nr_events, aio_context_t *ctx_idp)
{
return syscall(__NR_io_setup, nr_events, ctx_idp);
}
static inline int io_destroy(aio_context_t ctx)
{
return syscall(__NR_io_destroy, ctx);
}
static inline int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
{
return syscall(__NR_io_submit, ctx, nr, iocbpp);
}
static inline int io_getevents(aio_context_t ctx, long min_nr, long nr,
struct io_event *events, struct timespec *timeout)
{
return syscall(__NR_io_getevents, ctx, min_nr, nr, events, timeout);
}
int main(int argc, char *argv[])
{
int fd, rc;
char data[8192];
aio_context_t ctx = 0;
struct io_event events;
struct iocb cb;
struct iocb *cblist[] = {&cb};
fd = open("a.txt", O_CREAT | O_RDWR | O_DIRECT, 0666);
if (fd < 0)
return -1;
rc = io_setup(1, &ctx);
memset(&cb, 0, sizeof(cb));
cb.aio_buf = align(data, 512);
cb.aio_offset = 512;
cb.aio_nbytes = 4096;
cb.aio_fildes = fd;
cb.aio_lio_opcode = IOCB_CMD_PWRITE;
rc = io_submit(ctx, 1, cblist);
if (rc < 0) {
printf("io_submit: error=%d\n", rc);
goto error_exit;
}
rc = io_getevents(ctx, 1, 1, &events, NULL);
if (rc != 1) {
fprintf(stderr, "io_getevents failed: %s.\n", strerror(errno));
goto error_exit;
}
if (events.res < 0)
printf("write error: %s (%lld)\n", strerror(-events.res), events.res);
else
printf("write result: %lld\n", events.res);
rc = io_destroy(ctx);
error_exit:
close(fd);
return 0;
}