【问题标题】:What does "O_DIRECT 512-byte aligned" mean?“O_DIRECT 512 字节对齐”是什么意思?
【发布时间】:2019-04-01 01:57:49
【问题描述】:

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 和 offset 改成 333,好像工作正常。

【问题讨论】:

    标签: c linux io


    【解决方案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;
    }
    

    【讨论】:

    • 我正在使用&lt;linux/aio_abi.h&gt;, 3.10.0-862.14.4.el7.x86_64
    • 看看我新修改的代码。如果不对齐会报错。
    • 非常感谢!最后一个快速问题。如果我使用 linux aio,我必须使用 O_DIRECT 才能使用异步读/写吗?如果我使用 posix aio,可以省略 O_DIRECT 吗?
    • 可以去掉O_DIRECT,使用bufferio,让内核处理,但是会生成pagecache,和posix aio或者linux aio没有关系。
    猜你喜欢
    • 2014-09-24
    • 2012-04-30
    • 2016-06-11
    • 2011-05-09
    • 2023-03-25
    • 2012-01-17
    • 2023-03-19
    • 2021-08-23
    相关资源
    最近更新 更多