diff options
author | Yan, Zheng <zheng.yan@oracle.com> | 2009-09-24 09:17:31 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-09-24 09:17:31 -0400 |
commit | a57195214358b75807a74bad96a8601a36262af7 (patch) | |
tree | e288410ecfab5f15097bb66f06a5dd6bf99bca08 /fs/btrfs/ctree.c | |
parent | 11ef160fda9c150cd75db77194bcc66839709662 (diff) | |
download | op-kernel-dev-a57195214358b75807a74bad96a8601a36262af7.zip op-kernel-dev-a57195214358b75807a74bad96a8601a36262af7.tar.gz |
Btrfs: 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
check to btrfs_link and btrfs_rename.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 3fdcc05..ec96f3a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2853,6 +2853,12 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, 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); |