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.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 6b76fd967153..43d4779abdd1 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1249,6 +1249,63 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1249 return ret; 1249 return ret;
1250} 1250}
1251 1251
1252int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1253 struct btrfs_root *root,
1254 struct btrfs_path *path,
1255 u32 new_size)
1256{
1257 int ret = 0;
1258 int slot;
1259 int slot_orig;
1260 struct btrfs_leaf *leaf;
1261 struct buffer_head *leaf_buf;
1262 u32 nritems;
1263 unsigned int data_end;
1264 unsigned int old_data_start;
1265 unsigned int old_size;
1266 unsigned int size_diff;
1267 int i;
1268
1269 slot_orig = path->slots[0];
1270 leaf_buf = path->nodes[0];
1271 leaf = btrfs_buffer_leaf(leaf_buf);
1272
1273 nritems = btrfs_header_nritems(&leaf->header);
1274 data_end = leaf_data_end(root, leaf);
1275
1276 slot = path->slots[0];
1277 old_data_start = btrfs_item_offset(leaf->items + slot);
1278 old_size = btrfs_item_size(leaf->items + slot);
1279 BUG_ON(old_size <= new_size);
1280 size_diff = old_size - new_size;
1281
1282 BUG_ON(slot < 0);
1283 BUG_ON(slot >= nritems);
1284
1285 /*
1286 * item0..itemN ... dataN.offset..dataN.size .. data0.size
1287 */
1288 /* first correct the data pointers */
1289 for (i = slot; i < nritems; i++) {
1290 u32 ioff = btrfs_item_offset(leaf->items + i);
1291 btrfs_set_item_offset(leaf->items + i,
1292 ioff + size_diff);
1293 }
1294 /* shift the data */
1295printk("truncate item, new_size %u old_size %u, diff %u, bufp %p, dst, %p, num %u, old_data_start %u, data_end %u\n", new_size, old_size, size_diff, leaf, btrfs_leaf_data(leaf) + data_end + size_diff, old_data_start-data_end, old_data_start, data_end);
1296 btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1297 data_end + size_diff, btrfs_leaf_data(leaf) +
1298 data_end, old_data_start + new_size - data_end);
1299 btrfs_set_item_size(leaf->items + slot, new_size);
1300 btrfs_mark_buffer_dirty(leaf_buf);
1301
1302 ret = 0;
1303 if (btrfs_leaf_free_space(root, leaf) < 0)
1304 BUG();
1305 check_leaf(root, path, 0);
1306 return ret;
1307}
1308
1252int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root 1309int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root
1253 *root, struct btrfs_path *path, u32 data_size) 1310 *root, struct btrfs_path *path, u32 data_size)
1254{ 1311{