Skip to contentSkip to conversation

check size of inode backref before adding hardlink

PATCH New Yan Zheng 1 participant 1 message Aug 5, 2009 Btrfs file system

lore
Share & tools
lore

Yan Zheng

author
#0 lore raw

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.

---

fs/btrfs/ctree.c +6 -0
diff -urp 1/fs/btrfs/ctree.c 2/fs/btrfs/ctree.c
@@ -2853,6 +2853,12 @@ static noinline int split_leaf(struct bt
 	int 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
diff -urp 1/fs/btrfs/inode-item.c 2/fs/btrfs/inode-item.c
@@ -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],