From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev,
Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>,
Miklos Szeredi <mszeredi@redhat.com>,
Yang Bo <yb203166@antfin.com>
Subject: [PATCH 5.10 54/68] fuse: fix deadlock between atomic O_TRUNC and page invalidation
Date: Mon, 24 Apr 2023 15:18:25 +0200 [thread overview]
Message-ID: <20230424131129.732669316@linuxfoundation.org> (raw)
In-Reply-To: <20230424131127.653885914@linuxfoundation.org>
From: Miklos Szeredi <mszeredi@redhat.com>
commit 2fdbb8dd01556e1501132b5ad3826e8f71e24a8b upstream.
fuse_finish_open() will be called with FUSE_NOWRITE set in case of atomic
O_TRUNC open(), so commit 76224355db75 ("fuse: truncate pagecache on
atomic_o_trunc") replaced invalidate_inode_pages2() by truncate_pagecache()
in such a case to avoid the A-A deadlock. However, we found another A-B-B-A
deadlock related to the case above, which will cause the xfstests
generic/464 testcase hung in our virtio-fs test environment.
For example, consider two processes concurrently open one same file, one
with O_TRUNC and another without O_TRUNC. The deadlock case is described
below, if open(O_TRUNC) is already set_nowrite(acquired A), and is trying
to lock a page (acquiring B), open() could have held the page lock
(acquired B), and waiting on the page writeback (acquiring A). This would
lead to deadlocks.
open(O_TRUNC)
----------------------------------------------------------------
fuse_open_common
inode_lock [C acquire]
fuse_set_nowrite [A acquire]
fuse_finish_open
truncate_pagecache
lock_page [B acquire]
truncate_inode_page
unlock_page [B release]
fuse_release_nowrite [A release]
inode_unlock [C release]
----------------------------------------------------------------
open()
----------------------------------------------------------------
fuse_open_common
fuse_finish_open
invalidate_inode_pages2
lock_page [B acquire]
fuse_launder_page
fuse_wait_on_page_writeback [A acquire & release]
unlock_page [B release]
----------------------------------------------------------------
Besides this case, all calls of invalidate_inode_pages2() and
invalidate_inode_pages2_range() in fuse code also can deadlock with
open(O_TRUNC).
Fix by moving the truncate_pagecache() call outside the nowrite protected
region. The nowrite protection is only for delayed writeback
(writeback_cache) case, where inode lock does not protect against
truncation racing with writes on the server. Write syscalls racing with
page cache truncation still get the inode lock protection.
This patch also changes the order of filemap_invalidate_lock()
vs. fuse_set_nowrite() in fuse_open_common(). This new order matches the
order found in fuse_file_fallocate() and fuse_do_setattr().
Reported-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
Tested-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
Fixes: e4648309b85a ("fuse: truncate pending writes on O_TRUNC")
Cc: <stable@vger.kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fuse/dir.c | 5 +++++
fs/fuse/file.c | 29 +++++++++++++++++------------
2 files changed, 22 insertions(+), 12 deletions(-)
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -537,6 +537,7 @@ static int fuse_create_open(struct inode
struct fuse_entry_out outentry;
struct fuse_inode *fi;
struct fuse_file *ff;
+ bool trunc = flags & O_TRUNC;
/* Userspace expects S_IFREG in create mode */
BUG_ON((mode & S_IFMT) != S_IFREG);
@@ -604,6 +605,10 @@ static int fuse_create_open(struct inode
} else {
file->private_data = ff;
fuse_finish_open(inode, file);
+ if (fm->fc->atomic_o_trunc && trunc)
+ truncate_pagecache(inode, 0);
+ else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
+ invalidate_inode_pages2(inode->i_mapping);
}
return err;
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -206,14 +206,10 @@ void fuse_finish_open(struct inode *inod
fi->attr_version = atomic64_inc_return(&fc->attr_version);
i_size_write(inode, 0);
spin_unlock(&fi->lock);
- truncate_pagecache(inode, 0);
fuse_invalidate_attr(inode);
if (fc->writeback_cache)
file_update_time(file);
- } else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) {
- invalidate_inode_pages2(inode->i_mapping);
}
-
if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
fuse_link_write_file(file);
}
@@ -236,30 +232,39 @@ int fuse_open_common(struct inode *inode
if (err)
return err;
- if (is_wb_truncate || dax_truncate) {
+ if (is_wb_truncate || dax_truncate)
inode_lock(inode);
- fuse_set_nowrite(inode);
- }
if (dax_truncate) {
down_write(&get_fuse_inode(inode)->i_mmap_sem);
err = fuse_dax_break_layouts(inode, 0, 0);
if (err)
- goto out;
+ goto out_inode_unlock;
}
+ if (is_wb_truncate || dax_truncate)
+ fuse_set_nowrite(inode);
+
err = fuse_do_open(fm, get_node_id(inode), file, isdir);
if (!err)
fuse_finish_open(inode, file);
-out:
+ if (is_wb_truncate || dax_truncate)
+ fuse_release_nowrite(inode);
+ if (!err) {
+ struct fuse_file *ff = file->private_data;
+
+ if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC))
+ truncate_pagecache(inode, 0);
+ else if (!(ff->open_flags & FOPEN_KEEP_CACHE))
+ invalidate_inode_pages2(inode->i_mapping);
+ }
if (dax_truncate)
up_write(&get_fuse_inode(inode)->i_mmap_sem);
- if (is_wb_truncate | dax_truncate) {
- fuse_release_nowrite(inode);
+out_inode_unlock:
+ if (is_wb_truncate || dax_truncate)
inode_unlock(inode);
- }
return err;
}
next prev parent reply other threads:[~2023-04-24 13:36 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-24 13:17 [PATCH 5.10 00/68] 5.10.179-rc1 review Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 01/68] ARM: dts: rockchip: fix a typo error for rk3288 spdif node Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 02/68] arm64: dts: qcom: ipq8074-hk01: enable QMP device, not the PHY node Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 03/68] arm64: dts: meson-g12-common: specify full DMC range Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 04/68] arm64: dts: imx8mm-evk: correct pmic clock source Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 05/68] netfilter: br_netfilter: fix recent physdev match breakage Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 06/68] regulator: fan53555: Explicitly include bits header Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 07/68] net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 08/68] virtio_net: bugfix overflow inside xdp_linearize_page() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 09/68] sfc: Split STATE_READY in to STATE_NET_DOWN and STATE_NET_UP Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 10/68] sfc: Fix use-after-free due to selftest_work Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 11/68] netfilter: nf_tables: fix ifdef to also consider nf_tables=m Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 12/68] i40e: fix accessing vsi->active_filters without holding lock Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 13/68] i40e: fix i40e_setup_misc_vector() error handling Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 14/68] mlxfw: fix null-ptr-deref in mlxfw_mfa2_tlv_next() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 15/68] net: rpl: fix rpl header size calculation Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 16/68] mlxsw: pci: Fix possible crash during initialization Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 17/68] bpf: Fix incorrect verifier pruning due to missing register precision taints Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 18/68] e1000e: Disable TSO on i219-LM card to increase speed Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 19/68] f2fs: Fix f2fs_truncate_partial_nodes ftrace event Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 20/68] Input: i8042 - add quirk for Fujitsu Lifebook A574/H Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 21/68] selftests: sigaltstack: fix -Wuninitialized Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 22/68] scsi: megaraid_sas: Fix fw_crash_buffer_show() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 23/68] scsi: core: Improve scsi_vpd_inquiry() checks Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 24/68] net: dsa: b53: mmap: add phy ops Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 25/68] s390/ptrace: fix PTRACE_GET_LAST_BREAK error handling Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 26/68] nvme-tcp: fix a possible UAF when failing to allocate an io queue Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 27/68] xen/netback: use same error messages for same errors Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.10 28/68] powerpc/doc: Fix htmldocs errors Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 29/68] xfs: drop submit side trans alloc for append ioends Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 30/68] iio: light: tsl2772: fix reading proximity-diodes from device tree Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 31/68] nilfs2: initialize unused bytes in segment summary blocks Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 32/68] memstick: fix memory leak if card device is never registered Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 33/68] kernel/sys.c: fix and improve control flow in __sys_setres[ug]id() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 34/68] mmc: sdhci_am654: Set HIGH_SPEED_ENA for SDR12 and SDR25 Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 35/68] mm/khugepaged: check again on anon uffd-wp during isolation Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 36/68] sched/uclamp: Make task_fits_capacity() use util_fits_cpu() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 37/68] sched/uclamp: Fix fits_capacity() check in feec() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 38/68] sched/uclamp: Make select_idle_capacity() use util_fits_cpu() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 39/68] sched/uclamp: Make asym_fits_capacity() " Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 40/68] sched/uclamp: Make cpu_overutilized() " Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 41/68] sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()s early exit condition Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 42/68] sched/fair: Detect capacity inversion Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 43/68] sched/fair: Consider capacity inversion in util_fits_cpu() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 44/68] sched/uclamp: Fix a uninitialized variable warnings Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 45/68] sched/fair: Fixes for capacity inversion detection Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 46/68] MIPS: Define RUNTIME_DISCARD_EXIT in LD script Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 47/68] [PATCH v2 stable-5.10.y stable-5.15.y] docs: futex: Fix kernel-doc references after code split-up preparation Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 48/68] purgatory: fix disabling debug info Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 49/68] virtiofs: clean up error handling in virtio_fs_get_tree() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 50/68] virtiofs: split requests that exceed virtqueue size Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 51/68] fuse: check s_root when destroying sb Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 52/68] fuse: fix attr version comparison in fuse_read_update_size() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 53/68] fuse: always revalidate rename target dentry Greg Kroah-Hartman
2023-04-24 13:18 ` Greg Kroah-Hartman [this message]
2023-04-24 13:18 ` [PATCH 5.10 55/68] Revert "ext4: fix use-after-free in ext4_xattr_set_entry" Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 56/68] ext4: remove duplicate definition of ext4_xattr_ibody_inline_set() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 57/68] ext4: fix use-after-free in ext4_xattr_set_entry Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 58/68] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 59/68] tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 60/68] inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 61/68] dccp: Call inet6_destroy_sock() via sk->sk_destruct() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 62/68] sctp: " Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 63/68] pwm: meson: Explicitly set .polarity in .get_state() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 64/68] pwm: iqs620a: " Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 65/68] pwm: hibvt: " Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 66/68] iio: adc: at91-sama5d2_adc: fix an error code in at91_adc_allocate_trigger() Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 67/68] ASoC: fsl_asrc_dma: fix potential null-ptr-deref Greg Kroah-Hartman
2023-04-24 13:18 ` [PATCH 5.10 68/68] ASN.1: Fix check for strdup() success Greg Kroah-Hartman
2023-04-25 1:04 ` [PATCH 5.10 00/68] 5.10.179-rc1 review Guenter Roeck
2023-04-25 10:44 ` Jon Hunter
2023-04-25 13:28 ` Naresh Kamboju
2023-04-25 13:35 ` Chris Paterson
2023-04-25 18:43 ` Florian Fainelli
2023-04-26 0:28 ` Shuah Khan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230424131129.732669316@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=mszeredi@redhat.com \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=yb203166@antfin.com \
--cc=zhangjiachen.jaycee@bytedance.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox