Page MenuHomeFreeBSD

D31627.id93992.diff
No OneTemporary

D31627.id93992.diff

Index: lib/libc/sys/lio_listio.2
===================================================================
--- lib/libc/sys/lio_listio.2
+++ lib/libc/sys/lio_listio.2
@@ -66,11 +66,17 @@
.It Dv LIO_READ
Read data as if by a call to
.Xr aio_read 2 .
+.It Dv LIO_READV
+Read data as if by a call to
+.Xr aio_readv 2 .
.It Dv LIO_NOP
No operation.
.It Dv LIO_WRITE
Write data as if by a call to
.Xr aio_write 2 .
+.It Dv LIO_WRITEV
+Write data as if by a call to
+.Xr aio_writev 2 .
.El
.Pp
If the
@@ -205,7 +211,9 @@
.Sh SEE ALSO
.Xr aio_error 2 ,
.Xr aio_read 2 ,
+.Xr aio_readv 2 ,
.Xr aio_write 2 ,
+.Xr aio_writev 2 ,
.Xr read 2 ,
.Xr write 2 ,
.Xr sigevent 3 ,
@@ -216,6 +224,11 @@
.Fn lio_listio
function is expected to conform to
.St -p1003.1-2001 .
+The
+.Dv LIO_READV
+and
+.Dv LIO_WRITEV
+operations are FreeBSD extensions, and should not be used in portable code.
.Sh HISTORY
The
.Fn lio_listio
Index: sys/kern/vfs_aio.c
===================================================================
--- sys/kern/vfs_aio.c
+++ sys/kern/vfs_aio.c
@@ -1419,6 +1419,8 @@
error = copyin(ujob, kcb, sizeof(struct aiocb));
if (error)
return (error);
+ if (type == LIO_NOP)
+ type = kcb->aio_lio_opcode;
if (type & LIO_VECTORED) {
/* malloc a uio and copy in the iovec */
error = copyinuio(__DEVOLATILE(struct iovec*, kcb->aio_iov),
@@ -1557,8 +1559,10 @@
if (type == LIO_NOP) {
switch (job->uaiocb.aio_lio_opcode) {
case LIO_WRITE:
+ case LIO_WRITEV:
case LIO_NOP:
case LIO_READ:
+ case LIO_READV:
opcode = job->uaiocb.aio_lio_opcode;
break;
default:
Index: sys/sys/aio.h
===================================================================
--- sys/sys/aio.h
+++ sys/sys/aio.h
@@ -43,10 +43,12 @@
#define LIO_NOP 0x0
#define LIO_WRITE 0x1
#define LIO_READ 0x2
-#if defined(_KERNEL) || defined(_WANT_ALL_LIO_OPCODES)
+#if __BSD_VISIBLE
#define LIO_VECTORED 0x4
#define LIO_WRITEV (LIO_WRITE | LIO_VECTORED)
#define LIO_READV (LIO_READ | LIO_VECTORED)
+#endif
+#if defined(_KERNEL) || defined(_WANT_ALL_LIO_OPCODES)
#define LIO_SYNC 0x8
#define LIO_DSYNC (0x10 | LIO_SYNC)
#define LIO_MLOCK 0x20
Index: tests/sys/aio/lio_test.c
===================================================================
--- tests/sys/aio/lio_test.c
+++ tests/sys/aio/lio_test.c
@@ -210,15 +210,97 @@
ATF_REQUIRE_EQ(0, sem_destroy(&completions));
}
+/*
+ * A simple check that the allowed operations work.
+ */
+ATF_TC_WITHOUT_HEAD(lio_listio_opcodes);
+ATF_TC_BODY(lio_listio_opcodes, tc)
+{
+ struct aiocb write_cb, read_cb, writev_cb, readv_cb;
+ struct aiocb *list[] = {&write_cb, &read_cb, &writev_cb, &readv_cb};
+ struct iovec writev_iov[2];
+ struct iovec readv_iov[2];
+ char buffer[6];
+ int fd;
+
+ fd = open("testfile", O_CREAT | O_RDWR);
+ ATF_REQUIRE_MSG(fd >= 0, "open: %s", strerror(errno));
+
+ /* We start with numbers in a file and letters in memory... */
+ ATF_CHECK_EQ(0, ftruncate(fd, 0));
+ ATF_CHECK_EQ(6, write(fd, "123456", 6));
+ memcpy(buffer, "abcdef", 6);
+
+ /* a -> 1 */
+ bzero(&write_cb, sizeof(write_cb));
+ write_cb.aio_sigevent.sigev_notify = SIGEV_NONE;
+ write_cb.aio_fildes = fd;
+ write_cb.aio_lio_opcode = LIO_WRITE;
+ write_cb.aio_buf = &buffer[0];
+ write_cb.aio_nbytes = 1;
+ write_cb.aio_offset = 0;
+
+ /* b <- 2 */
+ bzero(&read_cb, sizeof(read_cb));
+ read_cb.aio_sigevent.sigev_notify = SIGEV_NONE;
+ read_cb.aio_fildes = fd;
+ read_cb.aio_lio_opcode = LIO_READ;
+ read_cb.aio_buf = &buffer[1];
+ read_cb.aio_nbytes = 1;
+ read_cb.aio_offset = 1;
+
+ /* d -> 3, c -> 4 */
+ writev_iov[0].iov_base = &buffer[3];
+ writev_iov[0].iov_len = 1;
+ writev_iov[1].iov_base = &buffer[2];
+ writev_iov[1].iov_len = 1;
+ bzero(&writev_cb, sizeof(writev_cb));
+ writev_cb.aio_sigevent.sigev_notify = SIGEV_NONE;
+ writev_cb.aio_fildes = fd;
+ writev_cb.aio_lio_opcode = LIO_WRITEV;
+ writev_cb.aio_iov = &writev_iov;
+ writev_cb.aio_iovcnt = 2;
+ writev_cb.aio_offset = 2;
+
+ /* f <- 5, e <- 6 */
+ readv_iov[0].iov_base = &buffer[5];
+ readv_iov[0].iov_len = 1;
+ readv_iov[1].iov_base = &buffer[4];
+ readv_iov[1].iov_len = 1;
+ bzero(&readv_cb, sizeof(readv_cb));
+ readv_cb.aio_sigevent.sigev_notify = SIGEV_NONE;
+ readv_cb.aio_fildes = fd;
+ readv_cb.aio_lio_opcode = LIO_READV;
+ readv_cb.aio_iov = &readv_iov;
+ readv_cb.aio_iovcnt = 2;
+ readv_cb.aio_offset = 4;
+
+ ATF_CHECK_EQ(0, lio_listio(LIO_WAIT, list, nitems(list), NULL));
+ ATF_CHECK_EQ(0, aio_error(&write_cb));
+ ATF_CHECK_EQ(1, aio_return(&write_cb));
+ ATF_CHECK_EQ(0, aio_error(&read_cb));
+ ATF_CHECK_EQ(1, aio_return(&read_cb));
+ ATF_CHECK_EQ(0, aio_error(&writev_cb));
+ ATF_CHECK_EQ(2, aio_return(&writev_cb));
+ ATF_CHECK_EQ(0, aio_error(&readv_cb));
+ ATF_CHECK_EQ(2, aio_return(&readv_cb));
+
+ ATF_CHECK_EQ(0, memcmp(buffer, "a2cd65", 6));
+ ATF_CHECK_EQ(6, pread(fd, buffer, 6, 0));
+ ATF_CHECK_EQ(0, memcmp(buffer, "a2dc56", 6));
+
+ close(fd);
+}
+
+
/*
* Only select opcodes are allowed with lio_listio
*/
ATF_TC_WITHOUT_HEAD(lio_listio_invalid_opcode);
ATF_TC_BODY(lio_listio_invalid_opcode, tc)
{
- struct aiocb sync_cb, mlock_cb, writev_cb, readv_cb;
- struct aiocb *list[] = {&sync_cb, &mlock_cb, &writev_cb, &readv_cb};
- struct iovec iov;
+ struct aiocb sync_cb, mlock_cb;
+ struct aiocb *list[] = {&sync_cb, &mlock_cb};
int fd;
fd = open("testfile", O_CREAT | O_RDWR);
@@ -231,30 +313,13 @@
bzero(&mlock_cb, sizeof(mlock_cb));
mlock_cb.aio_lio_opcode = LIO_MLOCK;
- iov.iov_base = NULL;
- iov.iov_len = 0;
-
- bzero(&readv_cb, sizeof(readv_cb));
- readv_cb.aio_fildes = fd;
- readv_cb.aio_lio_opcode = LIO_READV;
- readv_cb.aio_iov = &iov;
- readv_cb.aio_iovcnt = 1;
-
- bzero(&writev_cb, sizeof(writev_cb));
- writev_cb.aio_fildes = fd;
- writev_cb.aio_lio_opcode = LIO_WRITEV;
- writev_cb.aio_iov = &iov;
- writev_cb.aio_iovcnt = 1;
-
ATF_CHECK_ERRNO(EIO, lio_listio(LIO_WAIT, list, nitems(list), NULL));
ATF_CHECK_EQ(EINVAL, aio_error(&sync_cb));
ATF_CHECK_ERRNO(EINVAL, aio_return(&sync_cb) < 0);
ATF_CHECK_EQ(EINVAL, aio_error(&mlock_cb));
ATF_CHECK_ERRNO(EINVAL, aio_return(&mlock_cb) < 0);
- ATF_CHECK_EQ(EINVAL, aio_error(&readv_cb));
- ATF_CHECK_ERRNO(EINVAL, aio_return(&readv_cb) < 0);
- ATF_CHECK_EQ(EINVAL, aio_error(&writev_cb));
- ATF_CHECK_ERRNO(EINVAL, aio_return(&writev_cb) < 0);
+
+ close(fd);
}
@@ -267,6 +332,7 @@
ATF_TP_ADD_TC(tp, lio_listio_empty_nowait_signal);
ATF_TP_ADD_TC(tp, lio_listio_empty_nowait_thread);
ATF_TP_ADD_TC(tp, lio_listio_empty_wait);
+ ATF_TP_ADD_TC(tp, lio_listio_opcodes);
ATF_TP_ADD_TC(tp, lio_listio_invalid_opcode);
return (atf_no_error());
Index: usr.bin/truss/syscalls.c
===================================================================
--- usr.bin/truss/syscalls.c
+++ usr.bin/truss/syscalls.c
@@ -754,7 +754,7 @@
};
static struct xlat lio_opcodes[] = {
- X(LIO_WRITE) X(LIO_READ) X(LIO_NOP)
+ X(LIO_WRITE) X(LIO_READ) X(LIO_READV) X(LIO_WRITEV) X(LIO_NOP)
XEND
};

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 8, 4:42 PM (13 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25043116
Default Alt Text
D31627.id93992.diff (6 KB)

Event Timeline