Skip to content

Commit 4c46979

Browse files
fdmananakdave
authored andcommitted
btrfs: shrink the size of struct btrfs_delayed_item
Currently struct btrfs_delayed_item has a base size of 96 bytes, but its size can be decreased by doing the following 2 tweaks: 1) Change data_len from u32 to u16. Our maximum possible leaf size is 64K, so the data_len can never be larger than that, and in fact it is always much smaller than that. The max length for a dentry's name is ensured at the VFS level (PATH_MAX, 4096 bytes) and in struct btrfs_inode_ref and btrfs_dir_item we use a u16 to store the name's length; 2) Change 'ins_or_del' to a 1 bit enum, which is all we need since it can only have 2 values. After this there's also no longer the need to BUG_ON() before using 'ins_or_del' in several places. Also rename the field from 'ins_or_del' to 'type', which is more clear. These two tweaks decrease the size of struct btrfs_delayed_item from 96 bytes down to 88 bytes. A previous patch already reduced the size of this structure by 16 bytes, but an upcoming change will increase its size by 16 bytes (adding a struct list_head element). Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 4cbf37f commit 4c46979

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

fs/btrfs/delayed-inode.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,16 @@ static inline void btrfs_release_prepared_delayed_node(
302302
__btrfs_release_delayed_node(node, 1);
303303
}
304304

