From: Lukas Czerner <lczerner(a)redhat.com>
[ Upstream commit 24dc9864914eb5813173cfa53313fcd02e4aea7d ]
Callers of __jbd2_journal_unfile_buffer() and
__jbd2_journal_refile_buffer() assume that the b_transaction is set. In
fact if it's not, we can end up with journal_head refcounting errors
leading to crash much later that might be very hard to track down. Add
asserts to make sure that is the case.
We also make sure that b_next_transaction is NULL in
__jbd2_journal_unfile_buffer() since the callers expect that as well and
we should not get into that stage in this state anyway, leading to
problems later on if we do.
Tested with fstests.
Signed-off-by: Lukas Czerner <lczerner(a)redhat.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/20200617092549.6712-1-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
fs/jbd2/transaction.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 3233e5ac9774f..622610934c9ad 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1906,6 +1906,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
*/
static void __jbd2_journal_unfile_buffer(struct journal_head *jh)
{
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+ J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+
__jbd2_journal_temp_unlink_buffer(jh);
jh->b_transaction = NULL;
jbd2_journal_put_journal_head(jh);
@@ -2453,6 +2456,13 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
was_dirty = test_clear_buffer_jbddirty(bh);
__jbd2_journal_temp_unlink_buffer(jh);
+
+ /*
+ * b_transaction must be set, otherwise the new b_transaction won't
+ * be holding jh reference
+ */
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+
/*
* We set b_transaction here because b_next_transaction will inherit
* our jh reference and thus __jbd2_journal_file_buffer() must not
--
2.25.1
From: Lukas Czerner <lczerner(a)redhat.com>
[ Upstream commit 24dc9864914eb5813173cfa53313fcd02e4aea7d ]
Callers of __jbd2_journal_unfile_buffer() and
__jbd2_journal_refile_buffer() assume that the b_transaction is set. In
fact if it's not, we can end up with journal_head refcounting errors
leading to crash much later that might be very hard to track down. Add
asserts to make sure that is the case.
We also make sure that b_next_transaction is NULL in
__jbd2_journal_unfile_buffer() since the callers expect that as well and
we should not get into that stage in this state anyway, leading to
problems later on if we do.
Tested with fstests.
Signed-off-by: Lukas Czerner <lczerner(a)redhat.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/20200617092549.6712-1-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
fs/jbd2/transaction.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 8de458d64134a..1478512ecab3e 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1896,6 +1896,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
*/
static void __jbd2_journal_unfile_buffer(struct journal_head *jh)
{
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+ J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+
__jbd2_journal_temp_unlink_buffer(jh);
jh->b_transaction = NULL;
jbd2_journal_put_journal_head(jh);
@@ -2443,6 +2446,13 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
was_dirty = test_clear_buffer_jbddirty(bh);
__jbd2_journal_temp_unlink_buffer(jh);
+
+ /*
+ * b_transaction must be set, otherwise the new b_transaction won't
+ * be holding jh reference
+ */
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+
/*
* We set b_transaction here because b_next_transaction will inherit
* our jh reference and thus __jbd2_journal_file_buffer() must not
--
2.25.1
From: Lukas Czerner <lczerner(a)redhat.com>
[ Upstream commit 24dc9864914eb5813173cfa53313fcd02e4aea7d ]
Callers of __jbd2_journal_unfile_buffer() and
__jbd2_journal_refile_buffer() assume that the b_transaction is set. In
fact if it's not, we can end up with journal_head refcounting errors
leading to crash much later that might be very hard to track down. Add
asserts to make sure that is the case.
We also make sure that b_next_transaction is NULL in
__jbd2_journal_unfile_buffer() since the callers expect that as well and
we should not get into that stage in this state anyway, leading to
problems later on if we do.
Tested with fstests.
Signed-off-by: Lukas Czerner <lczerner(a)redhat.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/20200617092549.6712-1-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
fs/jbd2/transaction.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index a355ca418e788..b4bde0ae10948 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1914,6 +1914,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
*/
static void __jbd2_journal_unfile_buffer(struct journal_head *jh)
{
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+ J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+
__jbd2_journal_temp_unlink_buffer(jh);
jh->b_transaction = NULL;
jbd2_journal_put_journal_head(jh);
@@ -2461,6 +2464,13 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
was_dirty = test_clear_buffer_jbddirty(bh);
__jbd2_journal_temp_unlink_buffer(jh);
+
+ /*
+ * b_transaction must be set, otherwise the new b_transaction won't
+ * be holding jh reference
+ */
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+
/*
* We set b_transaction here because b_next_transaction will inherit
* our jh reference and thus __jbd2_journal_file_buffer() must not
--
2.25.1
From: Lukas Czerner <lczerner(a)redhat.com>
[ Upstream commit 24dc9864914eb5813173cfa53313fcd02e4aea7d ]
Callers of __jbd2_journal_unfile_buffer() and
__jbd2_journal_refile_buffer() assume that the b_transaction is set. In
fact if it's not, we can end up with journal_head refcounting errors
leading to crash much later that might be very hard to track down. Add
asserts to make sure that is the case.
We also make sure that b_next_transaction is NULL in
__jbd2_journal_unfile_buffer() since the callers expect that as well and
we should not get into that stage in this state anyway, leading to
problems later on if we do.
Tested with fstests.
Signed-off-by: Lukas Czerner <lczerner(a)redhat.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/20200617092549.6712-1-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
fs/jbd2/transaction.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 43693b6797105..5a0de78a5d71a 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1915,6 +1915,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
*/
static void __jbd2_journal_unfile_buffer(struct journal_head *jh)
{
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+ J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+
__jbd2_journal_temp_unlink_buffer(jh);
jh->b_transaction = NULL;
jbd2_journal_put_journal_head(jh);
@@ -2462,6 +2465,13 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
was_dirty = test_clear_buffer_jbddirty(bh);
__jbd2_journal_temp_unlink_buffer(jh);
+
+ /*
+ * b_transaction must be set, otherwise the new b_transaction won't
+ * be holding jh reference
+ */
+ J_ASSERT_JH(jh, jh->b_transaction != NULL);
+
/*
* We set b_transaction here because b_next_transaction will inherit
* our jh reference and thus __jbd2_journal_file_buffer() must not
--
2.25.1
This reverts commit 1adb2ff1f6b170cdbc3925a359c8f39d2215dc20.
This breaks display wake up in stable kernels (5.7.x and 5.8.x).
Note that there is no upstream equivalent to this
revert. This patch was targeted for stable by Sasha's stable
patch process. Presumably there are some other changes necessary
for this patch to work properly on stable kernels.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1266
Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com>
Cc: stable(a)vger.kernel.org # 5.7.x, 5.8.x
Cc: Sasha Levin <sashal(a)kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 +---
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 16 ++++++----------
.../amd/display/dc/dce110/dce110_hw_sequencer.c | 11 +----------
3 files changed, 8 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 841cc051b7d0..48ab51533d5d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3298,11 +3298,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
write_i2c_redriver_setting(pipe_ctx, false);
}
}
-
- disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
-
dc->hwss.disable_stream(pipe_ctx);
+ disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
if (pipe_ctx->stream->timing.flags.DSC) {
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_set_dsc_enable(pipe_ctx, false);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 6124af571bff..91cd884d6f25 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1102,10 +1102,6 @@ static inline enum link_training_result perform_link_training_int(
dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
dpcd_set_training_pattern(link, dpcd_pattern);
- /* delay 5ms after notifying sink of idle pattern before switching output */
- if (link->connector_signal != SIGNAL_TYPE_EDP)
- msleep(5);
-
/* 4. mainlink output idle pattern*/
dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
@@ -1555,12 +1551,6 @@ bool perform_link_training_with_retries(
struct dc_link *link = stream->link;
enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
- /* We need to do this before the link training to ensure the idle pattern in SST
- * mode will be sent right after the link training
- */
- link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
- pipe_ctx->stream_res.stream_enc->id, true);
-
for (j = 0; j < attempts; ++j) {
dp_enable_link_phy(
@@ -1577,6 +1567,12 @@ bool perform_link_training_with_retries(
dp_set_panel_mode(link, panel_mode);
+ /* We need to do this before the link training to ensure the idle pattern in SST
+ * mode will be sent right after the link training
+ */
+ link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
+ pipe_ctx->stream_res.stream_enc->id, true);
+
if (link->aux_access_disabled) {
dc_link_dp_perform_link_training_skip_aux(link, link_setting);
return true;
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 2af1d74d16ad..b77e9dc16086 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -1069,17 +1069,8 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
}
- if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
-
- /*
- * After output is idle pattern some sinks need time to recognize the stream
- * has changed or they enter protection state and hang.
- */
- if (!dc_is_embedded_signal(pipe_ctx->stream->signal))
- msleep(60);
- }
-
}
--
2.25.4
Upstream commits fdfe7cbd5880 ("KVM: Pass MMU notifier range flags to
kvm_unmap_hva_range()") and b5331379bc62 ("KVM: arm64: Only reschedule
if MMU_NOTIFIER_RANGE_BLOCKABLE is not set") fix a "sleeping from invalid
context" BUG caused by unmap_stage2_range() attempting to reschedule when
called on the OOM path.
Unfortunately, these patches rely on the MMU notifier callback being
passed knowledge about whether or not blocking is permitted, which was
introduced in 4.19. Rather than backport this considerable amount of
infrastructure just for KVM on arm, instead just remove the conditional
reschedule.
Cc: <stable(a)vger.kernel.org> # v4.4 only
Cc: Marc Zyngier <maz(a)kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose(a)arm.com>
Cc: James Morse <james.morse(a)arm.com>
Signed-off-by: Will Deacon <will(a)kernel.org>
---
arch/arm/kvm/mmu.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index e0267532bd4e..edd392fdc14b 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -300,14 +300,6 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
next = kvm_pgd_addr_end(addr, end);
if (!pgd_none(*pgd))
unmap_puds(kvm, pgd, addr, next);
- /*
- * If we are dealing with a large range in
- * stage2 table, release the kvm->mmu_lock
- * to prevent starvation and lockup detector
- * warnings.
- */
- if (kvm && (next != end))
- cond_resched_lock(&kvm->mmu_lock);
} while (pgd++, addr = next, addr != end);
}
--
2.28.0.297.g1956fa8f8d-goog
This is the start of the stable review cycle for the 4.9.234 release.
There are 39 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Wed, 26 Aug 2020 08:23:34 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.234-rc…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.9.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.9.234-rc1
Juergen Gross <jgross(a)suse.com>
xen: don't reschedule in preemption off sections
Peter Xu <peterx(a)redhat.com>
mm/hugetlb: fix calculation of adjust_range_if_pmd_sharing_possible
Al Viro <viro(a)zeniv.linux.org.uk>
do_epoll_ctl(): clean the failure exits up a bit
Marc Zyngier <maz(a)kernel.org>
epoll: Keep a reference on files added to the check list
Michael Ellerman <mpe(a)ellerman.id.au>
powerpc: Allow 4224 bytes of stack expansion for the signal frame
Vasant Hegde <hegdevasant(a)linux.vnet.ibm.com>
powerpc/pseries: Do not initiate shutdown when system is running on UPS
Tom Rix <trix(a)redhat.com>
net: dsa: b53: check for timeout
Dinghao Liu <dinghao.liu(a)zju.edu.cn>
ASoC: intel: Fix memleak in sst_media_open
Fugang Duan <fugang.duan(a)nxp.com>
net: fec: correct the error path for regulator disable in probe
Przemyslaw Patynowski <przemyslawx.patynowski(a)intel.com>
i40e: Set RX_ONLY mode for unicast promiscuous on VLAN
Eric Sandeen <sandeen(a)redhat.com>
ext4: fix potential negative array index in do_split()
Luc Van Oostenryck <luc.vanoostenryck(a)gmail.com>
alpha: fix annotation of io{read,write}{16,32}be()
Eiichi Tsukata <devel(a)etsukata.com>
xfs: Fix UBSAN null-ptr-deref in xfs_sysfs_init
Mao Wenan <wenan.mao(a)linux.alibaba.com>
virtio_ring: Avoid loop when vq is broken in virtqueue_poll
Javed Hasan <jhasan(a)marvell.com>
scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases
Zhe Li <lizhe67(a)huawei.com>
jffs2: fix UAF problem
Darrick J. Wong <darrick.wong(a)oracle.com>
xfs: fix inode quota reservation checks
Greg Ungerer <gerg(a)linux-m68k.org>
m68knommu: fix overwriting of bits in ColdFire V3 cache control
Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
Input: psmouse - add a newline when printing 'proto' by sysfs
Evgeny Novikov <novikov(a)ispras.ru>
media: vpss: clean up resources in init
Chuhong Yuan <hslester96(a)gmail.com>
media: budget-core: Improve exception handling in budget_register()
Stanley Chu <stanley.chu(a)mediatek.com>
scsi: ufs: Add DELAY_BEFORE_LPM quirk for Micron devices
Jan Kara <jack(a)suse.cz>
ext4: fix checking of directory entry validity for inline directories
Eric Biggers <ebiggers(a)google.com>
ext4: clean up ext4_match() and callers
zhangyi (F) <yi.zhang(a)huawei.com>
jbd2: add the missing unlock_buffer() in the error path of jbd2_write_superblock()
Charan Teja Reddy <charante(a)codeaurora.org>
mm, page_alloc: fix core hung in free_pcppages_bulk()
Doug Berger <opendmb(a)gmail.com>
mm: include CMA pages in lowmem_reserve at boot
Wei Yongjun <weiyongjun1(a)huawei.com>
kernel/relay.c: fix memleak on destroy relay channel
Jann Horn <jannh(a)google.com>
romfs: fix uninitialized memory leak in romfs_dev_read()
Josef Bacik <josef(a)toxicpanda.com>
btrfs: don't show full path of bind mounts in subvol=
Marcos Paulo de Souza <mpdesouza(a)suse.com>
btrfs: export helpers for subvolume name/id resolution
Hugh Dickins <hughd(a)google.com>
khugepaged: adjust VM_BUG_ON_MM() in __khugepaged_enter()
Hugh Dickins <hughd(a)google.com>
khugepaged: khugepaged_test_exit() check mmget_still_valid()
Kevin Hao <haokexin(a)gmail.com>
tracing/hwlat: Honor the tracing_cpumask
Steven Rostedt (VMware) <rostedt(a)goodmis.org>
tracing: Clean up the hwlat binding code
Masami Hiramatsu <mhiramat(a)kernel.org>
perf probe: Fix memory leakage when the probe point is not found
Liu Ying <victor.liu(a)nxp.com>
drm/imx: imx-ldb: Disable both channels for split mode in enc->disable()
Jan Beulich <JBeulich(a)suse.com>
x86/asm: Add instruction suffixes to bitops
Uros Bizjak <ubizjak(a)gmail.com>
x86/asm: Remove unnecessary \n\t in front of CC_SET() from asm templates
-------------
Diffstat:
Makefile | 4 +-
arch/alpha/include/asm/io.h | 8 +-
arch/m68k/include/asm/m53xxacr.h | 6 +-
arch/powerpc/mm/fault.c | 7 +-
arch/powerpc/platforms/pseries/ras.c | 1 -
arch/x86/include/asm/archrandom.h | 8 +-
arch/x86/include/asm/bitops.h | 29 ++++---
arch/x86/include/asm/percpu.h | 2 +-
drivers/gpu/drm/imx/imx-ldb.c | 7 +-
drivers/input/mouse/psmouse-base.c | 2 +-
drivers/media/pci/ttpci/budget-core.c | 11 ++-
drivers/media/platform/davinci/vpss.c | 20 ++++-
drivers/net/dsa/b53/b53_common.c | 2 +
drivers/net/ethernet/freescale/fec_main.c | 4 +-
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 2 +-
drivers/net/ethernet/intel/i40e/i40e_common.c | 35 ++++++--
drivers/scsi/libfc/fc_disc.c | 12 ++-
drivers/scsi/ufs/ufs_quirks.h | 1 +
drivers/scsi/ufs/ufshcd.c | 2 +
drivers/virtio/virtio_ring.c | 3 +
drivers/xen/preempt.c | 2 +-
fs/btrfs/ctree.h | 2 +
fs/btrfs/export.c | 8 +-
fs/btrfs/export.h | 5 ++
fs/btrfs/super.c | 18 +++--
fs/eventpoll.c | 19 +++--
fs/ext4/namei.c | 99 +++++++++--------------
fs/jbd2/journal.c | 4 +-
fs/jffs2/dir.c | 6 +-
fs/romfs/storage.c | 4 +-
fs/xfs/xfs_sysfs.h | 6 +-
fs/xfs/xfs_trans_dquot.c | 2 +-
kernel/relay.c | 1 +
kernel/trace/trace_hwlat.c | 37 ++++-----
mm/hugetlb.c | 24 +++---
mm/khugepaged.c | 7 +-
mm/page_alloc.c | 7 +-
sound/soc/intel/atom/sst-mfld-platform-pcm.c | 5 +-
tools/perf/util/probe-finder.c | 2 +-
39 files changed, 241 insertions(+), 183 deletions(-)
From: Marcos Paulo de Souza <mpdesouza(a)suse.com>
[BUG]
After commit 9afc66498a0b ("btrfs: block-group: refactor how we read one
block group item"), cache->length is being assigned after calling
btrfs_create_block_group_cache. This causes a problem since
set_free_space_tree_thresholds is calculate the free-space threshould to
decide is the free-space tree should convert from extents to bitmaps.
The current code calls set_free_space_tree_thresholds with cache->length
being 0, which then makes cache->bitmap_high_thresh being zero. This
implies the system will always use bitmap instead of extents, which is
not desired if the block group is not fragmented.
This behavior can be seen by a test that expects to repair systems
with FREE_SPACE_EXTENT and FREE_SPACE_BITMAP, but the current code only
created FREE_SPACE_BITMAP.
[FIX]
Call set_free_space_tree_thresholds after setting cache->length. There
is now a WARN_ON in set_free_space_tree_thresholds to help preventing
the same mistake to happen again in the future.
Link: https://github.com/kdave/btrfs-progs/issues/251
Fixes: 9afc66498a0b ("btrfs: block-group: refactor how we read one block group item")
CC: stable(a)vger.kernel.org # 5.8+
Reviewed-by: Qu Wenruo <wqu(a)suse.com>
Reviewed-by: Filipe Manana <fdmanana(a)suse.com>
Signed-off-by: Marcos Paulo de Souza <mpdesouza(a)suse.com>
---
Changes from v2:
* Add a WARN_ON and changed the warn message (Filipe)
* Add a Reviewed-by tag from Filipe
Changes from v1:
* Add warn message (Qu)
* Add a Reviewed-by tag from Qu
fs/btrfs/block-group.c | 4 +++-
fs/btrfs/free-space-tree.c | 4 ++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 44fdfa2eeb2e..01e8ba1da1d3 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1798,7 +1798,6 @@ static struct btrfs_block_group *btrfs_create_block_group_cache(
cache->fs_info = fs_info;
cache->full_stripe_len = btrfs_full_stripe_len(fs_info, start);
- set_free_space_tree_thresholds(cache);
cache->discard_index = BTRFS_DISCARD_INDEX_UNUSED;
@@ -1908,6 +1907,8 @@ static int read_one_block_group(struct btrfs_fs_info *info,
read_block_group_item(cache, path, key);
+ set_free_space_tree_thresholds(cache);
+
if (need_clear) {
/*
* When we mount with old space cache, we need to
@@ -2128,6 +2129,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
return -ENOMEM;
cache->length = size;
+ set_free_space_tree_thresholds(cache);
cache->used = bytes_used;
cache->flags = type;
cache->last_byte_to_unpin = (u64)-1;
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index 8b1f5c8897b7..f072c106b82b 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -22,6 +22,10 @@ void set_free_space_tree_thresholds(struct btrfs_block_group *cache)
size_t bitmap_size;
u64 num_bitmaps, total_bitmap_size;
+ if (WARN_ON(cache->length == 0))
+ btrfs_warn(cache->fs_info, "block group %llu length is zero",
+ cache->start);
+
/*
* We convert to bitmaps when the disk space required for using extents
* exceeds that required for using bitmaps.
--
2.28.0