[Devel] [PATCH RHEL7 COMMIT] fuse: resend interrupted release

Konstantin Khorenko khorenko at virtuozzo.com
Fri Apr 8 00:21:03 PDT 2016


The commit is pushed to "branch-rh7-3.10.0-327.10.1.vz7.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.10.1.vz7.12.5
------>
commit 689d1175f9c062f824611c4a8e19c70e2164ea52
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date:   Fri Apr 8 11:21:02 2016 +0400

    fuse: resend interrupted release
    
    If a client gets fatal signal while explicitly waiting for ACK from fused
    (request_wait_answer()), kernel fuse discards the request like this:
    
    > 		/* Request is not yet in userspace, bail out */
    > 		if (req->state == FUSE_REQ_PENDING) {
    > 			list_del(&req->list);
    > 			__fuse_put_request(req);
    > 			req->out.h.error = -EINTR;
    > 			return;
    > 		}
    
    This is nice for requests directly initiated by client, but not for RELEASE
    requests: we have to avoid discarding RELEASE requests because otherwise
    fused won't know when the file is "closed" by client (last fput called).
    
    The problem didn't exist before close_wait feature because then fuse_file_put
    sent RELEASE asynchronously. Hence no request_wait_answer() involved.
    
    The patch solves the problem by resending interrupted RELEASE asynchronously.
    This is OK because if the client is killed, he/she doesn't care about
    sync/async close(2) behavior.
    
    https://jira.sw.ru/browse/PSBM-45428
    
    Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
 fs/fuse/file.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f432b70..11c5959 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -155,10 +155,16 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
 		if (sync) {
 			req->background = 0;
 			fuse_request_send(ff->fc, req);
+			if (req->out.h.error == -EINTR) {
+				req->state = FUSE_REQ_INIT;
+				req->out.h.error = 0;
+				goto async_fallback;
+			}
 			fuse_file_list_del(ff);
 			path_put(&req->misc.release.path);
 			fuse_put_request(ff->fc, req);
 		} else {
+async_fallback:
 			fuse_file_list_del(ff);
 			req->end = fuse_release_end;
 			req->background = 1;


More information about the Devel mailing list