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

Pavel Butsykin pbutsykin at virtuozzo.com
Wed Jan 23 14:49:12 MSK 2019


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