git: 1298ecb6ba13 - stable/14 - lio_listio(2): add LIO_FOFFSET flag to ignore aiocb aio_offset

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sun, 18 Feb 2024 10:02:22 UTC
The branch stable/14 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1298ecb6ba138d8e1d256816ed68fea00b17bbec

commit 1298ecb6ba138d8e1d256816ed68fea00b17bbec
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-01-13 19:46:18 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-02-18 10:01:46 +0000

    lio_listio(2): add LIO_FOFFSET flag to ignore aiocb aio_offset
    
    (cherry picked from commit e4b7bbd6ab77e908a60362aa29e518f224a117b0)
---
 lib/libc/sys/lio_listio.2 | 15 ++++++++++++++-
 sys/kern/vfs_aio.c        | 17 ++++++++++++-----
 sys/sys/aio.h             |  4 ++++
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/lib/libc/sys/lio_listio.2 b/lib/libc/sys/lio_listio.2
index 34d2490cca01..bda65c38b1ac 100644
--- a/lib/libc/sys/lio_listio.2
+++ b/lib/libc/sys/lio_listio.2
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 22, 2021
+.Dd January 13, 2024
 .Dt LIO_LISTIO 2
 .Os
 .Sh NAME
@@ -78,6 +78,19 @@ Write data as if by a call to
 .El
 .Pp
 If the
+.Dv LIO_READ ,
+.Dv LIO_READV ,
+.Dv LIO_WRITE ,
+.Dv LIO_WRITEV
+opcodes are or-ed with the
+.Dv LIO_FOFFSET
+flag, the corresponding read or write operation uses the current file
+descriptor offset instead of
+.Va aio_offset
+from
+.Vt aiocb .
+.Pp
+If the
 .Fa mode
 argument is
 .Dv LIO_WAIT ,
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 8a0375a9f002..45f912a7cc2d 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -230,6 +230,9 @@ typedef struct oaiocb {
 #define	KAIOCB_CLEARED		0x10
 #define	KAIOCB_FINISHED		0x20
 
+/* ioflags */
+#define	KAIOCB_IO_FOFFSET	0x01
+
 /*
  * AIO process info
  */
@@ -790,12 +793,14 @@ aio_process_rw(struct kaiocb *job)
 		if (job->uiop->uio_resid == 0)
 			error = 0;
 		else
-			error = fo_read(fp, job->uiop, fp->f_cred, FOF_OFFSET,
-			    td);
+			error = fo_read(fp, job->uiop, fp->f_cred,
+			    (job->ioflags & KAIOCB_IO_FOFFSET) != 0 ? 0 :
+			    FOF_OFFSET, td);
 	} else {
 		if (fp->f_type == DTYPE_VNODE)
 			bwillwrite();
-		error = fo_write(fp, job->uiop, fp->f_cred, FOF_OFFSET, td);
+		error = fo_write(fp, job->uiop, fp->f_cred, (job->ioflags &
+		    KAIOCB_IO_FOFFSET) != 0 ? 0 : FOF_OFFSET, td);
 	}
 	msgrcv_end = td->td_ru.ru_msgrcv;
 	msgsnd_end = td->td_ru.ru_msgsnd;
@@ -1550,13 +1555,15 @@ aio_aqueue(struct thread *td, struct aiocb *ujob, struct aioliojob *lj,
 
 	/* Get the opcode. */
 	if (type == LIO_NOP) {
-		switch (job->uaiocb.aio_lio_opcode) {
+		switch (job->uaiocb.aio_lio_opcode & ~LIO_FOFFSET) {
 		case LIO_WRITE:
 		case LIO_WRITEV:
 		case LIO_NOP:
 		case LIO_READ:
 		case LIO_READV:
-			opcode = job->uaiocb.aio_lio_opcode;
+			opcode = job->uaiocb.aio_lio_opcode & ~LIO_FOFFSET;
+			if ((job->uaiocb.aio_lio_opcode & LIO_FOFFSET) != 0)
+				job->ioflags |= KAIOCB_IO_FOFFSET;
 			break;
 		default:
 			error = EINVAL;
diff --git a/sys/sys/aio.h b/sys/sys/aio.h
index a1aa96efed09..f987f1e1dbd4 100644
--- a/sys/sys/aio.h
+++ b/sys/sys/aio.h
@@ -51,6 +51,9 @@
 #define	LIO_DSYNC		(0x10 | LIO_SYNC)
 #define	LIO_MLOCK		0x20
 #endif
+#if __BSD_VISIBLE
+#define	LIO_FOFFSET		0x40
+#endif
 
 /*
  * LIO modes
@@ -129,6 +132,7 @@ struct kaiocb {
 	TAILQ_ENTRY(kaiocb) plist;	/* (a) lists of pending / done jobs */
 	TAILQ_ENTRY(kaiocb) allist;	/* (a) list of all jobs in proc */
 	int	jobflags;		/* (a) job flags */
+	int	ioflags;		/* (*) io flags */
 	int	inblock;		/* (*) input blocks */
 	int	outblock;		/* (*) output blocks */
 	int	msgsnd;			/* (*) messages sent */