[RHEL7,COMMIT] fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send

Submitted by Konstantin Khorenko on Feb. 4, 2019, 10:02 a.m.

Details

Message ID 201902041002.x14A2580020292@finist-ce7.sw.ru
State New
Series "fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send"
Headers show

Commit Message

Konstantin Khorenko Feb. 4, 2019, 10:02 a.m.
The commit is pushed to "branch-rh7-3.10.0-957.1.3.vz7.83.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.1.3.vz7.83.10
------>
commit f00dbb0c6c2c8e6f9ed5a64eaa286ac43cfe44ff
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Mon Feb 4 13:02:05 2019 +0300

    fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send
    
    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@virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
---
 fs/fuse/dev.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index dc21886ee55d..3e5e19ead7eb 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);
+
+		spin_lock(&fc->lock);
 		list_del_init(&req->list);
 		spin_unlock(&fc->lock);
+
 		request_end(fc, req);
-	} else if (fc->connected) {
+		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 {

Comments

Konstantin Khorenko Feb. 4, 2019, 11:57 a.m.
Dropped.

Not needed after series
[PATCH 1/2] fs/fuse kio: add FUSE_S_FAIL_IMMEDIATELY check in pcs_fuse_submit()‚Äč

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 02/04/2019 01:02 PM, Konstantin Khorenko wrote:
> The commit is pushed to "branch-rh7-3.10.0-957.1.3.vz7.83.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
> after rh7-3.10.0-957.1.3.vz7.83.10
> ------>
> commit f00dbb0c6c2c8e6f9ed5a64eaa286ac43cfe44ff
> Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
> Date:   Mon Feb 4 13:02:05 2019 +0300
>
>     fs/fuse: move FUSE_S_FAIL_IMMEDIATELY check before kio req send
>
>     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@virtuozzo.com>
>     Acked-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
> ---
>  fs/fuse/dev.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index dc21886ee55d..3e5e19ead7eb 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);
> +
> +		spin_lock(&fc->lock);
>  		list_del_init(&req->list);
>  		spin_unlock(&fc->lock);
> +
>  		request_end(fc, req);
> -	} else if (fc->connected) {
> +		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 {
> .
>