On 8/14/19 3:35 AM, Jackie Liu wrote:
> Suppose there are three IOs here, and their order is as follows:
> 
> Submit:
>       [1] IO_LINK
>           |
>           |---  [2] IO_LINK | IO_DRAIN
>                     |
>                     |- [3] NORMAL_IO
> 
> In theory, they all need to be inserted into the Link-list, but flag
> IO_DRAIN we have, io[2] and io[3] will be inserted into the defer_list,
> and finally, io[3] and io[2] will be processed at the same time.
> 
> Now, it is directly forbidden to pass these two flags at the same time.
> 
> Fixes: 9e645e1105c ("io_uring: add support for sqe links")
> Signed-off-by: Jackie Liu <liuyu...@kylinos.cn>
> ---
>   fs/io_uring.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/io_uring.c b/fs/io_uring.c
> index d542f1c..05ee628 100644
> --- a/fs/io_uring.c
> +++ b/fs/io_uring.c
> @@ -2074,10 +2074,13 @@ static void io_submit_sqe(struct io_ring_ctx *ctx, 
> struct sqe_submit *s,
>   {
>       struct io_uring_sqe *sqe_copy;
>       struct io_kiocb *req;
> +     unsigned int flags;
>       int ret;
>   
> +     flags = READ_ONCE(s->sqe->flags);
>       /* enforce forwards compatibility on users */
> -     if (unlikely(s->sqe->flags & ~SQE_VALID_FLAGS)) {
> +     if (unlikely((flags & ~SQE_VALID_FLAGS) ||
> +                  (flags & (IOSQE_IO_DRAIN | IOSQE_IO_LINK)))) {

This doesn't look right, as any setting of either DRAIN or LINK would now
fail?

Did you mean something ala:

        if ((flags & (IOSQE_IO_DRAIN | IOSQE_IO_LINK)) ==
            (IOSQE_IO_DRAIN | IOSQE_IO_LINK)) {
                ... fail ...
        }

which makes me worried that you didn't test this at all...

-- 
Jens Axboe

Reply via email to