[Devel] [PATCH] fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send

Alexey Kuznetsov kuznet at virtuozzo.com
Wed Jan 23 19:45:16 MSK 2019


Ack


On Wed, Jan 23, 2019 at 2:49 PM Pavel Butsykin <pbutsykin at virtuozzo.com> wrote:
>
> Fuse file with FUSE_S_FAIL_IMMEDIATELY state should not allow to execute new
> requests. But in case of kio requests it doesn't work because the status check
> is located behind kio.op->req_send(). To fix this let's move the status check
> before kio.op->req_send().
>
> Note: We can drop hunk with req->end(fc, req) in __fuse_request_send() because
> it was only needed to clenup kio setattr request after pcs_kio_setattr_handle().
>
> Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
> ---
>  fs/fuse/dev.c | 40 +++++++++++++++++++++++-----------------
>  1 file changed, 23 insertions(+), 17 deletions(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index dc21886ee55d..dcbed5d4932c 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -538,6 +538,11 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req,
>
>         BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
>
> +       if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state)) {
> +               req->out.h.error = -EIO;
> +               return;
> +       }
> +
>         if (fc->kio.op && !fc->kio.op->req_send(fc, req, false, false))
>                 return;
>
> @@ -547,11 +552,6 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req,
>                 req->out.h.error = -ENOTCONN;
>                 if (req->end)
>                         req->end(fc, req);
> -       } else if (ff && test_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state)) {
> -               spin_unlock(&fiq->waitq.lock);
> -               req->out.h.error = -EIO;
> -               if (req->end)
> -                       req->end(fc, req);
>         } else {
>                 req->in.h.unique = fuse_get_unique(fiq);
>                 queue_request(fiq, req);
> @@ -627,20 +627,26 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
>  {
>         BUG_ON(!req->end);
>
> -       if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, false))
> -               return;
> -
> -       spin_lock(&fc->lock);
>         if (req->page_cache && req->ff &&
>             test_bit(FUSE_S_FAIL_IMMEDIATELY, &req->ff->ff_state)) {
> -               BUG_ON(req->in.h.opcode != FUSE_READ);
> -               req->out.h.error = -EIO;
> -               __clear_bit(FR_BACKGROUND, &req->flags);
> -               __clear_bit(FR_PENDING, &req->flags);
> -               list_del_init(&req->list);
> -               spin_unlock(&fc->lock);
> -               request_end(fc, req);
> -       } else if (fc->connected) {
> +               BUG_ON(req->in.h.opcode != FUSE_READ);
> +               req->out.h.error = -EIO;
> +               __clear_bit(FR_BACKGROUND, &req->flags);
> +               __clear_bit(FR_PENDING, &req->flags);
> +
> +               spin_lock(&fc->lock);
> +               list_del_init(&req->list);
> +               spin_unlock(&fc->lock);
> +
> +               request_end(fc, req);
> +               return;
> +       }
> +
> +       if (fc->kio.op && !fc->kio.op->req_send(fc, req, true, false))
> +               return;
> +
> +       spin_lock(&fc->lock);
> +       if (fc->connected) {
>                 fuse_request_send_background_locked(fc, req);
>                 spin_unlock(&fc->lock);
>         } else {
> --
> 2.15.1
>



More information about the Devel mailing list