SHA256
1
0
forked from pool/u-boot
u-boot/0013-uboot-fs-btrfs-Fix-LZO-false-decomp.patch
Matthias Brugger 3f5ae570bf Accepting request 795564 from hardware👢staging
- Drop downstream zynqmp generic patches since zynqmp virt config
  superseed it:
Patch queue updated from git://github.com/openSUSE/u-boot.git tumbleweed-2020.04
* Patches dropped:
  0005-zynqmp-Add-generic-target.patch
  0006-tools-zynqmpbif-Add-support-for-loa.patch
  0007-boo-1123170-Remove-ubifs-support-fr.patch
  0008-zynqmp-generic-fix-compilation.patch
  0009-boo-1144161-Remove-nand-mtd-spi-dfu.patch
  0010-Kconfig-add-btrfs-to-distro-boot.patch
  0011-configs-Re-sync-with-CONFIG_DISTRO_.patch
  0012-configs-am335x_evm-disable-BTRFS.patch
  0013-net-bcmgenet-Don-t-set-ID_MODE_DIS-.patch
  0014-uboot-fs-btrfs-Use-LZO_LEN-to-repla.patch
  0015-uboot-fs-btrfs-Fix-LZO-false-decomp.patch
* Patches added:
  0005-tools-zynqmpbif-Add-support-for-loa.patch
  0006-boo-1123170-Remove-ubifs-support-fr.patch
  0007-boo-1144161-Remove-nand-mtd-spi-dfu.patch
  0008-Kconfig-add-btrfs-to-distro-boot.patch
  0009-configs-Re-sync-with-CONFIG_DISTRO_.patch
  0010-configs-am335x_evm-disable-BTRFS.patch
  0011-net-bcmgenet-Don-t-set-ID_MODE_DIS-.patch
  0012-uboot-fs-btrfs-Use-LZO_LEN-to-repla.patch
  0013-uboot-fs-btrfs-Fix-LZO-false-decomp.patch
- Follow upstream commits f7c6ee7f and be1b6c32 to unify 
  zynq/zynqmp configs:
  * Update zynq configs to use generic config + device tree for
    u-boot-avnetultra96rev1 and u-boot-xilinxzynqmpzcu102rev10
  * Use upstream u-boot-xilinxzynqmpvirt instead of downstream
    u-boot-xilinxzynqmpgeneric
- Switch to http URLs, ftp is obsolete
- Update to v2020.04:
  * Platfrom fixes: Amlogic, Atmel, fsl, iMX, Marvell, Mediatek,
    rockchip, RPi, samsung, socfpga, sunxi, Tegra, TI
  * EFI fixes
  * I2C fixes
  * GPIO fixes
  * MMC fixes
  * SPI fixes
  * USB fixes
  * Filesystem fixes
Patch queue updated from git://github.com/openSUSE/u-boot.git tumbleweed-2020.04
* Patches dropped:
  0010-ARM-tegra-Add-NVIDIA-Jetson-Nano-De.patch
  0011-net-Add-support-for-Broadcom-GENETv.patch
  0012-rpi4-Update-memory-map-to-accommoda.patch
  0013-rpi4-Enable-GENET-Ethernet-controll.patch
  0014-Kconfig-add-btrfs-to-distro-boot.patch
  0015-configs-Re-sync-with-CONFIG_DISTRO_.patch
  0016-configs-am335x_evm-disable-BTRFS.patch
  0017-net-phy-Fix-overlong-PHY-timeout.patch
  0018-net-bcmgenet-Don-t-set-ID_MODE_DIS-.patch
  0019-uboot-fs-btrfs-Use-LZO_LEN-to-repla.patch
  0020-uboot-fs-btrfs-Fix-LZO-false-decomp.patch
* Patches added:
  0010-Kconfig-add-btrfs-to-distro-boot.patch
  0011-configs-Re-sync-with-CONFIG_DISTRO_.patch
  0012-configs-am335x_evm-disable-BTRFS.patch
  0013-net-bcmgenet-Don-t-set-ID_MODE_DIS-.patch
  0014-uboot-fs-btrfs-Use-LZO_LEN-to-repla.patch
  0015-uboot-fs-btrfs-Fix-LZO-false-decomp.patch

