“ O_DIRECT 512字节对齐”是什么意思?

时间:2019-04-01 01:57:50

标签: c linux io

  

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,看来工作正常。

1 个答案:

答案 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;
}