From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Xiubo Li <xiubli@redhat.com>,
Jeff Layton <jlayton@kernel.org>,
Ilya Dryomov <idryomov@gmail.com>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.10 45/63] ceph: remove the capsnaps when removing caps
Date: Fri, 24 Sep 2021 14:44:45 +0200 [thread overview]
Message-ID: <20210924124335.822963063@linuxfoundation.org> (raw)
In-Reply-To: <20210924124334.228235870@linuxfoundation.org>
From: Xiubo Li <xiubli@redhat.com>
[ Upstream commit a6d37ccdd240e80f26aaea0e62cda310e0e184d7 ]
capsnaps will take inode references via ihold when queueing to flush.
When force unmounting, the client will just close the sessions and
may never get a flush reply, causing a leak and inode ref leak.
Fix this by removing the capsnaps for an inode when removing the caps.
URL: https://tracker.ceph.com/issues/52295
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ceph/caps.c | 68 +++++++++++++++++++++++++++++++++-----------
fs/ceph/mds_client.c | 31 +++++++++++++++++++-
fs/ceph/super.h | 6 ++++
3 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 678dac8365ed..f303e0d87c3f 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -3169,7 +3169,16 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
break;
}
}
- BUG_ON(!found);
+
+ if (!found) {
+ /*
+ * The capsnap should already be removed when removing
+ * auth cap in the case of a forced unmount.
+ */
+ WARN_ON_ONCE(ci->i_auth_cap);
+ goto unlock;
+ }
+
capsnap->dirty_pages -= nr;
if (capsnap->dirty_pages == 0) {
complete_capsnap = true;
@@ -3191,6 +3200,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
complete_capsnap ? " (complete capsnap)" : "");
}
+unlock:
spin_unlock(&ci->i_ceph_lock);
if (last) {
@@ -3657,6 +3667,43 @@ out:
iput(inode);
}
+void __ceph_remove_capsnap(struct inode *inode, struct ceph_cap_snap *capsnap,
+ bool *wake_ci, bool *wake_mdsc)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
+ bool ret;
+
+ lockdep_assert_held(&ci->i_ceph_lock);
+
+ dout("removing capsnap %p, inode %p ci %p\n", capsnap, inode, ci);
+
+ list_del_init(&capsnap->ci_item);
+ ret = __detach_cap_flush_from_ci(ci, &capsnap->cap_flush);
+ if (wake_ci)
+ *wake_ci = ret;
+
+ spin_lock(&mdsc->cap_dirty_lock);
+ if (list_empty(&ci->i_cap_flush_list))
+ list_del_init(&ci->i_flushing_item);
+
+ ret = __detach_cap_flush_from_mdsc(mdsc, &capsnap->cap_flush);
+ if (wake_mdsc)
+ *wake_mdsc = ret;
+ spin_unlock(&mdsc->cap_dirty_lock);
+}
+
+void ceph_remove_capsnap(struct inode *inode, struct ceph_cap_snap *capsnap,
+ bool *wake_ci, bool *wake_mdsc)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ lockdep_assert_held(&ci->i_ceph_lock);
+
+ WARN_ON_ONCE(capsnap->dirty_pages || capsnap->writing);
+ __ceph_remove_capsnap(inode, capsnap, wake_ci, wake_mdsc);
+}
+
/*
* Handle FLUSHSNAP_ACK. MDS has flushed snap data to disk and we can
* throw away our cap_snap.
@@ -3694,23 +3741,10 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
capsnap, capsnap->follows);
}
}
- if (flushed) {
- WARN_ON(capsnap->dirty_pages || capsnap->writing);
- dout(" removing %p cap_snap %p follows %lld\n",
- inode, capsnap, follows);
- list_del(&capsnap->ci_item);
- wake_ci |= __detach_cap_flush_from_ci(ci, &capsnap->cap_flush);
-
- spin_lock(&mdsc->cap_dirty_lock);
-
- if (list_empty(&ci->i_cap_flush_list))
- list_del_init(&ci->i_flushing_item);
-
- wake_mdsc |= __detach_cap_flush_from_mdsc(mdsc,
- &capsnap->cap_flush);
- spin_unlock(&mdsc->cap_dirty_lock);
- }
+ if (flushed)
+ ceph_remove_capsnap(inode, capsnap, &wake_ci, &wake_mdsc);
spin_unlock(&ci->i_ceph_lock);
+
if (flushed) {
ceph_put_snap_context(capsnap->context);
ceph_put_cap_snap(capsnap);
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 46606fb5b886..0f57b7d09457 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1587,14 +1587,39 @@ out:
return ret;
}
+static int remove_capsnaps(struct ceph_mds_client *mdsc, struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_cap_snap *capsnap;
+ int capsnap_release = 0;
+
+ lockdep_assert_held(&ci->i_ceph_lock);
+
+ dout("removing capsnaps, ci is %p, inode is %p\n", ci, inode);
+
+ while (!list_empty(&ci->i_cap_snaps)) {
+ capsnap = list_first_entry(&ci->i_cap_snaps,
+ struct ceph_cap_snap, ci_item);
+ __ceph_remove_capsnap(inode, capsnap, NULL, NULL);
+ ceph_put_snap_context(capsnap->context);
+ ceph_put_cap_snap(capsnap);
+ capsnap_release++;
+ }
+ wake_up_all(&ci->i_cap_wq);
+ wake_up_all(&mdsc->cap_flushing_wq);
+ return capsnap_release;
+}
+
static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
void *arg)
{
struct ceph_fs_client *fsc = (struct ceph_fs_client *)arg;
+ struct ceph_mds_client *mdsc = fsc->mdsc;
struct ceph_inode_info *ci = ceph_inode(inode);
LIST_HEAD(to_remove);
bool dirty_dropped = false;
bool invalidate = false;
+ int capsnap_release = 0;
dout("removing cap %p, ci is %p, inode is %p\n",
cap, ci, &ci->vfs_inode);
@@ -1602,7 +1627,6 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
__ceph_remove_cap(cap, false);
if (!ci->i_auth_cap) {
struct ceph_cap_flush *cf;
- struct ceph_mds_client *mdsc = fsc->mdsc;
if (READ_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
if (inode->i_data.nrpages > 0)
@@ -1666,6 +1690,9 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
list_add(&ci->i_prealloc_cap_flush->i_list, &to_remove);
ci->i_prealloc_cap_flush = NULL;
}
+
+ if (!list_empty(&ci->i_cap_snaps))
+ capsnap_release = remove_capsnaps(mdsc, inode);
}
spin_unlock(&ci->i_ceph_lock);
while (!list_empty(&to_remove)) {
@@ -1682,6 +1709,8 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
ceph_queue_invalidate(inode);
if (dirty_dropped)
iput(inode);
+ while (capsnap_release--)
+ iput(inode);
return 0;
}
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index a8c460393b01..9362eeb5812d 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -1134,6 +1134,12 @@ extern void ceph_put_cap_refs_no_check_caps(struct ceph_inode_info *ci,
int had);
extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
struct ceph_snap_context *snapc);
+extern void __ceph_remove_capsnap(struct inode *inode,
+ struct ceph_cap_snap *capsnap,
+ bool *wake_ci, bool *wake_mdsc);
+extern void ceph_remove_capsnap(struct inode *inode,
+ struct ceph_cap_snap *capsnap,
+ bool *wake_ci, bool *wake_mdsc);
extern void ceph_flush_snaps(struct ceph_inode_info *ci,
struct ceph_mds_session **psession);
extern bool __ceph_should_report_size(struct ceph_inode_info *ci);
--
2.33.0
next prev parent reply other threads:[~2021-09-24 13:09 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-24 12:44 [PATCH 5.10 00/63] 5.10.69-rc1 review Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 01/63] PCI: pci-bridge-emul: Add PCIe Root Capabilities Register Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 02/63] PCI: aardvark: Fix reporting CRS value Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 03/63] console: consume APC, DM, DCS Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 04/63] s390/pci_mmio: fully validate the VMA before calling follow_pte() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 05/63] ARM: Qualify enabling of swiotlb_init() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 06/63] ARM: 9077/1: PLT: Move struct plt_entries definition to header Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 07/63] ARM: 9078/1: Add warn suppress parameter to arm_gen_branch_link() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 08/63] ARM: 9079/1: ftrace: Add MODULE_PLTS support Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 09/63] ARM: 9098/1: ftrace: MODULE_PLT: Fix build problem without DYNAMIC_FTRACE Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 10/63] [PATCH] Revert "net/mlx5: Register to devlink ingress VLAN filter trap" Greg Kroah-Hartman
2021-09-27 8:39 ` Tariq Toukan
2021-09-24 12:44 ` [PATCH 5.10 11/63] sctp: validate chunk size in __rcv_asconf_lookup Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 12/63] sctp: add param size validation for SCTP_PARAM_SET_PRIMARY Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 13/63] staging: rtl8192u: Fix bitwise vs logical operator in TranslateRxSignalStuff819xUsb() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 14/63] coredump: fix memleak in dump_vma_snapshot() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 15/63] um: virtio_uml: fix memory leak on init failures Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 16/63] dmaengine: acpi: Avoid comparison GSI with Linux vIRQ Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 17/63] perf test: Fix bpf test sample mismatch reporting Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 18/63] perf tools: Allow build-id with trailing zeros Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 19/63] thermal/drivers/exynos: Fix an error code in exynos_tmu_probe() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 20/63] 9p/trans_virtio: Remove sysfs file on probe failure Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 21/63] prctl: allow to setup brk for et_dyn executables Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 22/63] nilfs2: use refcount_dec_and_lock() to fix potential UAF Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 23/63] profiling: fix shift-out-of-bounds bugs Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 24/63] PM: sleep: core: Avoid setting power.must_resume to false Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 25/63] pwm: lpc32xx: Dont modify HW state in .probe() after the PWM chip was registered Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 26/63] pwm: mxs: " Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 27/63] dmaengine: idxd: fix wq slot allocation index check Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 28/63] platform/chrome: sensorhub: Add trace events for sample Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 29/63] platform/chrome: cros_ec_trace: Fix format warnings Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 30/63] ceph: allow ceph_put_mds_session to take NULL or ERR_PTR Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 31/63] ceph: cancel delayed work instead of flushing on mdsc teardown Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 32/63] Kconfig.debug: drop selecting non-existing HARDLOCKUP_DETECTOR_ARCH Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 33/63] tools/bootconfig: Fix tracing_on option checking in ftrace2bconf.sh Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 34/63] thermal/core: Fix thermal_cooling_device_register() prototype Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 35/63] drm/amdgpu: Disable PCIE_DPM on Intel RKL Platform Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 36/63] drivers: base: cacheinfo: Get rid of DEFINE_SMP_CALL_CACHE_FUNCTION() Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 37/63] dma-buf: DMABUF_MOVE_NOTIFY should depend on DMA_SHARED_BUFFER Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 38/63] parisc: Move pci_dev_is_behind_card_dino to where it is used Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 39/63] iommu/amd: Relocate GAMSup check to early_enable_iommus Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 40/63] dmaengine: idxd: depends on !UML Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 41/63] dmaengine: sprd: Add missing MODULE_DEVICE_TABLE Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 42/63] dmaengine: ioat: depends on !UML Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 43/63] dmaengine: xilinx_dma: Set DMA mask for coherent APIs Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 44/63] ceph: request Fw caps before updating the mtime in ceph_write_iter Greg Kroah-Hartman
2021-09-24 12:44 ` Greg Kroah-Hartman [this message]
2021-09-24 12:44 ` [PATCH 5.10 46/63] ceph: lockdep annotations for try_nonblocking_invalidate Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 47/63] btrfs: update the bdev time directly when closing Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 48/63] btrfs: fix lockdep warning while mounting sprout fs Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 49/63] nilfs2: fix memory leak in nilfs_sysfs_create_device_group Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 50/63] nilfs2: fix NULL pointer in nilfs_##name##_attr_release Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 51/63] nilfs2: fix memory leak in nilfs_sysfs_create_##name##_group Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 52/63] nilfs2: fix memory leak in nilfs_sysfs_delete_##name##_group Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 53/63] nilfs2: fix memory leak in nilfs_sysfs_create_snapshot_group Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 54/63] nilfs2: fix memory leak in nilfs_sysfs_delete_snapshot_group Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 55/63] habanalabs: add validity check for event ID received from F/W Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 56/63] pwm: img: Dont modify HW state in .remove() callback Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 57/63] pwm: rockchip: " Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 58/63] pwm: stm32-lp: " Greg Kroah-Hartman
2021-09-24 12:44 ` [PATCH 5.10 59/63] blk-throttle: fix UAF by deleteing timer in blk_throtl_exit() Greg Kroah-Hartman
2021-09-24 12:45 ` [PATCH 5.10 60/63] blk-mq: allow 4x BLK_MAX_REQUEST_COUNT at blk_plug for multiple_queues Greg Kroah-Hartman
2021-09-24 12:45 ` [PATCH 5.10 61/63] rtc: rx8010: select REGMAP_I2C Greg Kroah-Hartman
2021-09-24 12:45 ` [PATCH 5.10 62/63] sched/idle: Make the idle timer expire in hard interrupt context Greg Kroah-Hartman
2021-09-24 12:45 ` [PATCH 5.10 63/63] drm/nouveau/nvkm: Replace -ENOSYS with -ENODEV Greg Kroah-Hartman
2021-09-24 14:12 ` [PATCH 5.10 00/63] 5.10.69-rc1 review Daniel Díaz
2021-09-24 22:11 ` Florian Fainelli
2021-09-25 11:48 ` Greg Kroah-Hartman
2021-09-24 17:57 ` Jon Hunter
2021-09-24 18:05 ` Fox Chen
2021-09-24 21:49 ` Pavel Machek
2021-09-24 21:52 ` 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=20210924124335.822963063@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=idryomov@gmail.com \
--cc=jlayton@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
--cc=xiubli@redhat.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;
as well as URLs for NNTP newsgroup(s).