OBS-URL: https://build.opensuse.org/request/show/795564
OBS-URL: https://build.opensuse.org/package/show/hardware:boot/u-boot?expand=0&rev=96
2020-04-20 09:32:05 +00:00

125 lines
3.6 KiB
Diff

From 82ad3674e71029334b519ff8c2bc077df82c2243 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Thu, 19 Mar 2020 20:30:06 +0800
Subject: [PATCH] uboot: fs/btrfs: Fix LZO false decompression error caused by
pending zero
[BUG]
For certain btrfs files with compressed file extent, uboot will fail to
load it:
btrfs_read_extent_reg: disk_bytenr=14229504 disk_len=73728 offset=0 nr_bytes=131
072
decompress_lzo: tot_len=70770
decompress_lzo: in_len=1389
decompress_lzo: in_len=2400
decompress_lzo: in_len=3002
decompress_lzo: in_len=1379
decompress_lzo: in_len=88539136
decompress_lzo: header error, in_len=88539136 clen=65534 tot_len=62580
NOTE: except the last line, all other lines are debug output.
[CAUSE]
Btrfs lzo compression uses its own format to record compressed size
(segmant header, LE32).
However to make decompression easier, we never put such segment header
across page boundary.
In above case, the xxd dump of the lzo compressed data looks like this:
00001fe0: 4cdc 02fc 0bfd 02c0 dc02 0d13 0100 0001 L...............
00001ff0: 0000 0008 0300 0000 0000 0011 0000|0000 ................
00002000: 4705 0000 0001 cc02 0000 0000 0000 1e01 G...............
'|' is the "expected" segment header start position.
But in that page, there are only 2 bytes left, can't contain the 4 bytes
segment header.
So btrfs compression will skip that 2 bytes, put the segment header in
next page directly.
Uboot doesn't have such check, and read the header with 2 bytes offset,
result 0x05470000 (88539136), other than the expected result
0x00000547 (1351), resulting above error.
[FIX]
Follow the btrfs-progs restore implementation, by introducing tot_in to
record total processed bytes (including headers), and do proper page
boundary skip to fix it.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
---
fs/btrfs/compression.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 4ef44ce114..2a6ac8bb10 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -9,6 +9,7 @@
#include <malloc.h>
#include <linux/lzo.h>
#include <linux/zstd.h>
+#include <linux/compat.h>
#include <u-boot/zlib.h>
#include <asm/unaligned.h>
@@ -17,6 +18,7 @@
static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
{
u32 tot_len, in_len, res;
+ u32 tot_in = 0;
size_t out_len;
int ret;
@@ -27,6 +29,7 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
cbuf += LZO_LEN;
clen -= LZO_LEN;
tot_len -= LZO_LEN;
+ tot_in += LZO_LEN;
if (tot_len == 0 && dlen)
return -1;
@@ -36,6 +39,9 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
res = 0;
while (tot_len > LZO_LEN) {
+ size_t mod_page;
+ size_t rem_page;
+
in_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
cbuf += LZO_LEN;
clen -= LZO_LEN;
@@ -44,6 +50,7 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
return -1;
tot_len -= (LZO_LEN + in_len);
+ tot_in += (LZO_LEN + in_len);
out_len = dlen;
ret = lzo1x_decompress_safe(cbuf, in_len, dbuf, &out_len);
@@ -56,6 +63,19 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
dlen -= out_len;
res += out_len;
+
+ /*
+ * If the 4 bytes header does not fit to the rest of the page we
+ * have to move to next one, or we read some garbage.
+ */
+ mod_page = tot_in % PAGE_SIZE;
+ rem_page = PAGE_SIZE - mod_page;
+ if (rem_page < LZO_LEN) {
+ cbuf += rem_page;
+ tot_in += rem_page;
+ clen -= rem_page;
+ tot_len -= rem_page;
+ }
}
return res;