Commit ce6ef5ab authored by David Sterba's avatar David Sterba
Browse files

btrfs: add little-endian optimized key helpers



The CPU and on-disk keys are mapped to two different structures because
of the endianness. There's an intermediate buffer used to do the
conversion, but this is not necessary when CPU and on-disk endianness
match.

Add optimized versions of helpers that take disk_key and use the buffer
directly for CPU keys or drop the intermediate buffer and conversion.

This saves a lot of stack space accross many functions and removes about
6K of generated binary code:

   text    data     bss     dec     hex filename
1090439   17468   14912 1122819  112203 pre/btrfs.ko
1084613   17456   14912 1116981  110b35 post/btrfs.ko

Delta: -5826

Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 5958253c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -1501,6 +1501,22 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
	return 0;
}

#ifdef __LITTLE_ENDIAN

/*
 * Compare two keys, on little-endian the disk order is same as CPU order and
 * we can avoid the conversion.
 */
static int comp_keys(const struct btrfs_disk_key *disk_key,
		     const struct btrfs_key *k2)
{
	const struct btrfs_key *k1 = (const struct btrfs_key *)disk_key;

	return btrfs_comp_cpu_keys(k1, k2);
}

#else

/*
 * compare two keys in a memcmp fashion
 */
@@ -1513,6 +1529,7 @@ static int comp_keys(const struct btrfs_disk_key *disk,

	return btrfs_comp_cpu_keys(&k1, k2);
}
#endif

/*
 * same as comp_keys only with two btrfs_key's
+48 −0
Original line number Diff line number Diff line
@@ -1895,6 +1895,52 @@ BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key,
BTRFS_SETGET_STACK_FUNCS(disk_key_offset, struct btrfs_disk_key, offset, 64);
BTRFS_SETGET_STACK_FUNCS(disk_key_type, struct btrfs_disk_key, type, 8);

#ifdef __LITTLE_ENDIAN

/*
 * Optimized helpers for little-endian architectures where CPU and on-disk
 * structures have the same endianness and we can skip conversions.
 */

static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu_key,
					 const struct btrfs_disk_key *disk_key)
{
	memcpy(cpu_key, disk_key, sizeof(struct btrfs_key));
}

static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk_key,
					 const struct btrfs_key *cpu_key)
{
	memcpy(disk_key, cpu_key, sizeof(struct btrfs_key));
}

static inline void btrfs_node_key_to_cpu(const struct extent_buffer *eb,
					 struct btrfs_key *cpu_key, int nr)
{
	struct btrfs_disk_key *disk_key = (struct btrfs_disk_key *)cpu_key;

	btrfs_node_key(eb, disk_key, nr);
}

static inline void btrfs_item_key_to_cpu(const struct extent_buffer *eb,
					 struct btrfs_key *cpu_key, int nr)
{
	struct btrfs_disk_key *disk_key = (struct btrfs_disk_key *)cpu_key;

	btrfs_item_key(eb, disk_key, nr);
}

static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb,
					     const struct btrfs_dir_item *item,
					     struct btrfs_key *cpu_key)
{
	struct btrfs_disk_key *disk_key = (struct btrfs_disk_key *)cpu_key;

	btrfs_dir_item_key(eb, item, disk_key);
}

#else

static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
					 const struct btrfs_disk_key *disk)
{
@@ -1936,6 +1982,8 @@ static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb,
	btrfs_disk_key_to_cpu(key, &disk_key);
}

#endif

/* struct btrfs_header */
BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64);
BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,