diff options
author | Marek Vasut <marex@denx.de> | 2018-09-22 04:13:35 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-09-30 13:00:37 -0400 |
commit | c9795396edd53ad29537037de8fd752662c676ad (patch) | |
tree | b4489e56e5c686c6ed87a1e302b0a90f56e3d165 /fs/btrfs/ctree.c | |
parent | 30b3241368aff899c56359f63214c164ed3fb3fb (diff) | |
download | u-boot-c9795396edd53ad29537037de8fd752662c676ad.tar.gz |
fs: btrfs: Fix cache alignment bugs
The btrfs implementation passes cache-unaligned buffers into the
block layer, which triggers cache alignment problems down in the
block device drivers. Align the buffers to prevent this.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marek Behun <marek.behun@nic.cz>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 4da36a9bc7..18b47d92fe 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -7,6 +7,7 @@ #include "btrfs.h" #include <malloc.h> +#include <memalign.h> int btrfs_comp_keys(struct btrfs_key *a, struct btrfs_key *b) { @@ -105,23 +106,24 @@ void btrfs_free_path(struct btrfs_path *p) static int read_tree_node(u64 physical, union btrfs_tree_node **buf) { - struct btrfs_header hdr; - unsigned long size, offset = sizeof(hdr); + ALLOC_CACHE_ALIGN_BUFFER(struct btrfs_header, hdr, + sizeof(struct btrfs_header)); + unsigned long size, offset = sizeof(*hdr); union btrfs_tree_node *res; u32 i; - if (!btrfs_devread(physical, sizeof(hdr), &hdr)) + if (!btrfs_devread(physical, sizeof(*hdr), hdr)) return -1; - btrfs_header_to_cpu(&hdr); + btrfs_header_to_cpu(hdr); - if (hdr.level) + if (hdr->level) size = sizeof(struct btrfs_node) - + hdr.nritems * sizeof(struct btrfs_key_ptr); + + hdr->nritems * sizeof(struct btrfs_key_ptr); else size = btrfs_info.sb.nodesize; - res = malloc(size); + res = malloc_cache_aligned(size); if (!res) { debug("%s: malloc failed\n", __func__); return -1; @@ -133,12 +135,12 @@ static int read_tree_node(u64 physical, union btrfs_tree_node **buf) return -1; } - res->header = hdr; - if (hdr.level) - for (i = 0; i < hdr.nritems; ++i) + memcpy(&res->header, hdr, sizeof(*hdr)); + if (hdr->level) + for (i = 0; i < hdr->nritems; ++i) btrfs_key_ptr_to_cpu(&res->node.ptrs[i]); else - for (i = 0; i < hdr.nritems; ++i) + for (i = 0; i < hdr->nritems; ++i) btrfs_item_to_cpu(&res->leaf.items[i]); *buf = res; |