305-
static struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len,
306-
struct btrfs_delayed_node *node)
305+
static struct btrfs_delayed_item *btrfs_alloc_delayed_item(u16 data_len,
306+
struct btrfs_delayed_node *node,
307+
enum btrfs_delayed_item_type type)
307308
{
308309
struct btrfs_delayed_item *item;
310+
309311
item = kmalloc(sizeof(*item) + data_len, GFP_NOFS);
310312
if (item) {
311313
item->data_len = data_len;
312-
item->ins_or_del = 0;
314+
item->type = type;
313315
item->bytes_reserved = 0;
314316
item->delayed_node = node;
315317
RB_CLEAR_NODE(&item->rb_node);
@@ -356,12 +358,11 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
356358
struct btrfs_delayed_item *item;
357359
bool leftmost = true;
358360

359-
if (ins->ins_or_del == BTRFS_DELAYED_INSERTION_ITEM)
361+
if (ins->type == BTRFS_DELAYED_INSERTION_ITEM)
360362
root = &delayed_node->ins_root;
361-
else if (ins->ins_or_del == BTRFS_DELAYED_DELETION_ITEM)
362-
root = &delayed_node->del_root;
363363
else
364-
BUG();
364+
root = &delayed_node->del_root;
365+
365366
p = &root->rb_root.rb_node;
366367
node = &ins->rb_node;
367368

@@ -383,7 +384,7 @@ static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
383384
rb_link_node(node, parent_node, p);
384385
rb_insert_color_cached(node, root, leftmost);
385386

386-
if (ins->ins_or_del == BTRFS_DELAYED_INSERTION_ITEM &&
387+
if (ins->type == BTRFS_DELAYED_INSERTION_ITEM &&
387388
ins->index >= delayed_node->index_cnt)
388389
delayed_node->index_cnt = ins->index + 1;
389390

@@ -414,10 +415,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
414415
delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root;
415416

416417
BUG_ON(!delayed_root);
417-
BUG_ON(delayed_item->ins_or_del != BTRFS_DELAYED_DELETION_ITEM &&
418-
delayed_item->ins_or_del != BTRFS_DELAYED_INSERTION_ITEM);
419418

420-
if (delayed_item->ins_or_del == BTRFS_DELAYED_INSERTION_ITEM)
419+
if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM)
421420
root = &delayed_item->delayed_node->ins_root;
422421
else
423422
root = &delayed_item->delayed_node->del_root;
@@ -509,7 +508,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
509508
* for the number of leaves that will be used, based on the delayed
510509
* node's index_items_size field.
511510
*/
512-
if (item->ins_or_del == BTRFS_DELAYED_DELETION_ITEM)
511+
if (item->type == BTRFS_DELAYED_DELETION_ITEM)
513512
item->bytes_reserved = num_bytes;
514513
}
515514

@@ -646,6 +645,7 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
646645
const int max_size = BTRFS_LEAF_DATA_SIZE(fs_info);
647646
struct btrfs_item_batch batch;
648647
struct btrfs_key first_key;
648+
const u32 first_data_size = first_item->data_len;
649649
int total_size;
650650
char *ins_data = NULL;
651651
int ret;
@@ -674,9 +674,9 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
674674
ASSERT(first_item->bytes_reserved == 0);
675675

676676
list_add_tail(&first_item->tree_list, &item_list);
677-
batch.total_data_size = first_item->data_len;
677+
batch.total_data_size = first_data_size;
678678
batch.nr = 1;
679-
total_size = first_item->data_len + sizeof(struct btrfs_item);
679+
total_size = first_data_size + sizeof(struct btrfs_item);
680680
curr = first_item;
681681

682682
while (true) {
@@ -711,7 +711,7 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
711711
first_key.type = BTRFS_DIR_INDEX_KEY;
712712
first_key.offset = first_item->index;
713713
batch.keys = &first_key;
714-
batch.data_sizes = &first_item->data_len;
714+
batch.data_sizes = &first_data_size;
715715
} else {
716716
struct btrfs_key *ins_keys;
717717
u32 *ins_sizes;
@@ -1427,14 +1427,14 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
14271427
return PTR_ERR(delayed_node);
14281428

14291429
delayed_item = btrfs_alloc_delayed_item(sizeof(*dir_item) + name_len,
1430-
delayed_node);
1430+
delayed_node,
1431+
BTRFS_DELAYED_INSERTION_ITEM);
14311432
if (!delayed_item) {
14321433
ret = -ENOMEM;
14331434
goto release_node;
14341435
}
14351436

14361437
delayed_item->index = index;
1437-
delayed_item->ins_or_del = BTRFS_DELAYED_INSERTION_ITEM;
14381438

14391439
dir_item = (struct btrfs_dir_item *)delayed_item->data;
14401440
dir_item->location = *disk_key;
@@ -1566,14 +1566,13 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
15661566
if (!ret)
15671567
goto end;
15681568

1569-
item = btrfs_alloc_delayed_item(0, node);
1569+
item = btrfs_alloc_delayed_item(0, node, BTRFS_DELAYED_DELETION_ITEM);
15701570
if (!item) {
15711571
ret = -ENOMEM;
15721572
goto end;
15731573
}
15741574

15751575
item->index = index;
1576-
item->ins_or_del = BTRFS_DELAYED_DELETION_ITEM;
15771576

15781577
ret = btrfs_delayed_item_reserve_metadata(trans, item);
15791578
/*

fs/btrfs/delayed-inode.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
#include <linux/refcount.h>
1717
#include "ctree.h"
1818

19-
/* types of the delayed item */
20-
#define BTRFS_DELAYED_INSERTION_ITEM 1
21-
#define BTRFS_DELAYED_DELETION_ITEM 2
19+
enum btrfs_delayed_item_type {
20+
BTRFS_DELAYED_INSERTION_ITEM,
21+
BTRFS_DELAYED_DELETION_ITEM
22+
};
2223

2324
struct btrfs_delayed_root {
2425
spinlock_t lock;
@@ -80,8 +81,9 @@ struct btrfs_delayed_item {
8081
u64 bytes_reserved;
8182
struct btrfs_delayed_node *delayed_node;
8283
refcount_t refs;
83-
int ins_or_del;
84-
u32 data_len;
84+
enum btrfs_delayed_item_type type:8;
85+
/* The maximum leaf size is 64K, so u16 is more than enough. */
86+
u16 data_len;
8587
char data[];
8688
};
8789

0 commit comments

Comments
 (0)