Imported Upstream version 0.3.113 upstream upstream/0.3.113
authorTizenOpenSource <tizenopensrc@samsung.com>
Wed, 28 Dec 2022 07:17:18 +0000 (16:17 +0900)
committerTizenOpenSource <tizenopensrc@samsung.com>
Wed, 28 Dec 2022 07:17:18 +0000 (16:17 +0900)
31 files changed:
harness/Makefile
harness/cases/16.t
harness/cases/17.t
harness/cases/18.t
harness/cases/19.t
harness/cases/21.t
harness/cases/22.t
harness/cases/23.t [new file with mode: 0644]
harness/cases/5.t
harness/main.c
harness/runtests.sh
libaio.spec
man/io.3
man/io_cancel.3
man/io_fsync.3
man/io_getevents.3
man/io_prep_fsync.3
man/io_prep_pread.3
man/io_prep_pwrite.3
man/io_queue_init.3
man/io_queue_release.3
man/io_queue_run.3
man/io_queue_wait.3
man/io_set_callback.3
man/io_submit.3
src/Makefile
src/compat-0_1.c
src/libaio.h
src/struct_offsets.c [new file with mode: 0644]
src/syscall.h
src/vsys_def.h

index f477737..4f225d3 100644 (file)
@@ -6,13 +6,22 @@ PROGS:=$(PARTPROGS) $(EXTRAPROGS)
 HARNESS_SRCS:=main.c
 # io_queue.c
 
-CFLAGS+=-Wall -Werror -I../src -g -O2 -DPAGE_SIZE=$(shell getconf PAGESIZE)
+CFLAGS+=-Wall -Werror -I../src -g -O2
 #-lpthread -lrt
 
+# gcc-11 does not like the test case in 3.t that
+# passes an invalid pointer (-1) to the kernel, so
+# tell the compiler we do not need a warning here
+cases/3.p:     CFLAGS+=-Wno-stringop-overflow
+
+# Change this on the build line to run tests against the installed libraries:
+# make LIBAIO=-laio partcheck
+LIBAIO?=../src/libaio.a
+
 all: $(PROGS)
 
 $(PROGS): %.p: %.t $(HARNESS_SRCS)
-       $(CC) $(CFLAGS) -DTEST_NAME=\"$<\" -o $@ main.c ../src/libaio.a -lpthread
+       $(CC) $(CFLAGS) -DTEST_NAME=\"$<\" -o $@ main.c $(LIBAIO) -lpthread
 
 clean:
        rm -f $(PROGS) *.o runtests.out rofile wofile rwfile
index 5a546ff..4d24b04 100644 (file)
 #define SYS_eventfd 318
 #elif defined(__alpha__)
 #define SYS_eventfd 478
-#elif defined(__aarch64__)
-/* arm64 does not implement eventfd, only eventfd2 */
+#elif defined(__aarch64__) || defined(__loongarch__) || defined(__riscv)
+/* these recent architectures do not implement eventfd, only eventfd2 */
 #define USE_EVENTFD2
 #ifndef SYS_eventfd2
 #define SYS_eventfd2 19
-#endif /* __aarch64__ */
+#endif /* __aarch64__ || __riscv */
 #else
 #error define SYS_eventfd for your arch!
 #endif
