From 533e2c6e8d877d612b09bef26bc154868093b6f6 Mon Sep 17 00:00:00 2001 From: Cliff Chen Date: Thu, 15 Apr 2021 10:50:42 +0800 Subject: [PATCH] ANDROID: fuse: fix deadlock for reply of FUSE_CANONICAL_PATH There is a deadlock when the reply of FUSE_CANONICAL_PATH from user- space client, because the kern_path function will issue a new request and wait the respond from client which has been in wait state. The ba- cktrace is like this: <6>[ 518.977731] ntfs-3g S 0 2138 1 0x04000000 <4>[ 518.977745] Call trace: <4>[ 518.977757] __switch_to+0x130/0x13c <4>[ 518.977767] __schedule+0x740/0x964 <4>[ 518.977777] schedule+0x70/0x90 <4>[ 518.977794] __fuse_request_send+0x1a0/0x340 <4>[ 518.977808] fuse_simple_request+0x178/0x1c8 <4>[ 518.977818] fuse_lookup_name+0xfc/0x220 <4>[ 518.977829] fuse_lookup+0x48/0x134 <4>[ 518.977842] __lookup_slow+0xc8/0x154 <4>[ 518.977853] walk_component+0x1c0/0x728 <4>[ 518.977863] path_lookupat+0xa8/0x208 <4>[ 518.977875] filename_lookup+0x8c/0x190 <4>[ 518.977887] kern_path+0x30/0x3c <4>[ 518.977901] fuse_dev_do_write+0x79c/0x114c <4>[ 518.977914] fuse_dev_write+0x60/0x84 <4>[ 518.977928] do_iter_readv_writev+0x11c/0x158 <4>[ 518.977941] do_iter_write+0x7c/0x1b8 <4>[ 518.977953] vfs_writev+0x84/0xe8 <4>[ 518.977966] do_writev+0x78/0x114 <4>[ 518.977979] __arm64_sys_writev+0x1c/0x24 <4>[ 518.977992] el0_svc_common+0x98/0x160 <4>[ 518.978005] el0_svc_handler+0x5c/0x64 <4>[ 518.978015] el0_svc+0x8/0xc Fixes: fa199896a3e2 ("ANDROID: fuse: Add support for d_canonical_path") Signed-off-by: Cliff Chen Change-Id: I13487e5c956c4537c2554a44208d6664653ef4f1 --- fs/fuse/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 9861204da06f..34f57710dbc4 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1938,7 +1938,8 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, char *path = (char *)req->out.args[0].value; path[req->out.args[0].size - 1] = 0; - req->out.h.error = kern_path(path, 0, req->out.canonical_path); + if (req->out.h.error != -ENOSYS) + req->out.h.error = kern_path(path, 0, req->out.canonical_path); } spin_lock(&fpq->lock);