[RHEL7,COMMIT] fs/fuse kio: missed cleanup for interrupted shrink request

Submitted by Konstantin Khorenko on Dec. 17, 2018, 3:59 p.m.

Details

Message ID 201812171559.wBHFxPwZ027255@finist-ce7.sw.ru
State New
Series "fs/fuse kio: missed cleanup for interrupted shrink request"
Headers show

Commit Message

Konstantin Khorenko Dec. 17, 2018, 3:59 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.20.2.vz7.73.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.20.2.vz7.73.23
------>
commit 890a454b05282720907de811f17f2dc1bbfad071
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Mon Dec 17 18:59:25 2018 +0300

    fs/fuse kio: missed cleanup for interrupted shrink request
    
    In the case when shrink request was interrupted we need cleanup di->size.op and
    resubmit pending read requests by analogy with this patch:
    "fs/fuse kio: missed clean di->size.op in failed shrink request"
    
    Also if the request has already gone to userspace, this request cannot be
    interrupted in order to avoid racing with request_end(). But it's still
    possible race with req->end callback, so let's also fix the wait condition.
    
    https://pmc.acronis.com/browse/VSTOR-19074
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 fs/fuse/dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 6fcbb117aa9c..dc21886ee55d 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -517,6 +517,8 @@  static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 			spin_unlock(&fiq->waitq.lock);
 			__fuse_put_request(req);
 			req->out.h.error = -EINTR;
+			if (req->end)
+				req->end(fc, req);
 			return;
 		}
 		spin_unlock(&fiq->waitq.lock);
@@ -526,7 +528,7 @@  static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 	 * Either request is already in userspace, or it was forced.
 	 * Wait it out.
 	 */
-	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
+	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags) && !req->end);
 }
 
 static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req,