check size of inode backref before adding hardlink
PATCH 1/1 check size of inode backref before adding hardlink
For every hardlink in btrfs, there is a corresponding inode back reference. All inode back references for hardlinks in a given directory are stored in single b-tree item. The size of b-tree item is limited by the size of b-tree leaf, so we can only create limited number of hardlinks to a given file in a directory.
The original code lacks of the check, it oops if the number of hardlinks goes over the limit. This patch fixes the issue by adding the check to btrfs_link and btrfs_rename.
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/ctree.c +6 -0
@@ -2853,6 +2853,12 @@ static noinline int split_leaf(struct btint split;int num_doubles =0 ; + l = path->nodes[0 ]; + slot = path->slots[0 ]; +if (extend && data_size +btrfs_item_size_nr (l, slot) + +sizeof (struct btrfs_item ) >BTRFS_LEAF_DATA_SIZE (root)) +return -EOVERFLOW ; +/* first try to make some room by pushing left and right */ if (data_size && ins_key->type !=BTRFS_DIR_ITEM_KEY ) { wret =push_leaf_right (trans, root, path, data_size,0 );
fs/btrfs/inode.c +33 -35
116 lines not on this page · raw message
fs/btrfs/inode-item.c +2 -0
@@ -149,6 +149,8 @@ int btrfs_insert_inode_ref(struct btrfs_ ptr = (unsigned long )(ref +1 ); ret =0 ; }else if (ret <0 ) { +if (ret == -EOVERFLOW ) + ret = -EMLINK ; goto out; }else { ref = btrfs_item_ptr(path->nodes[0], path->slots[0],