[RHEL7,COMMIT] fs/fuse kio: style fix in pcs_fuse_submit()

Submitted by Konstantin Khorenko on May 21, 2019, 4:02 p.m.

Details

Message ID 201905211602.x4LG2G2l027409@finist-ce7.sw.ru
State New
Series "fs/fuse kio: style fix in pcs_fuse_submit()"
Headers show

Commit Message

Konstantin Khorenko May 21, 2019, 4:02 p.m.
The commit is pushed to "branch-rh7-3.10.0-957.12.2.vz7.96.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.12.2.vz7.96.1
------>
commit cfa4c65a60056582e47f0be550a7b9554dd23ad5
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Tue May 21 19:02:16 2019 +0300

    fs/fuse kio: style fix in pcs_fuse_submit()
    
    This patch simplifies pcs_fuse_submit() a little bit by replacing &r->req with
    req, because here it's the same pointer.
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    
    =====================
    Patchset description:
    
    fix deadlock between synchronous reqs and fuse_invalidate_files
    
    One more deadlock with fuse_invalidate_files():
    
    [<ffffffff92ba7cc4>] __lock_page+0x74/0x90
    [<ffffffff92bb9a75>] invalidate_inode_pages2_range+0x445/0x470
    [<ffffffff92bb9ab7>] invalidate_inode_pages2+0x17/0x20
    [<ffffffffc034cde5>] fuse_invalidate_files+0x235/0x270 [fuse]
    [<ffffffffc033d3fb>] fuse_dev_do_write+0x7fb/0xe20 [fuse]
    [<ffffffffc033ddc1>] fuse_dev_write+0x71/0xa0 [fuse]
    [<ffffffff92c3c2e6>] do_sync_write+0x96/0xe0
    [<ffffffff92c3cdc0>] vfs_write+0xc0/0x1f0
    [<ffffffff92c3dbef>] SyS_write+0x7f/0xf0
    [<ffffffff9315589b>] system_call_fastpath+0x22/0x27
    
    This happened because synchronous kio read request was not dropped by kill_requests:
    
    PID: 20684  TASK: ffff9543c2e71160  CPU: 5   COMMAND: "co_io"
    [ffff9547b0faf9f8] __schedule at ffffffff93148a9f
    [ffff9547b0fafa88] schedule at ffffffff93148fe9
    [ffff9547b0fafa98] kpcs_req_send at ffffffffc047dab5 [fuse_kio_pcs]
    [ffff9547b0fafb08] __fuse_request_send at ffffffffc033a987 [fuse]
    [ffff9547b0fafb40] fuse_request_check_and_send at ffffffffc033e097 [fuse]
    [ffff9547b0fafb50] fuse_send_read at ffffffffc03463ec [fuse]
    [ffff9547b0fafb90] __fuse_readpage at ffffffffc03475ad [fuse]
    [ffff9547b0fafc40] fuse_readpage at ffffffffc0347a3c [fuse]
    [ffff9547b0fafca0] generic_file_read_iter at ffffffff92baa186
    [ffff9547b0fafd58] generic_file_aio_read at ffffffff92baa5c5
    [ffff9547b0fafdc0] fuse_file_aio_read at ffffffffc0343788 [fuse]
    [ffff9547b0fafdf0] do_sync_read at ffffffff92c3c206
    [ffff9547b0fafed0] vfs_read at ffffffff92c3cc2f
    [ffff9547b0faff00] sys_pread64 at ffffffff92c3dcf2
    [ffff9547b0faff50] system_call_fastpath at ffffffff9315589b
    
     struct pcs_fuse_req {
     req = {
        list = {
          next = 0xffff95479374eb18,
          prev = 0xffff9547acf76e00
        },
        ...
        page_cache = 1,
        page_needs_release = 0,
        killed = 0,
        ...
        ff = 0x0,
        io_inode = 0xffff95445da0b740,
    
    The fuse_file pointer was not initialized in req->ff, that means we can't check
    ff->ff_state inside pcs_fuse_submit(), despite the fact that this request has
    locked pages. It's believed that requests with an empty req->ff don't have pages,
    therefore, such requests may not be synchronized with fuse_invalidate_files().
    However, synchronous requests don't reference ff, but pass it as a parameter to
    fuse_request_check_and_send().
    
    This patchset fixes it.
    
    https://pmc.acronis.com/browse/VSTOR-23034
    Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    
    Pavel Butsykin (4):
      fs/fuse kio: forward fuse_file pointer to kpcs_req_send()
      fs/fuse kio: add pending kio requests to kqueue
      fs/fuse kio: style fix in pcs_fuse_submit()
      fs/fuse kio: keep fuse_file for requests waiting for shrink
---
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 245fdee569c2..cd3ec4897225 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -950,7 +950,7 @@  static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 	ireq = &r->exec.ireq;
 	ireq_init(di, ireq);
 
-	switch (r->req.in.h.opcode) {
+	switch (req->in.h.opcode) {
 	case FUSE_WRITE:
 	case FUSE_READ:
 		ret = pcs_fuse_prep_rw(r, ff);
@@ -967,7 +967,7 @@  static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 		struct fuse_fallocate_in *inarg = (void*) req->in.args[0].value;
 
 		if (pfc->fc->no_fallocate) {
-			r->req.out.h.error = -EOPNOTSUPP;
+			req->out.h.error = -EOPNOTSUPP;
 			goto error;
 		}
 
@@ -980,7 +980,7 @@  static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 		WARN_ON_ONCE(!mutex_is_locked(&fi->inode.i_mutex));
 		if (inarg->mode & (FALLOC_FL_ZERO_RANGE|FALLOC_FL_PUNCH_HOLE)) {
 			if ((inarg->offset & (PAGE_SIZE - 1)) || (inarg->length & (PAGE_SIZE - 1))) {
-				r->req.out.h.error = -EINVAL;
+				req->out.h.error = -EINVAL;
 				goto error;
 			}
 		}
@@ -1007,7 +1007,7 @@  static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 		goto submit;
 	case FUSE_IOCTL:
 		if (pfc->fc->no_fiemap) {
-			r->req.out.h.error = -EOPNOTSUPP;
+			req->out.h.error = -EOPNOTSUPP;
 			goto error;
 		}
 
@@ -1022,13 +1022,13 @@  static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
 		}
 		break;
 	}
-	r->req.out.h.error = 0;
+	req->out.h.error = 0;
 error:
-	DTRACE("do fuse_request_end req:%p op:%d err:%d\n", &r->req, r->req.in.h.opcode, r->req.out.h.error);
+	DTRACE("do fuse_request_end req:%p op:%d err:%d\n", req, req->in.h.opcode, req->out.h.error);
 
 	if (lk)
 		spin_unlock(&pfc->fc->bg_lock);
-	request_end(pfc->fc, &r->req);
+	request_end(pfc->fc, req);
 	if (lk)
 		spin_lock(&pfc->fc->bg_lock);
 	return;