Maxim, should this patch be sent to mainstream as well?
-- Best regards, Konstantin Khorenko, Virtuozzo Linux Kernel Team On 03/30/2016 03:58 AM, Maxim Patlasov wrote:
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 <[email protected]> --- 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; .
_______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
