No, the problem came with our "close_wait" feature. ML doesn't have it.

On 04/08/2016 12:20 AM, Konstantin Khorenko wrote:
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

Reply via email to