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(temp_file));
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);
96 /* SKIP this test if O_DIRECT is not available on this fs */
103 memset(buf, 0, BUFLEN);
105 iov.iov_len = BUFLEN;
106 io_prep_preadv2(&iocb, fd, &iov, 1, 0, RWF_NOWAIT);
108 ret = io_submit(ctx, 1, &iocbp);
111 * io_submit will return -EINVAL if RWF_NOWAIT is not supported by
112 * the kernel, and EOPNOTSUPP if it's not supported by the fs.
115 if (ret == -EINVAL || ret == -ENOTSUP) {
116 fprintf(stderr, "RWF_NOWAIT not supported by %s.\n",
117 ret == -EINVAL ? "kernel" : "file system");
126 ret = io_getevents(ctx, 1, 1, &event, NULL);
129 perror("io_getevents");
134 * We expect -EAGAIN due to the existence of a page cache page
135 * for the file system block we are writing.
137 if (event.res != -EAGAIN) {
138 fprintf(stderr, "Expected -EAGAIN, got %lu\n", event.res);
143 * An O_DIRECT write to the page will force the page out of the
144 * page cache, allowing the subsequent RWF_NOWAIT I/O to complete.
146 ret = pwrite(fd, buf, BUFLEN, 0);
153 * Now retry the RWF_NOWAIT I/O. This should succeed.
155 ret = io_submit(ctx, 1, &iocbp);
162 ret = io_getevents(ctx, 1, 1, &event, NULL);
165 perror("io_getevents");
169 if (event.res != BUFLEN) {
170 fprintf(stderr, "Expected %d, got %lu\n", BUFLEN, event.res);