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>
lime2-spi
Marek Vasut 6 years ago committed by Tom Rini
parent 30b3241368
commit c9795396ed
  1. 24
      fs/btrfs/ctree.c
  2. 3
      fs/btrfs/extent-io.c
  3. 3
      fs/btrfs/super.c

@ -7,6 +7,7 @@
#include "btrfs.h" #include "btrfs.h"
#include <malloc.h> #include <malloc.h>
#include <memalign.h>
int btrfs_comp_keys(struct btrfs_key *a, struct btrfs_key *b) 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) static int read_tree_node(u64 physical, union btrfs_tree_node **buf)
{ {
struct btrfs_header hdr; ALLOC_CACHE_ALIGN_BUFFER(struct btrfs_header, hdr,
unsigned long size, offset = sizeof(hdr); sizeof(struct btrfs_header));
unsigned long size, offset = sizeof(*hdr);
union btrfs_tree_node *res; union btrfs_tree_node *res;
u32 i; u32 i;
if (!btrfs_devread(physical, sizeof(hdr), &hdr)) if (!btrfs_devread(physical, sizeof(*hdr), hdr))
return -1; return -1;
btrfs_header_to_cpu(&hdr); btrfs_header_to_cpu(hdr);
if (hdr.level) if (hdr->level)
size = sizeof(struct btrfs_node) size = sizeof(struct btrfs_node)
+ hdr.nritems * sizeof(struct btrfs_key_ptr); + hdr->nritems * sizeof(struct btrfs_key_ptr);
else else
size = btrfs_info.sb.nodesize; size = btrfs_info.sb.nodesize;
res = malloc(size); res = malloc_cache_aligned(size);
if (!res) { if (!res) {
debug("%s: malloc failed\n", __func__); debug("%s: malloc failed\n", __func__);
return -1; return -1;
@ -133,12 +135,12 @@ static int read_tree_node(u64 physical, union btrfs_tree_node **buf)
return -1; return -1;
} }
res->header = hdr; memcpy(&res->header, hdr, sizeof(*hdr));
if (hdr.level) if (hdr->level)
for (i = 0; i < hdr.nritems; ++i) for (i = 0; i < hdr->nritems; ++i)
btrfs_key_ptr_to_cpu(&res->node.ptrs[i]); btrfs_key_ptr_to_cpu(&res->node.ptrs[i]);
else else
for (i = 0; i < hdr.nritems; ++i) for (i = 0; i < hdr->nritems; ++i)
btrfs_item_to_cpu(&res->leaf.items[i]); btrfs_item_to_cpu(&res->leaf.items[i]);
*buf = res; *buf = res;

@ -7,6 +7,7 @@
#include "btrfs.h" #include "btrfs.h"
#include <malloc.h> #include <malloc.h>
#include <memalign.h>
u64 btrfs_read_extent_inline(struct btrfs_path *path, u64 btrfs_read_extent_inline(struct btrfs_path *path,
struct btrfs_file_extent_item *extent, u64 offset, struct btrfs_file_extent_item *extent, u64 offset,
@ -89,7 +90,7 @@ u64 btrfs_read_extent_reg(struct btrfs_path *path,
return size; return size;
} }
cbuf = malloc(dlen > size ? clen + dlen : clen); cbuf = malloc_cache_aligned(dlen > size ? clen + dlen : clen);
if (!cbuf) if (!cbuf)
return -1ULL; return -1ULL;

@ -6,6 +6,7 @@
*/ */
#include "btrfs.h" #include "btrfs.h"
#include <memalign.h>
#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN \ #define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN \
| BTRFS_HEADER_FLAG_RELOC \ | BTRFS_HEADER_FLAG_RELOC \
@ -179,7 +180,7 @@ int btrfs_read_superblock(void)
0x4000000000ull, 0x4000000000ull,
0x4000000000000ull 0x4000000000000ull
}; };
char raw_sb[BTRFS_SUPER_INFO_SIZE]; ALLOC_CACHE_ALIGN_BUFFER(char, raw_sb, BTRFS_SUPER_INFO_SIZE);
struct btrfs_super_block *sb = (struct btrfs_super_block *) raw_sb; struct btrfs_super_block *sb = (struct btrfs_super_block *) raw_sb;
u64 dev_total_bytes; u64 dev_total_bytes;
int i; int i;

Loading…
Cancel
Save