aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2022-07-26 13:22:10 +0800
committerTom Rini <trini@konsulko.com>2022-08-05 13:25:48 -0400
commit33dcce3587dc791bb260d0750813a83530530107 (patch)
tree0d25e350864fe5222f8a15fb2b67940a4534348f
parentc7f18bdd457769e7d8384d422705faeb8163ec4d (diff)
downloadu-boot-33dcce3587dc791bb260d0750813a83530530107.zip
u-boot-33dcce3587dc791bb260d0750813a83530530107.tar.gz
u-boot-33dcce3587dc791bb260d0750813a83530530107.tar.bz2
fs: btrfs: fix a bug which no data get read if the length is not 0
[BUG] When testing with unaligned read, if a specific length is passed in, btrfs driver will read out nothing: => load host 0 $kernel_addr_r 5k_file 0x1000 0 0 bytes read in 0 ms But if no length is passed in, it works fine, even if we pass a non-zero length: => load host 0 $kernel_addr_r 5k_file 0 0x1000 1024 bytes read in 0 ms [CAUSE] In btrfs_read() if we have a larger size than our file, we will try to truncate it using the file size. However the real file size is not initialized if @len is not zero, thus we always truncate our length to 0, and cause the problem. [FIX] Fix it by just always do the file size check. In fact btrfs_size() always follow soft link, thus it will return the real file size correctly. Signed-off-by: Qu Wenruo <wqu@suse.com>
-rw-r--r--fs/btrfs/btrfs.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c
index 4cdbbbe..309cd59 100644
--- a/fs/btrfs/btrfs.c
+++ b/fs/btrfs/btrfs.c
@@ -246,16 +246,17 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len,
return -EINVAL;
}
- if (!len) {
- ret = btrfs_size(file, &real_size);
- if (ret < 0) {
- error("Failed to get inode size: %s", file);
- return ret;
- }
- len = real_size;
+ ret = btrfs_size(file, &real_size);
+ if (ret < 0) {
+ error("Failed to get inode size: %s", file);
+ return ret;
}
- if (len > real_size - offset)
+ /*
+ * If the length is 0 (meaning read the whole file) or the range is
+ * beyond file size, truncate it to the end of the file.
+ */
+ if (!len || len > real_size - offset)
len = real_size - offset;
ret = btrfs_file_read(root, ino, offset, len, buf);