aboutsummaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/compression.c42
-rw-r--r--fs/btrfs/super.c8
2 files changed, 39 insertions, 11 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 346875d45a..b1884fc15e 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -9,39 +9,47 @@
#include <malloc.h>
#include <linux/lzo.h>
#include <linux/zstd.h>
+#include <linux/compat.h>
#include <u-boot/zlib.h>
#include <asm/unaligned.h>
+/* Header for each segment, LE32, recording the compressed size */
+#define LZO_LEN 4
static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
{
- u32 tot_len, in_len, res;
+ u32 tot_len, tot_in, in_len, res;
size_t out_len;
int ret;
- if (clen < 4)
+ if (clen < LZO_LEN)
return -1;
tot_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
- cbuf += 4;
- clen -= 4;
- tot_len -= 4;
+ tot_in = 0;
+ cbuf += LZO_LEN;
+ clen -= LZO_LEN;
+ tot_len -= LZO_LEN;
+ tot_in += LZO_LEN;
if (tot_len == 0 && dlen)
return -1;
- if (tot_len < 4)
+ if (tot_len < LZO_LEN)
return -1;
res = 0;
- while (tot_len > 4) {
+ while (tot_len > LZO_LEN) {
+ u32 rem_page;
+
in_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
- cbuf += 4;
- clen -= 4;
+ cbuf += LZO_LEN;
+ clen -= LZO_LEN;
- if (in_len > clen || tot_len < 4 + in_len)
+ if (in_len > clen || tot_len < LZO_LEN + in_len)
return -1;
- tot_len -= 4 + in_len;
+ 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);
@@ -54,6 +62,18 @@ 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.
+ */
+ rem_page = PAGE_SIZE - (tot_in % PAGE_SIZE);
+ if (rem_page < LZO_LEN) {
+ cbuf += rem_page;
+ tot_in += rem_page;
+ clen -= rem_page;
+ tot_len -= rem_page;
+ }
}
return res;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 2dc4a6fcd7..b693a073fc 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -7,6 +7,7 @@
#include "btrfs.h"
#include <memalign.h>
+#include <linux/compat.h>
#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN \
| BTRFS_HEADER_FLAG_RELOC \
@@ -232,6 +233,13 @@ int btrfs_read_superblock(void)
return -1;
}
+ if (sb->sectorsize != PAGE_SIZE) {
+ printf(
+ "%s: Unsupported sector size (%u), only supports %u as sector size\n",
+ __func__, sb->sectorsize, PAGE_SIZE);
+ return -1;
+ }
+
if (btrfs_info.sb.num_devices != 1) {
printf("%s: Unsupported number of devices (%lli). This driver "
"only supports filesystem on one device.\n", __func__,