2 * Copyright 2017, Red Hat, Inc.
6 * RWF_NOWAIT will cause -EAGAIN to be returned in the io_event for
7 * any I/O that cannot be serviced without blocking the submission
8 * thread. Instances covered by the kernel at the time this test was
10 * - O_DIRECT I/O to a file offset that has populated page cache pages
11 * - the submission context cannot obtain the inode lock
12 * - space allocation is necessary
13 * - we need to wait for other I/O (e.g. in the misaligned I/O case)
17 * The easiest of these to test is that a direct I/O is writing to a
18 * file offset with populated page cache. We also test to ensure that
19 * we can perform I/O in the absence of the above conditions.
21 * Author: Jeff Moyer <jmoyer@redhat.com>
33 #define TEMPLATE "21.XXXXXX"
37 #define RWF_NOWAIT 0x00000008
44 char temp_file[sizeof(TEMPLATE)];
46 strncpy(temp_file, TEMPLATE, sizeof(TEMPLATE));
47 fd = mkstemp(temp_file);
62 struct iocb iocb, *iocbp = &iocb;
63 struct io_event event;
64 char buf[BUFLEN] __attribute__((aligned (4096)));
67 fd = open_temp_file();
71 memset(&ctx, 0, sizeof(ctx));
72 ret = io_setup(1, &ctx);
74 fprintf(stderr, "io_setup failed with %d\n", ret);
79 * Perform a buffered write to a file. This instantiates the
80 * block and adds the page to the page cache.
82 memset(buf, 0xa, BUFLEN);
83 ret = write(fd, buf, BUFLEN);
90 * Now attempt an aio/dio pwritev2 with the RWF_NONBLOCK flag
93 flags = fcntl(fd, F_GETFL);
94 ret = fcntl(fd, F_SETFL, flags | O_DIRECT);
100 memset(buf, 0, BUFLEN);
102 iov.iov_len = BUFLEN;
103 io_prep_preadv2(&iocb, fd, &iov, 1, 0, RWF_NOWAIT);
105 ret = io_submit(ctx, 1, &iocbp);
108 * io_submit will return -EINVAL if RWF_NOWAIT is not supported.
111 if (ret == -EINVAL) {
112 fprintf(stderr, "RWF_NOWAIT not supported by kernel.\n");
113 /* just return success */
121 ret = io_getevents(ctx, 1, 1, &event, NULL);
124 perror("io_getevents");
129 * We expect -EAGAIN due to the existence of a page cache page
130 * for the file system block we are writing.
132 if (event.res != -EAGAIN) {
133 fprintf(stderr, "Expected -EAGAIN, got %lu\n", event.res);
138 * An O_DIRECT write to the page will force the page out of the
139 * page cache, allowing the subsequent RWF_NOWAIT I/O to complete.
141 ret = pwrite(fd, buf, BUFLEN, 0);
148 * Now retry the RWF_NOWAIT I/O. This should succeed.
150 ret = io_submit(ctx, 1, &iocbp);
157 ret = io_getevents(ctx, 1, 1, &event, NULL);
160 perror("io_getevents");
164 if (event.res != BUFLEN) {
165 fprintf(stderr, "Expected %d, got %lu\n", BUFLEN, event.res);