aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index e2fc6f0d0243..6b76fd967153 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1249,6 +1249,60 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1249 return ret; 1249 return ret;
1250} 1250}
1251 1251
1252int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
1253 *root, struct btrfs_path *path, u32 data_size)
1254{
1255 int ret = 0;
1256 int slot;
1257 int slot_orig;
1258 struct btrfs_leaf *leaf;
1259 struct buffer_head *leaf_buf;
1260 u32 nritems;
1261 unsigned int data_end;
1262 unsigned int old_data;
1263 unsigned int old_size;
1264 int i;
1265
1266 slot_orig = path->slots[0];
1267 leaf_buf = path->nodes[0];
1268 leaf = btrfs_buffer_leaf(leaf_buf);
1269
1270 nritems = btrfs_header_nritems(&leaf->header);
1271 data_end = leaf_data_end(root, leaf);
1272
1273 if (btrfs_leaf_free_space(root, leaf) < data_size)
1274 BUG();
1275 slot = path->slots[0];
1276 old_data = btrfs_item_end(leaf->items + slot);
1277
1278 BUG_ON(slot < 0);
1279 BUG_ON(slot >= nritems);
1280
1281 /*
1282 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1283 */
1284 /* first correct the data pointers */
1285 for (i = slot; i < nritems; i++) {
1286 u32 ioff = btrfs_item_offset(leaf->items + i);
1287 btrfs_set_item_offset(leaf->items + i,
1288 ioff - data_size);
1289 }
1290 /* shift the data */
1291 btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1292 data_end - data_size, btrfs_leaf_data(leaf) +
1293 data_end, old_data - data_end);
1294 data_end = old_data;
1295 old_size = btrfs_item_size(leaf->items + slot);
1296 btrfs_set_item_size(leaf->items + slot, old_size + data_size);
1297 btrfs_mark_buffer_dirty(leaf_buf);
1298
1299 ret = 0;
1300 if (btrfs_leaf_free_space(root, leaf) < 0)
1301 BUG();
1302 check_leaf(root, path, 0);
1303 return ret;
1304}
1305
1252/* 1306/*
1253 * Given a key and some data, insert an item into the tree. 1307 * Given a key and some data, insert an item into the tree.
1254 * This does all the path init required, making room in the tree if needed. 1308 * This does all the path init required, making room in the tree if needed.