Giter Club home page Giter Club logo

Comments (9)

axboe avatar axboe commented on August 15, 2024 1

Here's the updated commit:

https://git.kernel.dk/cgit/linux-block/commit/?h=for-5.6/io_uring&id=020bfce8352dd4b79ebc61d89c721f454289f456

Only difference is that it adds IORING_FEAT_RW_CUR_POS as a feature flag, since this feature is otherwise not that easy to detect.

from liburing.

CarterLi avatar CarterLi commented on August 15, 2024

What if a user does submit 2 seeking readv ops for the same fd once? Just behaves like 2 plain readv in different threads.

from liburing.

axboe avatar axboe commented on August 15, 2024

Better late than never... Here's the simple patch to do that, you just have to set offset to -1 and it'll use the current file position. This strictly relies on the application doing the right thing, of course. If it submits multiple reads at the same time, then it'll get multiple reads done at the SAME offset, and the end file position will NOT be pos + bytes_read.

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 4ee53ad80110..930be17bece2 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -494,6 +494,7 @@ struct io_kiocb {
 #define REQ_F_COMP_LOCKED	32768	/* completion under lock */
 #define REQ_F_HARDLINK		65536	/* doesn't sever on completion < 0 */
 #define REQ_F_FORCE_ASYNC	131072	/* IOSQE_ASYNC */
+#define REQ_F_CUR_POS		262144	/* read/write uses file position */
 	u64			user_data;
 	u32			result;
 	u32			sequence;
@@ -1710,6 +1711,10 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 		req->flags |= REQ_F_ISREG;
 
 	kiocb->ki_pos = READ_ONCE(sqe->off);
+	if (kiocb->ki_pos == -1 && !(req->file->f_mode & FMODE_STREAM)) {
+		req->flags |= REQ_F_CUR_POS;
+		kiocb->ki_pos = req->file->f_pos;
+	}
 	kiocb->ki_flags = iocb_flags(kiocb->ki_filp);
 	kiocb->ki_hint = ki_hint_validate(file_write_hint(kiocb->ki_filp));
 
@@ -1781,6 +1786,10 @@ static inline void io_rw_done(struct kiocb *kiocb, ssize_t ret)
 static void kiocb_done(struct kiocb *kiocb, ssize_t ret, struct io_kiocb **nxt,
 		       bool in_async)
 {
+	struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
+
+	if (req->flags & REQ_F_CUR_POS)
+		req->file->f_pos = kiocb->ki_pos;
 	if (in_async && ret >= 0 && kiocb->ki_complete == io_complete_rw)
 		*nxt = __io_complete_rw(kiocb, ret);
 	else

from liburing.

axboe avatar axboe commented on August 15, 2024

I'll add this to the 5.6 mix, no promises yet.

from liburing.

CarterLi avatar CarterLi commented on August 15, 2024

If it submits multiple reads at the same time, then it'll get multiple reads done at the SAME offset, and the end file position will NOT be pos + bytes_read.

What about IOSQE_IO_LINK?

read(fd1, buf, size, -1, IOSQE_IO_LINK);
write(fd2, buf, size, -1, IOSQE_IO_LINK);
read(fd1, buf, size, -1, IOSQE_IO_LINK);
write(fd2, buf, size, -1);

Will it work as expected?

from liburing.

axboe avatar axboe commented on August 15, 2024

Yes, those are serialized with each other internally, hence that will work as expected. Only concurrent reads or writes will not. If you do:

sqe1 = io_uring_get_sqe(ring);
io_uring_prep_readv(sqe1, fd, &iov, 1, -1);

sqe2 = io_uring_get_sqe(ring);
io_uring_prep_readv(sqe2, fd, &iov, 1, -1);

io_uring_submit(ring);

Then all bets are off, since you don't know if sqe1 or sqe2 is completed first, and they are probably both issued at the same time and will get the same offset assigned. Whichever completes the last will set the file position. But that's the general caveat.

from liburing.

CarterLi avatar CarterLi commented on August 15, 2024

Perfect! It's better to document those feature flag in the man page.

Thanks!

from liburing.

beef9999 avatar beef9999 commented on August 15, 2024

Question 1:

The Linux manual said that the preadv and pwritev are atomic.
So what about the io_uring_prep_writev and io_uring_prep_readv ?

from liburing.

beef9999 avatar beef9999 commented on August 15, 2024

Question 2:

The Linux manual said when opening with O_APPEND,

Before each write, the file offset is positioned at the end of the file, as if with lseek.

Does this rule applies to io_uring as well, if I passed -1 as the offset?

from liburing.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.