index 38ada4d..b4b6660 100644 (file)
@@ -119,7 +119,7 @@ void prune(io_context_t io_ctx, int max_ios, int getevents_type)
 
 void run_test(int max_ios, int getevents_type)
 {
-       int fd, ret;
+       int fd, ret, flags;
        long i, to_submit;
        struct iocb **iocb_sub;
        io_context_t io_ctx;
@@ -137,9 +137,16 @@ void run_test(int max_ios, int getevents_type)
        events = calloc(max_ios, sizeof(*events));
 
        unlink(filename);
-       fd = open(filename, O_CREAT | O_RDWR | O_DIRECT, 0644);
+       fd = open(filename, O_CREAT | O_RDWR, 0644);
        assert(fd >= 0);
 
+       /*
+        * Use O_DIRECT if it's available.  If it's not, the test code
+        * will still operate correctly, just potentially slower.
+        */
+       flags = fcntl(fd, F_GETFL, 0);
+       fcntl(fd, F_SETFL, flags | O_DIRECT);
+
        ret = ftruncate(fd, max_ios * io_size);
        assert(!ret);
 
index 5587ceb..e8dbcd1 100644 (file)
 
 #define THREADS_NUM 100
 
+static size_t page_size;
+
 void
 aio_worker(void *ptr)
 {
-       int i, j, fd;
-       char buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+       int i, j, fd, ret;
+       char *buffer = NULL;
+
+       ret = posix_memalign((void **)&buffer, page_size, page_size);
+       assert(ret == 0);
+       assert(buffer != NULL);
 
        fd = open(FILENAME, O_DIRECT|O_RDONLY);
+       if (fd < 0 && errno == EINVAL)
+               exit(3); /* skip this test, O_DIRECT is unavailable */
        assert(fd >= 0);
 
        for (i = 0; i < 1000; i++) {
@@ -55,19 +63,19 @@ aio_worker(void *ptr)
                struct iocb *cbs[1];
 
                assert(!io_queue_init(1, &ctx));
-               io_prep_pread(&cb, fd, buffer, PAGE_SIZE, 0);
+               io_prep_pread(&cb, fd, buffer, page_size, 0);
                cbs[0] = &cb;
 
-               memset(buffer, '0', PAGE_SIZE);
+               memset(buffer, '0', page_size);
                assert(io_submit(ctx, 1, &cbs[0]) == 1);
                // wait random time (0-500ms) ?
 
                io_destroy(ctx);
-               memset(buffer, DESTROY_PATTERN, PAGE_SIZE);
+               memset(buffer, DESTROY_PATTERN, page_size);
                // wait random for (0-500ms) ?
 
                // check it is still DESTROY_PATTERN
-               for (j = 0; j < PAGE_SIZE; j++) {
+               for (j = 0; j < page_size; j++) {
                        if (buffer[j] != DESTROY_PATTERN) {
                                fprintf(stderr,
                                        "Buffer has unexpected character: %c\n",
@@ -77,6 +85,7 @@ aio_worker(void *ptr)
                }
        }
 
+       free(buffer);
        close(fd);
 }
 
@@ -84,15 +93,22 @@ int
 test_main(void)
 {
        int i, fd, ret;
-       char buffer[PAGE_SIZE];
+       char *buffer = NULL;
        pthread_t threads[THREADS_NUM];
 
+       page_size = sysconf(_SC_PAGESIZE);
+       assert(page_size >= 1);
+
+       ret = posix_memalign((void **)&buffer, page_size, page_size);
+       assert(ret == 0);
+       assert(buffer != NULL);
+
        fd = open(FILENAME, O_CREAT|O_TRUNC|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
        assert(fd != -1);
 
-       memset(buffer, FILEPATTERN, PAGE_SIZE);
-       ret = write(fd, buffer, PAGE_SIZE);
-       assert(ret == PAGE_SIZE);
+       memset(buffer, FILEPATTERN, page_size);
+       ret = write(fd, buffer, page_size);
+       assert(ret == page_size);
        close(fd);
 
        for (i = 0; i < THREADS_NUM; i++) {
index 4989510..ba1c620 100644 (file)
@@ -38,15 +38,21 @@ struct aio_ring {
 int
 open_temp_file(void)
 {
-       int fd;
+       int fd, flags;
        char template[sizeof(TEMPLATE)];
 
-       strncpy(template, TEMPLATE, sizeof(TEMPLATE));
-       fd = mkostemp(template, O_DIRECT);
+       strncpy(template, TEMPLATE, sizeof(template));
+       fd = mkstemp(template);
        if (fd < 0) {
                perror("mkstemp");
                exit(1);
        }
+       /*
+        * O_DIRECT is desirable, but not required for this test.
+        */
+       flags = fcntl(F_GETFL, 0);
+       fcntl(F_SETFL, flags | O_DIRECT);
+
        unlink(template);
        return fd;
 }
index 441eaa8..4164c02 100644 (file)
@@ -43,7 +43,7 @@ open_temp_file()
        int fd;
        char temp_file[sizeof(TEMPLATE)];
 
-       strncpy(temp_file, TEMPLATE, sizeof(TEMPLATE));
+       strncpy(temp_file, TEMPLATE, sizeof(temp_file));
        fd = mkstemp(temp_file);
        if (fd < 0) {
                perror("mkstemp");
@@ -92,7 +92,10 @@ test_main()
         */
        flags = fcntl(fd, F_GETFL);
        ret = fcntl(fd, F_SETFL, flags | O_DIRECT);
-       if (ret != 0) {
+       if (ret < 0) {
+               /* SKIP this test if O_DIRECT is not available on this fs */
+               if (errno == EINVAL)
+                       return 3;
                perror("fcntl");
                return 1;
        }
@@ -105,13 +108,15 @@ test_main()
        ret = io_submit(ctx, 1, &iocbp);
 
        /*
-        * io_submit will return -EINVAL if RWF_NOWAIT is not supported.
+        * io_submit will return -EINVAL if RWF_NOWAIT is not supported by
+        * the kernel, and EOPNOTSUPP if it's not supported by the fs.
         */
        if (ret != 1) {
-               if (ret == -EINVAL) {
-                       fprintf(stderr, "RWF_NOWAIT not supported by kernel.\n");
-                       /* just return success */
-                       return 0;
+               if (ret == -EINVAL || ret == -ENOTSUP) {
+                       fprintf(stderr, "RWF_NOWAIT not supported by %s.\n",
+                               ret == -EINVAL ? "kernel" : "file system");
+                       /* skip this test */
+                       return 3;
                }
                errno = -ret;
                perror("io_submit");
index c7428a8..d6a8986 100644 (file)
@@ -76,14 +76,17 @@ int test_main(void)
 
                ret = io_setup(1, &ctx);
                if (ret) {
-                       printf("child: io_setup failed\n");
+                       printf("child: io_setup failed: %s\n", strerror(-ret));
                        return 1;
                }
 
                io_prep_poll(&iocb, pipe1[0], POLLIN);
                ret = io_submit(ctx, 1, iocbs);
                if (ret != 1) {
-                       printf("child: io_submit failed\n");
+                       /* if poll isn't supported, skip the test */
+                       if (ret == -EINVAL)
+                               return 3;
+                       printf("child: io_submit failed: %s\n", strerror(-ret));
                        return 1;
                }
 
@@ -95,8 +98,13 @@ int test_main(void)
                        ret = io_pgetevents(ctx, 1, 1, &ev, &to, &sigmask);
                } while (ret == 0);
 
+               /* SKIP if the syscall has not been implemented. */
+               if (ret == -ENOSYS)
+                       return 3;
+
                if (ret != -EINTR) {
-                       printf("child: io_pgetevents did not set errno to EINTR\n");
+                       printf("child: io_pgetevents did not set errno to "
+                              "EINTR: %s\n", strerror(-ret));
                        return 1;
                }
 
@@ -114,21 +122,29 @@ int test_main(void)
 
                ret = io_setup(1, &ctx);
                if (ret) {
-                       printf("parent: io_setup failed\n");
+                       printf("parent: io_setup failed: %s\n", strerror(-ret));
                        return 1;
                }
 
                ret = io_submit(ctx, 1, iocbs);
                if (ret != 1) {
-                       printf("parent: io_submit failed\n");
+                       /* if poll isn't supported, skip the test */
+                       if (ret == -EINVAL)
+                               return 3;
+                       printf("parent: io_submit failed with %d: %s\n",
+                              ret, strerror(-ret));
                        return 1;
                }
 
                kill(p, SIGUSR1);
 
                ret = io_pgetevents(ctx, 1, 1, &ev, NULL, &sigmask);
+               /* SKIP if the syscall has not been implemented. */
+               if (ret == -ENOSYS)
+                       return 3;
                if (ret < 0) {
-                       printf("parent: io_pgetevents failed\n");
+                       printf("parent: io_pgetevents failed: %s\n",
+                              strerror(-ret));
                        return 1;
                }
                if (ret != 1) {
@@ -147,3 +163,9 @@ int test_main(void)
                return 0;
        }
 }
+/*
+ * Local variables:
+ *  mode: c
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/harness/cases/23.t b/harness/cases/23.t
new file mode 100644 (file)
index 0000000..cc5a8a1
--- /dev/null
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/*
+ * Verify that aio poll doesn't miss any events.  This is a regression test for
+ * kernel commit 363bee27e258 ("aio: keep poll requests on waitqueue until
+ * completed").
+ *
+ * This test repeatedly does the following operations in parallel:
+ *
+ *     Thread 1: Aio-poll the read end of a pipe, then wait for it to complete.
+ *     Thread 2: Splice a byte to the pipe.
+ *     Thread 3: Read from the pipe, then splice another byte to it.
+ *
+ * The pipe will never be empty at the end, so the poll should always complete.
+ * With the bug, that didn't always happen, as the second splice sometimes
+ * didn't cause a wakeup due to the waitqueue entry being temporarily removed,
+ * as per the following buggy sequence of events:
+ *
+ *     1. Thread 1 adds the poll waitqueue entry.
+ *     2. Thread 2 does the first splice.  This calls the poll wakeup function,
+ *        which deletes the waitqueue entry [BUG!], then schedules the async
+ *        completion work.
+ *     3. Thread 3 reads from the pipe.
+ *     4. Async work sees that the pipe isn't ready.
+ *     5. Thread 3 splices some data to the pipe, but doesn't call the poll
+ *        wakeup function because the waitqueue is currently empty.
+ *     6. Async work re-adds the waitqueue entry, as the pipe wasn't ready.
+ *
+ * The reason we use splice() rather than write() is because in order for step
+ * (2) to not complete the poll inline, the kernel must not pass an event mask
+ * to the wakeup function.  This is the case for splice() to a pipe, but not
+ * write() to a pipe (at least in the kernel versions with the bug).
+ */
+#include <poll.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/wait.h>
+
+static int tmpfd;
+static int pipefds[2];
+static pthread_barrier_t barrier;
+static bool exiting;
+
+static void fail(const char *format, ...)
+{
+       va_list va;
+
+       va_start(va, format);
+       vfprintf(stderr, format, va);
+       putc('\n', stderr);
+       va_end(va);
+       exit(1);
+}
+
+static void fail_errno(const char *format, ...)
+{
+       va_list va;
+
+       va_start(va, format);
+       vfprintf(stderr, format, va);
+       fprintf(stderr, ": %s", strerror(errno));
+       putc('\n', stderr);
+       va_end(va);
+       exit(1);
+}
+
+/* Thread 2 */
+static void *thrproc2(void *arg)
+{
+       for (;;) {
+               off_t offset = 0;
+
+               pthread_barrier_wait(&barrier);
+               if (exiting)
+                       break;
+
+               /* Splice a byte to the pipe. */
+               if (splice(tmpfd, &offset, pipefds[1], NULL, 1, 0) != 1)
+                       fail_errno("splice failed in thread 2");
+
+               pthread_barrier_wait(&barrier);
+       }
+       return NULL;
+}
+
+/* Thread 3 */
+static void *thrproc3(void *arg)
+{
+       for (;;) {
+               char c;
+               off_t offset = 0;
+
+               pthread_barrier_wait(&barrier);
+               if (exiting)
+                       break;
+
+               /* Read a byte from the pipe. */
+               if (read(pipefds[0], &c, 1) != 1)
+                       fail_errno("read failed in thread 3");
+
+               /* Splice a byte to the pipe. */
+               if (splice(tmpfd, &offset, pipefds[1], NULL, 1, 0) != 1)
+                       fail_errno("splice failed in thread 3");
+
+               pthread_barrier_wait(&barrier);
+       }
+       return NULL;
+}
+
+static int child_process(void)
+{
+       int ret;
+       io_context_t ctx = NULL;
+       pthread_t t2, t3;
+       int i;
+       struct iocb iocb;
+       struct iocb *iocbs[] = { &iocb };
+       struct io_event event;
+       struct timespec timeout = { .tv_sec = 5 };
+       char c;
+
+       ret = io_setup(1, &ctx);
+       if (ret != 0) {
+               errno = -ret;
+               fail_errno("io_setup failed");
+       }
+
+       if (pipe(pipefds) != 0)
+               fail_errno("pipe failed");
+
+       errno = pthread_barrier_init(&barrier, NULL, 3);
+       if (errno)
+               fail_errno("pthread_barrier_init failed");
+
+       errno = pthread_create(&t2, NULL, thrproc2, NULL);
+       if (errno)
+               fail_errno("pthread_create failed");
+
+       errno = pthread_create(&t3, NULL, thrproc3, NULL);
+       if (errno)
+               fail_errno("pthread_create failed");
+
+       for (i = 0; i < 5000; i++) {
+               /* Thread 1 */
+
+               /* Submit a poll request. */
+               io_prep_poll(&iocb, pipefds[0], POLLIN);
+               ret = io_submit(ctx, 1, iocbs);
+               if (ret != 1) {
+                       /* If aio poll isn't supported, skip the test. */
+                       errno = -ret;
+                       if (errno == EINVAL) {
+                               printf("aio poll is not supported\n");
+                               return 3;
+                       }
+                       fail_errno("io_submit failed");
+               }
+
+               /* Tell the other threads to continue. */
+               pthread_barrier_wait(&barrier);
+
+               /*
+                * Wait for the poll to complete.  Wait at most 5 seconds, in
+                * case we hit the bug so the poll wouldn't otherwise complete.
+                */
+               ret = io_getevents(ctx, 1, 1, &event, &timeout);
+               if (ret < 0) {
+                       errno = -ret;
+                       fail_errno("io_getevents failed");
+               }
+               if (ret == 0) {
+                       /*
+                        * The poll eventually timed out rather than giving us
+                        * an event, so we've detected the bug.
+                        */
+                       fail("FAIL: poll missed an event!");
+               }
+
+               /* Wait for the other threads to finish their iteration. */
+               pthread_barrier_wait(&barrier);
+
+               /* The pipe has 1 byte; read it to get back to initial state. */
+               if (read(pipefds[0], &c, 1) != 1)
+                       fail_errno("read failed in thread 1");
+       }
+       exiting = true;
+       pthread_barrier_wait(&barrier);
+       errno = pthread_join(t2, NULL);
+       if (errno)
+               fail_errno("pthread_join failed");
+       errno = pthread_join(t3, NULL);
+       if (errno)
+               fail_errno("pthread_join failed");
+       return 0;
+}
+
+int test_main(void)
+{
+       char tmpfile_name[] = "/tmp/aio.XXXXXX";
+       int ret;
+       int ncpus;
+       int i;
+       int overall_status = 0;
+       int status;
+
+       /* Create a 1-byte temporary file. */
+       tmpfd = mkstemp(tmpfile_name);
+       if (tmpfd < 0) {
+               fprintf(stderr, "failed to create temporary file: %s\n",
+                       strerror(errno));
+               return 1;
+       }
+       if (pwrite(tmpfd, "X", 1, 0) != 1) {
+               fprintf(stderr, "failed to write to temporary file: %s\n",
+                       strerror(errno));
+               return 1;
+       }
+
+       /*
+        * Run the test in multiple processes to increase the chance of hitting
+        * the race condition.
+        */
+       ret = sysconf(_SC_NPROCESSORS_CONF);
+       if (ret < 1) {
+               fprintf(stderr, "failed to get number of CPUs: %s\n",
+                       strerror(errno));
+               return 1;
+       }
+       ncpus = ret;
+       for (i = 0; i < ncpus; i++) {
+               ret = fork();
+               if (ret < 0) {
+                       fprintf(stderr, "fork failed: %s\n", strerror(errno));
+                       return 1;
+               }
+               if (ret == 0)
+                       exit(child_process());
+       }
+       for (i = 0; i < ncpus; i++) {
+               if (wait(&status) < 0) {
+                       fprintf(stderr, "wait failed: %s\n", strerror(errno));
+                       return 1;
+               }
+               if (!WIFEXITED(status))
+                       overall_status = 1;
+               else if (overall_status == 0)
+                       overall_status = WEXITSTATUS(status);
+       }
+       unlink(tmpfile_name);
+       return overall_status;
+}
index 2b4b4bb..b0a7c56 100644 (file)
@@ -40,13 +40,12 @@ int test_main(void)
        buf = mmap(0, page_size, PROT_WRITE, MAP_SHARED, rwfd, 0);
        assert(buf != (char *)-1);
 
-       status |= attempt_rw(rwfd, buf, SIZE,  0,  READ, SIZE);
-
        /* Whether PROT_WRITE is readable is arch-dependent.  So compare
-        * against read result. */
-       res = read(rwfd, buf, SIZE);
+        * against write() result (to make the kernel read from buf). */
+       res = write(rwfd, buf, SIZE);
        if (res < 0)
                res = -errno;
+       status |= attempt_rw(rwfd, buf, SIZE,  0,  READ, SIZE);
        status |= attempt_rw(rwfd, buf, SIZE,  0, WRITE, res);
 
        return status;
index 9ecd5da..82e9c69 100644 (file)
@@ -26,15 +26,27 @@ char test_name[] = TEST_NAME;
 int main(void)
 {
        int res;
+       const char *test_result;
 
 #if defined(SETUP)
        SETUP;
 #endif
 
        res = test_main();
-       printf("test %s completed %s.\n", test_name, 
-               res ? "FAILED" : "PASSED"
-               );
+       switch(res) {
+       case 0:
+               test_result = "PASSED";
+               break;
+       case 3:
+               test_result = "SKIPPED";
+               break;
+       default:
+               test_result = "FAILED";
+               res = 1;
+               break;
+       }
+
+       printf("test %s completed %s.\n", test_name, test_result);
        fflush(stdout);
-       return res ? 1 : 0;
+       return res;
 }
index 717c72a..e9ceec8 100755 (executable)
@@ -2,6 +2,7 @@
 
 passes=0
 fails=0
+skips=0
 
 echo "Test run starting at" `date`
 
@@ -11,9 +12,20 @@ while [ $# -ge 1 ] ; do
        echo "Starting $this_test"
        $this_test 2>&1
        res=$?
-       if [ $res -eq 0 ] ; then str="" ; passes=$[passes + 1] ; else str=" -- FAILED" ; fails=$[fails + 1] ; fi
+       if [ $res -eq 0 ]; then
+               str="";
+               passes=$((passes + 1));
+       elif [ $res -eq 3 ]; then
+               str=" -- SKIPPED";
+               skips=$((skips + 1));
+       else
+               str=" -- FAILED"
+               fails=$((fails + 1));
+       fi
        echo "Completed $this_test with $res$str".
 done
 
-echo "Pass: $passes  Fail: $fails"
+echo "Pass: $passes  Fail: $fails  Skip: $skips"
 echo "Test run complete at" `date`
+
+exit $fails
index d1fa2cc..fc62371 100644 (file)
@@ -1,5 +1,5 @@
 Name: libaio
-Version: 0.3.112
+Version: 0.3.113
 Release: 1
 Summary: Linux-native asynchronous I/O access library
 License: LGPL
@@ -7,7 +7,7 @@ Group:  System Environment/Libraries
 Source: %{name}-%{version}.tar.gz
 BuildRoot: %{_tmppath}/%{name}-root
 # Fix ExclusiveArch as we implement this functionality on more architectures
-ExclusiveArch: i386 x86_64 ia64 s390 s390x ppc ppc64 ppc64pseries ppc64iseries alpha alphaev6 %{arm}
+ExclusiveArch: i386 x86_64 ia64 s390 s390x ppc ppc64 ppc64pseries ppc64iseries alpha alphaev6 %{arm} loongarch64
 
 %description
 The Linux-native asynchronous I/O facility ("async I/O", or "aio") has a
@@ -57,6 +57,13 @@ make install DESTDIR=$RPM_BUILD_ROOT prefix=/usr libdir=/%{_libdir}
 %attr(0644,root,root) %{_libdir}/libaio.a
 
 %changelog
+* Mon Mar 28 2022 Jeff Moyer <jmoyer@redhat.com> - 0.3.113-1
+- Fix padding in vector and sockaddr structures on 32 bit (Brett Holman)
+- Add a test case for missed poll events (Eric Biggers)
+- Add loongarch support (Yehui Ren)
+- man page cleanup and fixes (Guillem Jover)
+- assorted test harness fixess (Guillem Jover, Jeff Moyer)
+
 * Mon Oct 22 2018 Jeff Moyer <jmoyer@redhat.com> - 0.3.112-1
 - Add async poll support (Christoph Hellwig)
 - Use canonical DESTDIR= environment variable (Thomas Petazzoni)
index d910a68..bfa9836 100644 (file)
--- a/man/io.3
+++ b/man/io.3
@@ -1,25 +1,27 @@
-.TH io 3 2002-09-12 "Linux 2.4" Linux IO"
+.TH io 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io \- Asynchronous IO
-.SH SYNOPSYS
+.SH SYNOPSIS
 .nf
 .B #include <errno.h>
 .sp
 .br 
-.B #include <libio.h>
+.B #include <libaio.h>
 .sp
 .fi
 .SH DESCRIPTION
-The libaio library defines a new set of I/O operations which can
+The
+.B libaio
+library defines a new set of I/O operations which can
 significantly reduce the time an application spends waiting at I/O.  The
 new functions allow a program to initiate one or more I/O operations and
 then immediately resume normal work while the I/O operations are
 executed in parallel.  
 
 These functions are part of the library with realtime functions named
-.IR "libaio"
-.  They are not actually part of the 
-.IR "libc" 
+.BR libaio .
+They are not actually part of the
+.B libc
 binary.
 The implementation of these functions can be done using support in the
 kernel.
@@ -27,9 +29,9 @@ kernel.
 All IO operations operate on files which were opened previously.  There
 might be arbitrarily many operations running for one file.  The
 asynchronous I/O operations are controlled using a data structure named
-.IR "struct iocb"
+.B struct iocb
 It is defined in
-.IR "libio.h"
+.I libaio.h
 as follows.
 
 .nf
@@ -74,7 +76,7 @@ struct iocb {
 
 .fi
 .TP
-.IR "int aio_fildes"
+.BI int " aio_fildes"
 This element specifies the file descriptor to be used for the
 operation.  It must be a legal descriptor, otherwise the operation will
 fail.
@@ -82,58 +84,55 @@ fail.
 The device on which the file is opened must allow the seek operation.
 I.e., it is not possible to use any of the IO operations on devices
 like terminals where an 
-.IR "lseek"
+.BR lseek (2)
 call would lead to an error.
 .TP
-.IR "long u.c.offset"
+.BI long " u.c.offset"
 This element specifies the offset in the file at which the operation (input
 or output) is performed.  Since the operations are carried out in arbitrary
 order and more than one operation for one file descriptor can be
 started, one cannot expect a current read/write position of the file
 descriptor.
 .TP
-.IR "void *buf"
+.BI "void *" buf
 This is a pointer to the buffer with the data to be written or the place
 where the read data is stored.
 .TP
-.IR "long u.c.nbytes"
+.BI long " u.c.nbytes"
 This element specifies the length of the buffer pointed to by 
-.IR "io_buf"
-.
+.IR io_buf .
 .TP
-.IR "int aio_reqprio"
+.BI int " aio_reqprio"
 Is not currently used.
 .TP
 .B "IO_CMD_PREAD"
 Start a read operation.  Read from the file at position
-.IR "u.c.offset"
+.I u.c.offset
 and store the next 
-.IR "u.c.nbytes"
+.I u.c.nbytes
 bytes in the
 buffer pointed to by 
-.IR "buf"
-.
+.IR buf .
 .TP
 .B "IO_CMD_PWRITE"
 Start a write operation.  Write 
-.IR "u.c.nbytes" 
+.I u.c.nbytes
 bytes starting at
-.IR "buf"
+.I buf
 into the file starting at position 
-.IR "u.c.offset"
-.
+.IR u.c.offset .
 .TP
 .B "IO_CMD_NOP"
 Do nothing for this control block.  This value is useful sometimes when
 an array of 
-.IR "struct iocb"
+.B struct iocb
 values contains holes, i.e., some of the
 values must not be handled although the whole array is presented to the
-.IR "io_submit"
+.BR io_submit (3)
 function.
 .TP 
 .B "IO_CMD_FSYNC"
-.TP
+.TQ
 .B "IO_CMD_POLL"
 This is experimental.
 .SH EXAMPLE
@@ -175,11 +174,11 @@ static const char *srcname = NULL;
 static void io_error(const char *func, int rc)
 {
     if (rc == -ENOSYS)
-       fprintf(stderr, "AIO not in this kernel\n");
+       fprintf(stderr, "AIO not in this kernel\\n");
     else if (rc < 0 && -rc < sys_nerr)
-       fprintf(stderr, "%s: %s\n", func, sys_errlist[-rc]);
+       fprintf(stderr, "%s: %s\\n", func, sys_errlist[-rc]);
     else
-       fprintf(stderr, "%s: error %d\n", func, rc);
+       fprintf(stderr, "%s: error %d\\n", func, rc);
 
     if (dstfd > 0)
        close(dstfd);
@@ -198,7 +197,7 @@ static void wr_done(io_context_t ctx, struct iocb *iocb, long res, long res2)
        io_error("aio write", res2);
     }
     if (res != iocb->u.c.nbytes) {
-       fprintf(stderr, "write missed bytes expect %d got %d\n", iocb->u.c.nbytes, res2);
+       fprintf(stderr, "write missed bytes expect %d got %d\\n", iocb->u.c.nbytes, res2);
        exit(1);
     }
     --tocopy;
@@ -224,7 +223,7 @@ static void rd_done(io_context_t ctx, struct iocb *iocb, long res, long res2)
     if (res2 != 0)
        io_error("aio read", res2);
     if (res != iosize) {
-       fprintf(stderr, "read missing bytes expect %d got %d\n", iocb->u.c.nbytes, res);
+       fprintf(stderr, "read missing bytes expect %d got %d\\n", iocb->u.c.nbytes, res);
        exit(1);
     }
 
@@ -284,7 +283,7 @@ int main(int argc, char *const *argv)
                char *buf = (char *) malloc(iosize);
 
                if (NULL == buf || NULL == io) {
-                   fprintf(stderr, "out of memory\n");
+                   fprintf(stderr, "out of memory\\n");
                    exit(1);
                }
 
@@ -336,16 +335,16 @@ int main(int argc, char *const *argv)
  */
 .fi
 .SH "SEE ALSO"
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 9a16084..8c6910e 100644 (file)
@@ -1,4 +1,4 @@
-.TH io_cancel 2 2002-09-03 "Linux 2.4" "Linux AIO"
+.TH io_cancel 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_cancel \- Cancel io requests
 .SH SYNOPSIS
@@ -9,7 +9,7 @@ io_cancel \- Cancel io requests
 .B #include <libaio.h>
 .sp
 .br
-.BI "int io_cancel(io_context_t ctx, struct iocb *iocb)"
+.BI "int io_cancel(io_context_t " ctx ", struct iocb *" iocb ");"
 .br
 .sp
 struct iocb {
@@ -21,8 +21,11 @@ struct iocb {
 };
 .fi
 .SH DESCRIPTION
-Attempts to cancel an iocb previously passed to io_submit.  If
-the operation is successfully cancelled, the resulting event is
+Attempts to cancel an
+.I iocb
+previously passed to
+.BR io_submit (3).
+If the operation is successfully cancelled, the resulting event is
 copied into the memory pointed to by result without being placed
 into the completion queue.
 .PP
@@ -33,33 +36,37 @@ have to be overwritten soon.  As an example, assume an application, which
 writes data in files in a situation where new incoming data would have
 to be written in a file which will be updated by an enqueued request.
 .SH "RETURN VALUES"
-0 is returned on success , otherwise returns Errno.
+\fI0\fP is returned on success, otherwise returns \fIerrno\fP.
 .SH ERRORS
 .TP
 .B EFAULT 
 If any of the data structures pointed to are invalid.
 .TP
 .B EINVAL 
-If aio_context specified by ctx_id is
-invalid.  
+If
+.I aio_context
+specified by
+.I ctx
+is invalid.
 .TP
 .B EAGAIN
-If the iocb specified was not
-cancelled.  
+If the
+.I iocb
+specified was not cancelled.
 .TP
 .B ENOSYS 
-if not implemented.
+If not implemented.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 53eb63d..06538c4 100644 (file)
@@ -1,13 +1,13 @@
-./" static inline int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)
-./" {
-./"    io_prep_fsync(iocb, fd);
-./"    io_set_callback(iocb, cb);
-./"    return io_submit(ctx, 1, &iocb);
-./" }
-.TH io_fsync 3 2002-09-12 "Linux 2.4" Linux AIO"
+.\" static inline int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)
+.\" {
+.\"    io_prep_fsync(iocb, fd);
+.\"    io_set_callback(iocb, cb);
+.\"    return io_submit(ctx, 1, &iocb);
+.\" }
+.TH io_fsync 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_fsync \- Synchronize a file's complete in-core state with that on disk
-.SH SYNOPSYS
+.SH SYNOPSIS
 .nf
 .B #include <errno.h>
 .sp
@@ -15,7 +15,7 @@ io_fsync \- Synchronize a file's complete in-core state with that on disk
 .B #include <libaio.h>
 .sp
 .br
-.BI "int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)"
+.BI "int io_fsync(io_context_t " ctx ", struct iocb *" iocb ", io_callback_t " cb ", int " fd ");"
 .sp
 struct iocb {
        void            *data;
@@ -39,8 +39,8 @@ resources (mainly computation time).
 Calling this function forces all I/O operations operating queued at the
 time of the function call operating on the file descriptor
 .IR "iocb->io_fildes"
-into the synchronized I/O completion state .  The 
-.IR "io_fsync"
+into the synchronized I/O completion state.  The
+.BR io_fsync ()
 function returns
 immediately but the notification through the method described in
 .IR "io_callback"
@@ -49,7 +49,10 @@ file descriptor have terminated and the file is synchronized.  This also
 means that requests for this very same file descriptor which are queued
 after the synchronization request are not affected.
 .SH "RETURN VALUES"
-Returns 0, otherwise returns errno.
+Returns
+.BR 0 ,
+otherwise returns
+.IR errno .
 .SH ERRORS
 .TP
 .B EFAULT
@@ -58,7 +61,7 @@ referenced data outside of the program's accessible address space.
 .TP
 .B EINVAL
 .I ctx
-refers to an unitialized aio context, the iocb pointed to by 
+refers to an uninitialized aio context, the iocb pointed to by
 .I iocbs
 contains an improperly initialized iocb, 
 .TP
@@ -68,15 +71,15 @@ The iocb contains a file descriptor that does not exist.
 .B EINVAL
 The file specified in the iocb does not support the given io operation.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_getevents(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_getevents (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 5062daa..6ff686d 100644 (file)
@@ -1,22 +1,22 @@
-./"/* io_getevents:
-./" *      Attempts to read at least min_nr events and up to nr events from
-./" *      the completion queue for the aio_context specified by ctx_id.  May
-./" *      fail with -EINVAL if ctx_id is invalid, if min_nr is out of range,
-./" *      if nr is out of range, if when is out of range.  May fail with
-./" *      -EFAULT if any of the memory specified to is invalid.  May return
-./" *      0 or < min_nr if no events are available and the timeout specified
-./" *      by when has elapsed, where when == NULL specifies an infinite
-./" *      timeout.  Note that the timeout pointed to by when is relative and
-./" *      will be updated if not NULL and the operation blocks.  Will fail
-./" *      with -ENOSYS if not implemented.
-./" */
-./"asmlinkage long sys_io_getevents(io_context_t ctx_id,
-./"                                 long min_nr,
-./"                                 long nr,
-./"                                 struct io_event *events,
-./"                                 struct timespec *timeout)
-./"
-.TH io_getevents 2 2002-09-03 "Linux 2.4" "Linux AIO"
+.\"/* io_getevents:
+.\" *      Attempts to read at least min_nr events and up to nr events from
+.\" *      the completion queue for the aio_context specified by ctx.  May
+.\" *      fail with -EINVAL if ctx is invalid, if min_nr is out of range,
+.\" *      if nr is out of range, if when is out of range.  May fail with
+.\" *      -EFAULT if any of the memory specified to is invalid.  May return
+.\" *      0 or < min_nr if no events are available and the timeout specified
+.\" *      by when has elapsed, where when == NULL specifies an infinite
+.\" *      timeout.  Note that the timeout pointed to by when is relative and
+.\" *      will be updated if not NULL and the operation blocks.  Will fail
+.\" *      with -ENOSYS if not implemented.
+.\" */
+.\"asmlinkage long sys_io_getevents(io_context_t ctx,
+.\"                                 long min_nr,
+.\"                                 long nr,
+.\"                                 struct io_event *events,
+.\"                                 struct timespec *timeout)
+.\"
+.TH io_getevents 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_getevents, aio_pgetevents \- Read resulting events from io requests
 .SH SYNOPSIS
@@ -42,19 +42,25 @@ struct io_event {
         unsigned        PADDED(res2, __pad4);
 };
 .sp
-.BI "int io_getevents(io_context_t " ctx ",  long " nr ", struct io_event *" events "[], struct timespec *" timeout ");"
-.BI "int io_pgetevents(io_context_t " ctx ",  long " nr ", struct io_event *" events "[], struct timespec *" timeout ", sigset_t *" sigmask ");"
+.BI "int io_getevents(io_context_t " ctx ", long " nr ", struct io_event *" events "[], struct timespec *" timeout ");"
+.BI "int io_pgetevents(io_context_t " ctx ", long " nr ", struct io_event *" events "[], struct timespec *" timeout ", sigset_t *" sigmask ");"
 .fi
 .SH DESCRIPTION
-Attempts to read  up to nr events from
-the completion queue for the aio_context specified by ctx.  
+Attempts to read up to
+.I nr
+events from the completion queue for the aio_context specified by
+.IR ctx .
 .SH "RETURN VALUES"
 May return
-0 if no events are available and the timeout specified
-by when has elapsed, where when == NULL specifies an infinite
+.B 0
+if no events are available and the timeout specified
+by when has elapsed, where
+.I when
+== NULL specifies an infinite
 timeout.  Note that the timeout pointed to by when is relative and
-will be updated if not NULL and the operation blocks.  Will fail
-with ENOSYS if not implemented.
+will be updated if not NULL and the operation blocks.  Will fail with
+.B ENOSYS
+if not implemented.
 .SS io_pgetevents()
 The relationship between
 .BR io_getevents ()
@@ -64,16 +70,15 @@ is analogous to the relationship between
 .BR select (2)
 and
 .BR pselect (2):
-similar
+similar to
 .BR pselect (2),
 .BR pgetevents ()
 allows an application to safely wait until either an aio completion
-events happens or until a signal is caught.
+event happens or until a signal is caught.
 .PP
 The following
 .BR io_pgetevents ()
 call:
-call:
 .PP
 .in +4n
 .EX
@@ -107,28 +112,34 @@ argument is specified as NULL, then no signal mask manipulation is
 performed (and thus
 .BR io_pgetevents ()
 behaves the same as
-.BR io_getevents()
-) .
+.BR io_getevents() ).
 .SH ERRORS
 .TP
 .B EINVAL 
-if ctx_id is invalid, if min_nr is out of range,
-if nr is out of range, if when is out of range.  
+If
+.I ctx
+is invalid, if
+.I min_nr
+is out of range, if
+.I nr
+is out of range, if
+.I when
+is out of range.
 .TP
 .B EFAULT 
-if any of the memory specified to is invalid.  
+If any of the memory specified to is invalid.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3),
-.BR pselect(2)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3),
+.BR pselect (2).
index 4cf935a..419dfeb 100644 (file)
@@ -1,14 +1,14 @@
-./" static inline void io_prep_fsync(struct iocb *iocb, int fd)
-./" {
-./"    memset(iocb, 0, sizeof(*iocb));
-./"    iocb->aio_fildes = fd;
-./"    iocb->aio_lio_opcode = IO_CMD_FSYNC;
-./"    iocb->aio_reqprio = 0;
-./" }
-.TH io_prep_fsync 3 2002-09-12 "Linux 2.4" Linux AIO"
+.\" static inline void io_prep_fsync(struct iocb *iocb, int fd)
+.\" {
+.\"    memset(iocb, 0, sizeof(*iocb));
+.\"    iocb->aio_fildes = fd;
+.\"    iocb->aio_lio_opcode = IO_CMD_FSYNC;
+.\"    iocb->aio_reqprio = 0;
+.\" }
+.TH io_prep_fsync 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_prep_fsync \- Synchronize a file's complete in-core state with that on disk
-.SH SYNOPSYS
+.SH SYNOPSIS
 .nf
 .B #include <errno.h>
 .br
@@ -16,7 +16,7 @@ io_prep_fsync \- Synchronize a file's complete in-core state with that on disk
 .B #include <libaio.h>
 .br
 .sp
-.BI "static inline void io_prep_fsync(struct iocb *iocb, int fd)"
+.BI "static inline void io_prep_fsync(struct iocb *" iocb ", int " fd ");"
 .sp
 struct iocb {
        void            *data;
@@ -28,62 +28,86 @@ struct iocb {
 .sp
 .fi
 .SH DESCRIPTION
-This is an inline convenience function for setting up an iocbv for a FSYNC request.
-.br
+This is an inline convenience function for setting up an
+.I iocbv
+for a
+.B FSYNC
+request.
+.
+.PP
 The file for which
-.TP 
+.nf
 .IR "iocb->aio_fildes = fd" 
-is a descriptor is set up with
-the command
-.TP 
-.IR "iocb->aio_lio_opcode = IO_CMD_FSYNC:
+.fi
+is a descriptor is set up with the command
+.nf
+.IR "iocb->aio_lio_opcode = IO_CMD_FSYNC"
+.fi
 .
 .PP
-The io_prep_fsync() function shall set up an IO_CMD_FSYNC operation
-to asynchronously force all I/O
+The
+.BR io_prep_fsync ()
+function shall set up an
+.B IO_CMD_FSYNC
+operation to asynchronously force all I/O
 operations associated with the file indicated by the file
-descriptor aio_fildes member of the iocb structure referenced by
+descriptor
+.I aio_fildes
+member of the
+.I iocb
+structure referenced by
 the iocb argument and queued at the time of the call to
-io_submit() to the synchronized I/O completion state. The function
+.BR io_submit ()
+to the synchronized I/O completion state. The function
 call shall return when the synchronization request has been
 initiated or queued to the file or device (even when the data
 cannot be synchronized immediately).
 
 All currently queued I/O operations shall be completed as if by a call
-to fsync(); that is, as defined for synchronized I/O file
+to
+.BR fsync (2);
+that is, as defined for synchronized I/O file
 integrity completion. If the
-operation queued by io_prep_fsync() fails, then, as for fsync(),
+operation queued by
+.BR io_prep_fsync ()
+fails, then, as for
+.BR fsync (2),
 outstanding I/O operations are not guaranteed to have
 been completed.
 
-If io_prep_fsync() succeeds, then it is only the I/O that was queued
-at the time of the call to io_submit() that is guaranteed to be
+If
+.BR io_prep_fsync ()
+succeeds, then it is only the I/O that was queued
+at the time of the call to
+.BR io_submit (3)
+that is guaranteed to be
 forced to the relevant completion state. The completion of
 subsequent I/O on the file descriptor is not guaranteed to be
 completed in a synchronized fashion.
 .PP
-This function returns immediately . To schedule the operation, the
+This function returns immediately. To schedule the operation, the
 function
-.IR io_submit
+.BR io_submit (3)
 must be called.
 .PP
-Simultaneous asynchronous operations using the same iocb produce
-undefined results.
+Simultaneous asynchronous operations using the same
+.I iocb
+produce undefined results.
 .SH "RETURN VALUES"
-None
+None.
 .SH ERRORS
-None
+None.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 5938aec..e0756a7 100644 (file)
@@ -1,17 +1,17 @@
-./" static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
-./" {
-./"    memset(iocb, 0, sizeof(*iocb));
-./"    iocb->aio_fildes = fd;
-./"    iocb->aio_lio_opcode = IO_CMD_PREAD;
-./"    iocb->aio_reqprio = 0;
-./"    iocb->u.c.buf = buf;
-./"    iocb->u.c.nbytes = count;
-./"    iocb->u.c.offset = offset;
-./" }
-.TH io_prep_pread 3 2002-09-12 "Linux 2.4" Linux AIO"
+.\" static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
+.\" {
+.\"    memset(iocb, 0, sizeof(*iocb));
+.\"    iocb->aio_fildes = fd;
+.\"    iocb->aio_lio_opcode = IO_CMD_PREAD;
+.\"    iocb->aio_reqprio = 0;
+.\"    iocb->u.c.buf = buf;
+.\"    iocb->u.c.nbytes = count;
+.\"    iocb->u.c.offset = offset;
+.\" }
+.TH io_prep_pread 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_prep_pread \- Set up asynchronous read
-.SH SYNOPSYS
+.SH SYNOPSIS
 .nf
 .B #include <errno.h>
 .sp
@@ -19,8 +19,8 @@ io_prep_pread \- Set up asynchronous read
 .B #include <libaio.h>
 .br
 .sp
-.BI "inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
-"
+.BI "inline void io_prep_pread(struct iocb *" iocb ", int " fd ", void *" buf ", size_t " count ", long long " offset ");"
+.
 .sp
 struct iocb {
        void            *data;
@@ -31,49 +31,43 @@ struct iocb {
 };
 .fi
 .SH DESCRIPTION
-.IR io_prep_pread 
+.BR io_prep_pread ()
 is an inline convenience function designed to facilitate the initialization of
 the iocb for an asynchronous read operation.
 
 The first
-.TP
-.IR "iocb->u.c.nbytes = count"
+.I iocb->u.c.nbytes = count
 bytes of the file for which
-.TP
-.IR "iocb->aio_fildes = fd"
+.I iocb->aio_fildes = fd
 is a descriptor are written to the buffer
 starting at
-.TP
-.IR "iocb->u.c.buf = buf"
-.
-.br
+.IR "iocb->u.c.buf = buf" .
 Reading starts at the absolute position
-.TP
-.IR "ioc->u.c.offset = offset"
+.I ioc->u.c.offset = offset
 in the file.
 .PP
-This function returns immediately . To schedule the operation, the
+This function returns immediately. To schedule the operation, the
 function 
-.IR io_submit
+.BR io_submit (3)
 must be called.
 .PP
-Simultaneous asynchronous operations using the same iocb produce
+Simultaneous asynchronous operations using the same \fIiocb\fP produce
 undefined results.
 .SH "RETURN VALUES"
-None
+None.
 .SH ERRORS
-None
+None.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 68b3500..b3770b4 100644 (file)
@@ -1,17 +1,17 @@
-./" static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
-./" {
-./"    memset(iocb, 0, sizeof(*iocb));
-./"    iocb->aio_fildes = fd;
-./"    iocb->aio_lio_opcode = IO_CMD_PWRITE;
-./"    iocb->aio_reqprio = 0;
-./"    iocb->u.c.buf = buf;
-./"    iocb->u.c.nbytes = count;
-./"    iocb->u.c.offset = offset;
-./" }
-.TH io_prep_pwrite 3 2002-09-12 "Linux 2.4" Linux AIO"
+.\" static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
+.\" {
+.\"    memset(iocb, 0, sizeof(*iocb));
+.\"    iocb->aio_fildes = fd;
+.\"    iocb->aio_lio_opcode = IO_CMD_PWRITE;
+.\"    iocb->aio_reqprio = 0;
+.\"    iocb->u.c.buf = buf;
+.\"    iocb->u.c.nbytes = count;
+.\"    iocb->u.c.offset = offset;
+.\" }
+.TH io_prep_pwrite 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_prep_pwrite \- Set up iocb for asynchronous writes
-.SH SYNOPSYS
+.SH SYNOPSIS
 .nf
 .B #include <errno.h>
 .br
@@ -19,8 +19,8 @@ io_prep_pwrite \- Set up iocb for asynchronous writes
 .B #include <libaio.h>
 .br
 .sp
-.BI "inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
-"
+.BI "inline void io_prep_pwrite(struct iocb *" iocb ", int " fd ", void *" buf ", size_t " count ", long long " offset ");"
+.
 .sp
 struct iocb {
        void            *data;
@@ -31,47 +31,42 @@ struct iocb {
 };
 .fi
 .SH DESCRIPTION
-io_prep_write is a convenicence function for setting up parallel writes.
+.BR io_prep_write ()
+is a convenience function for setting up parallel writes.
 
 The first
-.TP
 .IR "iocb->u.c.nbytes = count"
 bytes of the file for which
-.TP
 .IR "iocb->aio_fildes = fd"
 is a descriptor are written from the buffer
 starting at
-.TP
-.IR "iocb->u.c.buf = buf"
-.
-.br
+.IR "iocb->u.c.buf = buf" .
 Writing starts at the absolute position
-.TP
 .IR "ioc->u.c.offset = offset"
 in the file.
 .PP
-This function returns immediately . To schedule the operation, the
+This function returns immediately. To schedule the operation, the
 function
-.IR io_submit
+.BR io_submit (3)
 must be called.
 .PP
 Simultaneous asynchronous operations using the same iocb produce
 undefined results.
 .SH "RETURN VALUES"
-None
+None.
 .SH ERRORS
-None
+None.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 317f631..661f377 100644 (file)
@@ -1,4 +1,4 @@
-.TH io_queue_init 2 2002-09-03 "Linux 2.4" "Linux AIO"
+.TH io_queue_init 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_queue_init \- Initialize asynchronous io state machine
 
@@ -10,25 +10,31 @@ io_queue_init \- Initialize asynchronous io state machine
 .B #include <libaio.h>
 .br
 .sp
-.BI "int io_queue_init(int maxevents, io_context_t  *ctx );"
+.BI "int io_queue_init(int " maxevents ", io_context_t *" ctx ");"
 .sp
 .fi
 .SH DESCRIPTION
-.B io_queue_init
-Attempts to create an aio context capable of receiving at least 
-.IR maxevents
+.BR io_queue_init ()
+attempts to create an aio context capable of receiving at least
+.I maxevents
 events. 
-.IR ctx
+.I ctx
 must point to an aio context that already exists and must be initialized
 to 
-.IR 0
+.B 0
 before the call.
-If the operation is successful, *cxtp is filled with the resulting handle.
+If the operation is successful,
+.I *cxtp
+is filled with the resulting handle.
 .SH "RETURN VALUES"
 On success,
-.B io_queue_init
-returns 0.  Otherwise, -error is return, where
-error is one of the Exxx values defined in the Errors section.
+.BR io_queue_init ()
+returns
+.BR 0 .
+Otherwise, -error is return, where
+error is one of the Exxx values defined in the
+.B ERRORS
+section.
 .SH ERRORS
 .TP
 .B EFAULT
@@ -37,27 +43,31 @@ referenced data outside of the program's accessible address space.
 .TP
 .B EINVAL
 .I maxevents
-is <= 0 or 
+is <=
+.B 0
+or
 .IR ctx
-is an invalid memory locattion.
+is an invalid memory location.
 .TP
 .B ENOSYS 
-Not implemented
+Not implemented.
 .TP
 .B EAGAIN
 .IR "maxevents > max_aio_reqs"
-where max_aio_reqs is a tunable value.
+where
+.I max_aio_reqs
+is a tunable value.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 06b9ec0..7a67141 100644 (file)
@@ -1,4 +1,4 @@
-.TH io_queue_release 2 2002-09-03 "Linux 2.4" "Linux AIO"
+.TH io_queue_release 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_queue_release \- Release the context associated with the userspace handle
 .SH SYNOPSIS
@@ -8,41 +8,44 @@ io_queue_release \- Release the context associated with the userspace handle
 .B #include <libaio.h>
 .br
 .sp
-.BI "int io_queue_release(io_context_t ctx)"
+.BI "int io_queue_release(io_context_t " ctx ");"
 .sp
 .SH DESCRIPTION
 .B io_queue_release
-destroys the context associated with the userspace handle.    May cancel any outstanding
+destroys the context associated with the userspace handle. May cancel any outstanding
 AIOs and block on completion.
-
-.B cts.
+.
 .SH "RETURN VALUES"
 On success,
-.B io_queue_release
-returns 0.  Otherwise, -error is return, where
+.BR io_queue_release ()
+returns
+.BR 0 .
+Otherwise, -error is return, where
 error is one of the Exxx values defined in the Errors section.
 .SH ERRORS
 .TP
 .B EINVAL
 .I ctx 
-refers to an unitialized aio context, the iocb pointed to by
+refers to an uninitialized aio context, the
+.I iocb
+pointed to by
 .I iocbs 
-contains an improperly initialized iocb,
+contains an improperly initialized
+.IR iocb .
 .TP
 .B ENOSYS 
-Not implemented
+Not implemented.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_run(3),
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_run (3),
 .BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
-
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 57dd417..2bb9701 100644 (file)
@@ -1,4 +1,4 @@
-.TH io_queue_run 2 2002-09-03 "Linux 2.4" "Linux AIO"
+.TH io_queue_run 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_queue_run \- Handle completed io requests
 .SH SYNOPSIS
@@ -9,17 +9,19 @@ io_queue_run \- Handle completed io requests
 .B #include <libaio.h>
 .br
 .sp
-.BI "int io_queue_run(io_context_t  ctx );"
+.BI "int io_queue_run(io_context_t " ctx ");"
 .sp
 .fi
 .SH DESCRIPTION
-.B io_queue_run
-Attempts to read  all the events events from
-the completion queue for the aio_context specified by ctx_id.
+.BR io_queue_run ()
+attempts to read all the events from
+the completion queue for the aio_context specified by
+.IR ctx .
 .SH "RETURN VALUES"
 May return
-0 if no events are available.
-Will fail with -ENOSYS if not implemented.
+.B 0
+if no events are available.
+Will fail with -\fBENOSYS\fP if not implemented.
 .SH ERRORS
 .TP
 .B EFAULT
@@ -28,23 +30,25 @@ referenced data outside of the program's accessible address space.
 .TP
 .B EINVAL
 .I ctx 
-refers to an unitialized aio context, the iocb pointed to by
+refers to an uninitialized aio context, the
+.I iocb
+pointed to by
 .I iocbs 
-contains an improperly initialized iocb,
+contains an improperly initialized iocb.
 .TP
 .B ENOSYS 
-Not implemented
+Not implemented.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index 2306663..1cf4f0b 100644 (file)
@@ -1,4 +1,4 @@
-.TH io_queue_wait 2 2002-09-03 "Linux 2.4" "Linux AIO"
+.TH io_queue_wait 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_queue_wait \- Wait for io requests to complete
 .SH SYNOPSIS
@@ -9,22 +9,27 @@ io_queue_wait \- Wait for io requests to complete
 .B #include <libaio.h>
 .br
 .sp
-.BI "int io_queue_wait(io_context_t ctx, const struct timespec *timeout);"
+.BI "int io_queue_wait(io_context_t " ctx ", const struct timespec *" timeout ");"
 .fi
 .SH DESCRIPTION
-Attempts to read  an event from
-the completion queue for the aio_context specified by ctx_id.
+.BR io_queue_wait ()
+attempts to read an event from
+the completion queue for the aio_context specified by
+.IR ctx .
 .SH "RETURN VALUES"
 May return
-0 if no events are available and the timeout specified
+.B 0
+if no events are available and the timeout specified
 by when has elapsed, where when == NULL specifies an infinite
-timeout.  Note that the timeout pointed to by when is relative and
+\fItimeout\fP.  Note that the \fItimeout\fP pointed to by when is relative and
 will be updated if not NULL and the operation blocks.  Will fail
-with -ENOSYS if not implemented.
+with -\fBENOSYS\fP if not implemented.
 .SH "RETURN VALUES"
 On success,
-.B io_queue_wait
-returns 0.  Otherwise, -error is return, where
+.BR io_queue_wait ()
+returns
+.BR 0 .
+Otherwise, -error is return, where
 error is one of the Exxx values defined in the Errors section.
 .SH ERRORS
 .TP
@@ -34,23 +39,25 @@ referenced data outside of the program's accessible address space.
 .TP
 .B EINVAL
 .I ctx 
-refers to an unitialized aio context, the iocb pointed to by
+refers to an uninitialized aio context, the
+.I iocb
+pointed to by
 .I iocbs 
-contains an improperly initialized iocb,
+contains an improperly initialized iocb.
 .TP
 .B ENOSYS 
-Not implemented
+Not implemented.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_set_callback(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_set_callback (3),
+.BR io_submit (3),
+.BR errno (3).
index a8ca789..855f4b9 100644 (file)
@@ -1,8 +1,8 @@
-./"\ 3static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)
-.TH io_set_callback 3 2002-09-12 "Linux 2.4" Linux AIO"
+.\"static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)
+.TH io_set_callback 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_set_callback \- Set up io completion callback function
-.SH SYNOPSYS
+.SH SYNOPSIS
 .nf
 .B #include <errno.h>
 .br
@@ -10,7 +10,7 @@ io_set_callback \- Set up io completion callback function
 .B #include <libaio.h>
 .br
 .sp
-.BI "static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)"
+.BI "static inline void io_set_callback(struct iocb *" iocb ", io_callback_t " cb ");"
 .sp
 struct iocb {
        void            *data;
@@ -25,20 +25,23 @@ typedef void (*io_callback_t)(io_context_t ctx, struct iocb *iocb, long res, lon
 .fi
 .SH DESCRIPTION
 The callback is not done if the caller uses raw events from 
-io_getevents, only with the library helpers
+.BR io_getevents (3),
+only with the library helpers.
 .SH "RETURN VALUES"
+None.
 .SH ERRORS
+None.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_submit(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_submit (3),
+.BR errno (3).
index b6966ef..c15134f 100644 (file)
@@ -1,16 +1,16 @@
-./"/* sys_io_submit:
-./" *      Queue the nr iocbs pointed to by iocbpp for processing.  Returns
-./" *      the number of iocbs queued.  May return -EINVAL if the aio_context
-./" *      specified by ctx_id is invalid, if nr is < 0, if the iocb at
-./" *      *iocbpp[0] is not properly initialized, if the operation specified
-./" *      is invalid for the file descriptor in the iocb.  May fail with
-./" *      -EFAULT if any of the data structures point to invalid data.  May
-./" *      fail with -EBADF if the file descriptor specified in the first
-./" *      iocb is invalid.  May fail with -EAGAIN if insufficient resources
-./" *      are available to queue any iocbs.  Will return 0 if nr is 0.  Will
-./" *      fail with -ENOSYS if not implemented.
-./" */
-.TH io_submit 2 2002-09-02 "Linux 2.4" "Linux AIO"
+.\"/* sys_io_submit:
+.\" *      Queue the nr iocbs pointed to by iocbpp for processing.  Returns
+.\" *      the number of iocbs queued.  May return -EINVAL if the aio_context
+.\" *      specified by ctx is invalid, if nr is < 0, if the iocb at
+.\" *      *iocbpp[0] is not properly initialized, if the operation specified
+.\" *      is invalid for the file descriptor in the iocb.  May fail with
+.\" *      -EFAULT if any of the data structures point to invalid data.  May
+.\" *      fail with -EBADF if the file descriptor specified in the first
+.\" *      iocb is invalid.  May fail with -EAGAIN if insufficient resources
+.\" *      are available to queue any iocbs.  Will return 0 if nr is 0.  Will
+.\" *      fail with -ENOSYS if not implemented.
+.\" */
+.TH io_submit 3 2019-07-23 "Linux" "Linux AIO"
 .SH NAME
 io_submit \- Submit io requests
 .SH SYNOPSIS
@@ -32,33 +32,30 @@ struct iocb {
 };
 .fi
 .SH DESCRIPTION
-.B io_submit
+.BR io_submit ()
 submits
 .I nr
 iocbs for processing for a given io context ctx.
 
 The 
-.IR "io_submit"
+.BR io_submit ()
 function can be used to enqueue an arbitrary
 number of read and write requests at one time.  The requests can all be
 meant for the same file, all for different files or every solution in
 between.
 
-.IR "io_submit"
+.BR io_submit ()
 gets the 
-.IR "nr"
-requests from the array pointed to
-by 
-.IR "iocbs"
-.  The operation to be performed is determined by the
+.I nr
+requests from the array pointed to by
+.IR "iocbs" .
+The operation to be performed is determined by the
 .IR "aio_lio_opcode"
 member in each element of 
-.IR "iocbs"
-.  If this
-field is 
+.IR "iocbs" .
+If this field is
 .B "IO_CMD_PREAD"
-a read operation is enqueued, similar to a call
-of 
+a read operation is enqueued, similar to a call of
 .IR "io_prep_pread"
 for this element of the array (except that the way
 the termination is signalled is different, as we will see below).  If
@@ -75,10 +72,10 @@ in which case this element of
 .IR "iocbs"
 is simply ignored.  This
 ``operation'' is useful in situations where one has a fixed array of
-.IR "struct iocb"
+.B struct iocb
 elements from which only a few need to be handled at
 a time.  Another situation is where the 
-.IR "io_submit"
+.BR io_submit (3)
 call was
 canceled before all requests are processed  and the remaining requests have to be reissued.
 
@@ -86,15 +83,15 @@ The other members of each element of the array pointed to by
 .IR "iocbs"
 must have values suitable for the operation as described in
 the documentation for 
-.IR "io_prep_pread"
+.BR io_prep_pread (3)
 and 
-.IR "io_prep_pwrite"
+.BR io_prep_pwrite (3)
 above.
 
 The function returns immediately after
 having enqueued all the requests.  
 On success,
-.B io_submit
+.BR io_submit ()
 returns the number of iocbs submitted successfully.  Otherwise, -error is return, where 
 error is one of the Exxx values defined in the Errors section.
 .PP
@@ -110,26 +107,30 @@ referenced data outside of the program's accessible address space.
 .TP
 .B EINVAL
 .I ctx
-refers to an unitialized aio context, the iocb pointed to by 
+refers to an uninitialized aio context, the iocb pointed to by
 .I iocbs
 contains an improperly initialized iocb, 
 .TP
 .B EBADF
-The iocb contains a file descriptor that does not exist.
+The
+.I iocb
+contains a file descriptor that does not exist.
 .TP
 .B EINVAL
-The file specified in the iocb does not support the given io operation.
+The file specified in the
+.I iocb
+does not support the given io operation.
 .SH "SEE ALSO"
-.BR io(3),
-.BR io_cancel(3),
-.BR io_fsync(3),
-.BR io_getevents(3),
-.BR io_prep_fsync(3),
-.BR io_prep_pread(3),
-.BR io_prep_pwrite(3),
-.BR io_queue_init(3),
-.BR io_queue_release(3),
-.BR io_queue_run(3),
-.BR io_queue_wait(3),
-.BR io_set_callback(3),
-.BR errno(3)
+.BR io (3),
+.BR io_cancel (3),
+.BR io_fsync (3),
+.BR io_getevents (3),
+.BR io_prep_fsync (3),
+.BR io_prep_pread (3),
+.BR io_prep_pwrite (3),
+.BR io_queue_init (3),
+.BR io_queue_release (3),
+.BR io_queue_run (3),
+.BR io_queue_wait (3),
+.BR io_set_callback (3),
+.BR errno (3).
index 37ae219..d080a1b 100644 (file)
@@ -12,7 +12,7 @@ ENABLE_SHARED ?= 1
 
 soname=libaio.so.1
 minor=0
-micro=1
+micro=2
 libname=$(soname).$(minor).$(micro)
 all_targets += libaio.a
 
@@ -55,6 +55,7 @@ libaio.a: $(libaio_objs)
        $(RANLIB) libaio.a
 
 $(libname): $(libaio_sobjs) libaio.map
+       $(CC) $(CFLAGS) -c struct_offsets.c
        $(CC) $(SO_CFLAGS) -Wl,--version-script=libaio.map -Wl,-soname=$(soname) -o $@ $(libaio_sobjs) $(LINK_FLAGS)
 
 install: $(all_targets)
index 136396f..722e107 100644 (file)
@@ -49,14 +49,14 @@ int compat0_1_io_queue_wait(io_context_t ctx, struct timespec *when)
 
 /* ABI change.  Provide backwards compatibility for this one. */
 SYMVER(compat0_1_io_getevents, io_getevents, 0.1);
-int compat0_1_io_getevents(io_context_t ctx_id, long nr,
+int compat0_1_io_getevents(io_context_t ctx, long nr,
                       struct io_event *events,
                       const struct timespec *const_timeout)
 {
        struct timespec timeout;
        if (const_timeout)
                timeout = *const_timeout;
-       return io_getevents(ctx_id, 1, nr, events,
+       return io_getevents(ctx, 1, nr, events,
                        const_timeout ? &timeout : NULL);
 }
 
index 2bc24e0..24b4b8a 100644 (file)
@@ -53,7 +53,8 @@ typedef enum io_iocb_cmd {
 /* little endian, 32 bits */
 #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
     defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
-    defined(__cris__) || (defined(__riscv) && __riscv_xlen == 32) || \
+    defined(__cris__) || defined(__loongarch32) || \
+    (defined(__riscv) && __riscv_xlen == 32) || \
     (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
          __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 4)
 #define PADDED(x, y)   x; unsigned y
@@ -63,6 +64,7 @@ typedef enum io_iocb_cmd {
 /* little endian, 64 bits */
 #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \
       (defined(__aarch64__) && defined(__AARCH64EL__)) || \
+      defined(__loongarch64) || \
       (defined(__riscv) && __riscv_xlen == 64) || \
       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
           __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_LONG__ == 8)
@@ -100,8 +102,8 @@ struct io_iocb_poll {
 };     /* result code is the set of result flags or -'ve errno */
 
 struct io_iocb_sockaddr {
-       struct sockaddr *addr;
-       int             len;
+       PADDEDptr(struct sockaddr *addr, __pad1);
+       PADDEDul(len, __pad2);
 };     /* result code is the length of the sockaddr, or -'ve errno */
 
 struct io_iocb_common {
@@ -114,8 +116,8 @@ struct io_iocb_common {
 };     /* result code is the amount read or -'ve errno */
 
 struct io_iocb_vector {
-       const struct iovec      *vec;
-       int                     nr;
+       PADDEDptr(const struct iovec *vec, __pad1);
+       PADDEDul(nr, __pad2);
        long long               offset;
 };     /* result code is the amount read or -'ve errno */
 
@@ -162,8 +164,8 @@ extern int io_setup(int maxevents, io_context_t *ctxp);
 extern int io_destroy(io_context_t ctx);
 extern int io_submit(io_context_t ctx, long nr, struct iocb *ios[]);
 extern int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt);
-extern int io_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
-extern int io_pgetevents(io_context_t ctx_id, long min_nr, long nr,
+extern int io_getevents(io_context_t ctx, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
+extern int io_pgetevents(io_context_t ctx, long min_nr, long nr,
                struct io_event *events, struct timespec *timeout,
                sigset_t *sigmask);
 
diff --git a/src/struct_offsets.c b/src/struct_offsets.c
new file mode 100644 (file)
index 0000000..4dc6fcc
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Ensure that data structure offsets in the iocb.u union match.
+ * Note that this code does not end up in the compiled object files.
+ * Its sole purpose is to abort the build if the structure padding
+ * is incorrect.
+ */
+#include <stddef.h>
+#include <assert.h>
+#include <libaio.h>
+
+void
+offset_check(void)
+{
+       static_assert(offsetof(struct iocb, u.v.nr) ==
+                     offsetof(struct iocb, u.c.nbytes),
+                     "Error: iocb.u.v.nr does not match the offset of iocb.u.c.nbytes.");
+       static_assert(offsetof(struct iocb, u.v.offset) ==
+                     offsetof(struct iocb, u.c.offset),
+                     "Error: iocb.u.v.offset does not match the offset of iocb.u.c.offset");
+       static_assert(offsetof(struct iocb, u.saddr.len) ==
+                     offsetof(struct iocb, u.c.nbytes),
+                     "Error: iocb.u.saddr.len does not match the offset of iocb.u.c.nbytes");
+}
index b53da4c..d2a117b 100644 (file)
@@ -27,7 +27,7 @@
 #include "syscall-arm.h"
 #elif defined(__sparc__)
 #include "syscall-sparc.h"
-#elif defined(__aarch64__) || defined(__riscv)
+#elif defined(__aarch64__) || defined(__loongarch__) || defined(__riscv)
 #include "syscall-generic.h"
 #else
 #warning "using system call numbers from sys/syscall.h"
index 13d032e..dd711dc 100644 (file)
@@ -20,5 +20,5 @@ extern int vsys_io_destroy(io_context_t ctx);
 extern int vsys_io_submit(io_context_t ctx, long nr, struct iocb *iocbs[]);
 extern int vsys_io_cancel(io_context_t ctx, struct iocb *iocb);
 extern int vsys_io_wait(io_context_t ctx, struct iocb *iocb, const struct timespec *when);
-extern int vsys_io_getevents(io_context_t ctx_id, long nr, struct io_event *events, const struct timespec *timeout);
+extern int vsys_io_getevents(io_context_t ctx, long nr, struct io_event *events, const struct timespec *timeout);