Commit graph

24 commits

Author SHA1 Message Date
Dan Carpenter
08404fa208 btrfs: fix some error checking for btrfs_decompress()
The btrfs_decompress() function mostly (u32)-1 on error but it can
also return -EPERM or other kernel error codes from zstd_decompress().
The "ret" variable is an int, so we could just check for negatives.

Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Qu Wenruo <wqu@suse.com>
2023-08-08 17:41:52 -04:00
Dominique Martinet
b1d3013d02 btrfs: fix offset when reading compressed extents
btrfs_read_extent_reg correctly computed the extent offset in the
BTRFS_COMPRESS_NONE case, but did not account for the 'offset - key.offset'
part correctly in the compressed case, making the function read
incorrect data.

In the case I examined, the last 4k of a file was corrupted and
contained data from a few blocks prior, e.g. reading a 10k file with a
single extent:
btrfs_file_read()
 -> btrfs_read_extent_reg
    (aligned part loop, until 8k)
 -> read_and_truncate_page
   -> btrfs_read_extent_reg
      (re-reads the last extent from 8k to the end,
      incorrectly reading the first 2k of data)

This can be reproduced as follow:
$ truncate -s 200M btr
$ mount btr -o compress /mnt
$ pat() { dd if=/dev/zero bs=1M count=$1 iflag=count_bytes status=none | tr '\0' "\\$2"; }
$ { pat 4K 1; pat 4K 2; pat 2K 3; }  > /mnt/file
$ sync
$ filefrag -v /mnt/file
File size of /mnt/file is 10240 (3 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       2:       3328..      3330:      3:             last,encoded,eof
$ umount /mnt

Then in u-boot:
=> load scsi 0 2000000 file
10240 bytes read in 3 ms (3.3 MiB/s)
=> md 2001ff0
02001ff0: 02020202 02020202 02020202 02020202  ................
02002000: 01010101 01010101 01010101 01010101  ................
02002010: 01010101 01010101 01010101 01010101  ................

(02002000 onwards should contain '03' pattern but went back to 01,
start of the extent)

After patch, data is read properly:
=> md 2001ff0
02001ff0: 02020202 02020202 02020202 02020202  ................
02002000: 03030303 03030303 03030303 03030303  ................
02002010: 03030303 03030303 03030303 03030303  ................

Note that the code previously (before commit e3427184f3 ("fs: btrfs:
Implement btrfs_file_read()")) did not split that read in two, so
this is a regression even if the previous code might not have been
handling offsets correctly either (something that booted now fails to
boot)

Fixes: a26a6bedaf ("fs: btrfs: Introduce btrfs_read_extent_inline() and btrfs_read_extent_reg()")
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
2023-05-08 09:23:53 -04:00
Marek Behún
61143f741e treewide: Fix Marek's name and change my e-mail address
Fix diacritics in some instances of my name and change my e-mail address
to kabel@kernel.org.

Add corresponding .mailmap entries.

Signed-off-by: Marek Behún <kabel@kernel.org>
Reviewed-by: Stefan Roese <sr@denx.de>
2022-07-21 10:14:04 +02:00
Heinrich Schuchardt
89ab1e2817 btrfs: simplify lookup_data_extent()
After returning if ret <= 0 we know that ret > 0. No need to check it.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Anand Jain <anand.jain>
2022-06-06 17:47:17 -04:00
Qu Wenruo
7c075433fe fs/btrfs: fix a bug that U-boot fs btrfs implementation doesn't handle NO_HOLE feature correctly
[BUG]
When passing a btrfs with NO_HOLE feature to U-boot, and if one file
contains holes, then the hash of the file is not correct in U-boot:

 # mkfs.btrfs -f test.img	# Since v5.15, mkfs defaults to NO_HOLES
 # mount test.img /mnt/btrfs
 # xfs_io -f -c "pwrite 0 4k" -c "pwrite 8k 4k" /mnt/btrfs/file
 # md5sum /mnt/btrfs/file
 277f3840b275c74d01e979ea9d75ac19  /mnt/btrfs/file
 # umount /mnt/btrfs
 # ./u-boot
 => host bind 0 /home/adam/test.img
 => ls host 0
 <   >      12288  Mon Dec 27 05:35:23 2021  file
 => load host 0 0x1000000 file
 12288 bytes read in 0 ms
 => md5sum 0x1000000 0x3000
 md5 for 01000000 ... 01002fff ==> 855ffdbe4d0ccc5acab92e1b5330e4c1

The md5sum doesn't match at all.

[CAUSE]
In U-boot btrfs implementation, the function btrfs_read_file() has the
following iteration for file extent iteration:

	/* Read the aligned part */
	while (cur < aligned_end) {
		ret = lookup_data_extent(root, &path, ino, cur, &next_offset);
		if (ret < 0)
			goto out;
		if (ret > 0) {
			/* No next, direct exit */
			if (!next_offset) {
				ret = 0;
				goto out;
			}
		}
		/* Read file extent */

But for NO_HOLES features, hole extents will not have any extent item
for it.
Thus if @cur is at a hole, lookup_data_extent() will just return >0, and
update @next_offset.

But we still believe there is some data to read for @cur for ret > 0
case, causing we read extent data from the next file extent.

This means, what we do for above NO_HOLES btrfs is:
- Read 4K data from disk to file offset [0, 4K)
  So far the data is still correct

- Read 4K data from disk to file offset [4K, 8K)
  We didn't skip the 4K hole, but read the data at file offset [8K, 12K)
  into file offset [4K, 8K).

  This causes the checksum mismatch.

[FIX]
Add extra check to skip to the next non-hole range after
lookup_data_extent().

Signed-off-by: Qu Wenruo <wqu@suse.com>
2022-01-18 08:31:02 -05:00
Qu Wenruo
dae9aeda45 fs: btrfs: fix the false alert of decompression failure
There are some cases where decompressed sectors can have padding zeros.

In kernel code, we have lines to address such situation:

        /*
         * btrfs_getblock is doing a zero on the tail of the page too,
         * but this will cover anything missing from the decompressed
         * data.
         */
        if (bytes < destlen)
                memset(kaddr+bytes, 0, destlen-bytes);
        kunmap_local(kaddr);

But not in U-boot code, thus we have some reports of U-boot failed to
read compressed files in btrfs.

Fix it by doing the same thing of the kernel, for both inline and
regular compressed extents.

Reported-by: Matwey Kornilov <matwey.kornilov@gmail.com>
Link: https://bugzilla.suse.com/show_bug.cgi?id=1183717
Fixes: a26a6bedaf ("fs: btrfs: Introduce btrfs_read_extent_inline() and btrfs_read_extent_reg()")
Signed-off-by: Qu Wenruo <wqu@suse.com>
2021-04-27 08:05:30 -04:00
Qu Wenruo
9b5546c37a fs: btrfs: inode: handle uninitialized type before returning it
In btrfs_lookup_path() the local variable @type should always be updated
after we hit any file/dir.

But if @filename is NULL from the very beginning, then we don't
initialize it and return it directly.

To prevent such problem from happening, we initialize @type to
BTRFS_FT_UNKNOWN.
For normal execution route, it will get updated for each filename we
resolved.
Buf if we didn't find any path, we check if the type is still FT_UNKNOWN
and ret == 0. If true we know there is something wrong, just return
-EUCLEAN to inform the caller.

Reported-by: Coverity CID 312958
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-11-19 09:45:49 -05:00
Qu Wenruo
5573c20fad fs: btrfs: Cleanup the old implementation
This cleans up the now unneeded code from the old btrfs implementation.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 21:00:36 -04:00
Qu Wenruo
e3427184f3 fs: btrfs: Implement btrfs_file_read()
This version of btrfs_file_read() has the following new features:
- Tries all mirrors
- More handling on unaligned size
- Better compressed extent handling
  The old implementation doesn't handle compressed extent with offset
  properly: we need to read out the whole compressed extent, then
  decompress the whole extent, and only then copy the requested part.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 21:00:36 -04:00
Qu Wenruo
01347f64d5 fs: btrfs: Introduce lookup_data_extent() for later use
This implements lookup_data_extent() function for the incoming
new implementation of btrfs_file_read().

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
a26a6bedaf fs: btrfs: Introduce btrfs_read_extent_inline() and btrfs_read_extent_reg()
These two functions are used to do sector aligned read, which will be
later used to implement btrfs_file_read().

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
0cc8fc65c1 fs: btrfs: Rename btrfs_file_read() and its callees to avoid name conflicts
Rename btrfs_file_read() and its callees to avoid name conflicts with
the incoming new code.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
c921aa20c3 fs: btrfs: Implement btrfs_lookup_path()
This is the extent buffer based path lookup routine.

To implement this, btrfs_lookup_dir_item() is crossported from
btrfs-progs, and implements btrfs_lookup_path() from scratch.

Unlike the existing __btrfs_lookup_path(), since btrfs_read_fs_root()
will check whether a root is a orphan at read time, there is no need to
check root backref, this makes the code a little easier to read.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
5bdcb37495 fs: btrfs: inode: Allow next_length() to return value > BTRFS_NAME_LEN
All existing next_length() caller handles return value > BTRFS_NAME_LEN,
so there is no need to do BTRFS_NAME_LEN check in next_length().

But still, we want to exit early if we're beyond BTRFS_NAME_LEN, so this
patch makes next_length() exit as soon as we're beyond BTRFS_NAME_LEN.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
92bc179c5f fs: btrfs: Use btrfs_readlink() to implement __btrfs_readlink()
The existing __btrfs_readlink() can be easily re-implemented using the
extent buffer based btrfs_readlink().

This is the first step to re-implement U-Boot's btrfs code.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
cafffc50ad fs: btrfs: Rename path resolve related functions to avoid name conflicts
Since the old code is using __btrfs_path/__btrfs_root which is different
from the regular extent buffer based one, we add "__" prefix for the old
implementation to avoid name conflicts for the incoming crossport.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
207011b81e fs: btrfs: Rename btrfs_root to __btrfs_root
This is to avoid naming conflicts between extent buffer based
btrfs_root.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
33966de31f fs: btrfs: Rename struct btrfs_path to struct __btrfs_path
To avoid name conflicting between the extent buffer based btrfs_path
from btrfs-progs, rename struct btrfs_path to struct __btrfs_path.

Also rename btrfs_free_path() to __btrfs_free_path() to avoid conflicts.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
75b0817bab fs: btrfs: Crossport read_tree_block() from btrfs-progs
This is the one of the basic stone function for btrfs, which:
- Resolves the chunk mappings
- Reads data from disk
- Does various sanity check

With read_tree_block(), we can finally crossport needed btrfs btree
operations to U-Boot.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Qu Wenruo
3b4b40c0d6 fs: btrfs: Sync btrfs_btree.h from kernel
This version includes all needed on-disk format from kernel.

Only need to modify the include headers for U-Boot, everything else is
untouched.

Also, since U-Boot btrfs is using a different endian convert timing (at
tree block read time), it needs some forced type conversion before
proper crossport.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Marek Behún <marek.behun@nic.cz>
2020-09-07 20:57:27 -04:00
Tom Rini
83d290c56f SPDX: Convert all of our single license tags to Linux Kernel style
When U-Boot started using SPDX tags we were among the early adopters and
there weren't a lot of other examples to borrow from.  So we picked the
area of the file that usually had a full license text and replaced it
with an appropriate SPDX-License-Identifier: entry.  Since then, the
Linux Kernel has adopted SPDX tags and they place it as the very first
line in a file (except where shebangs are used, then it's second line)
and with slightly different comment styles than us.

In part due to community overlap, in part due to better tag visibility
and in part for other minor reasons, switch over to that style.

This commit changes all instances where we have a single declared
license in the tag as both the before and after are identical in tag
contents.  There's also a few places where I found we did not have a tag
and have introduced one.

Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07 09:34:12 -04:00
Marek Behún
733d963e3b fs: btrfs: Remove a foreign language note
I accidentaly left a foreign language note in the code from development.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
2017-10-16 09:42:51 -04:00
Marek Behún
ecab881c7f fs: btrfs: Fix usage of uninitialized variables
The variable res should be initialized to 0 in these functions,
because if the searched key is not found, the variable is used
uninitialized.

Reported-by: Coverity (CID: 167335)
Reported-by: Coverity (CID: 167336)
Reported-by: Coverity (CID: 167337)
Signed-off-by: Marek Behun <marek.behun@nic.cz>
2017-10-16 09:42:51 -04:00
Marek Behún
21a14facb1 fs: btrfs: Add single-device read-only BTRFS implementation
This adds the proper implementation for the BTRFS filesystem.
The implementation currently supports only read-only mode and
the filesystem can be only on a single device.

Checksums of data chunks is unimplemented.

Compression is implemented (ZLIB + LZO).

Signed-off-by: Marek Behun <marek.behun@nic.cz>

 create mode 100644 fs/btrfs/btrfs.h
 create mode 100644 fs/btrfs/chunk-map.c
 create mode 100644 fs/btrfs/compression.c
 create mode 100644 fs/btrfs/ctree.c
 create mode 100644 fs/btrfs/dev.c
 create mode 100644 fs/btrfs/dir-item.c
 create mode 100644 fs/btrfs/extent-io.c
 create mode 100644 fs/btrfs/hash.c
 create mode 100644 fs/btrfs/inode.c
 create mode 100644 fs/btrfs/root.c
 create mode 100644 fs/btrfs/subvolume.c
 create mode 100644 fs/btrfs/super.c
2017-10-02 21:52:17 -04:00