aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/root-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/root-tree.c')
-rw-r--r--fs/btrfs/root-tree.c69
1 files changed, 51 insertions, 18 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 0ddc6d61c55a..5ef72599a581 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -278,31 +278,57 @@ out:
278 return ret; 278 return ret;
279} 279}
280 280
281#if 0 /* this will get used when snapshot deletion is implemented */
282int btrfs_del_root_ref(struct btrfs_trans_handle *trans, 281int btrfs_del_root_ref(struct btrfs_trans_handle *trans,
283 struct btrfs_root *tree_root, 282 struct btrfs_root *tree_root,
284 u64 root_id, u8 type, u64 ref_id) 283 u64 root_id, u64 ref_id, u64 dirid, u64 *sequence,
284 const char *name, int name_len)
285
285{ 286{
287 struct btrfs_path *path;
288 struct btrfs_root_ref *ref;
289 struct extent_buffer *leaf;
286 struct btrfs_key key; 290 struct btrfs_key key;
291 unsigned long ptr;
292 int err = 0;
287 int ret; 293 int ret;
288 struct btrfs_path *path;
289 294
290 path = btrfs_alloc_path(); 295 path = btrfs_alloc_path();
296 if (!path)
297 return -ENOMEM;
291 298
292 key.objectid = root_id; 299 key.objectid = root_id;
293 key.type = type; 300 key.type = BTRFS_ROOT_BACKREF_KEY;
294 key.offset = ref_id; 301 key.offset = ref_id;
295 302again:
296 ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); 303 ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
297 BUG_ON(ret); 304 BUG_ON(ret < 0);
298 305 if (ret == 0) {
299 ret = btrfs_del_item(trans, tree_root, path); 306 leaf = path->nodes[0];
300 BUG_ON(ret); 307 ref = btrfs_item_ptr(leaf, path->slots[0],
308 struct btrfs_root_ref);
309
310 WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
311 WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
312 ptr = (unsigned long)(ref + 1);
313 WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
314 *sequence = btrfs_root_ref_sequence(leaf, ref);
315
316 ret = btrfs_del_item(trans, tree_root, path);
317 BUG_ON(ret);
318 } else
319 err = -ENOENT;
320
321 if (key.type == BTRFS_ROOT_BACKREF_KEY) {
322 btrfs_release_path(tree_root, path);
323 key.objectid = ref_id;
324 key.type = BTRFS_ROOT_REF_KEY;
325 key.offset = root_id;
326 goto again;
327 }
301 328
302 btrfs_free_path(path); 329 btrfs_free_path(path);
303 return ret; 330 return err;
304} 331}
305#endif
306 332
307int btrfs_find_root_ref(struct btrfs_root *tree_root, 333int btrfs_find_root_ref(struct btrfs_root *tree_root,
308 struct btrfs_path *path, 334 struct btrfs_path *path,
@@ -319,7 +345,6 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root,
319 return ret; 345 return ret;
320} 346}
321 347
322
323/* 348/*
324 * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY 349 * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY
325 * or BTRFS_ROOT_BACKREF_KEY. 350 * or BTRFS_ROOT_BACKREF_KEY.
@@ -335,8 +360,7 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root,
335 */ 360 */
336int btrfs_add_root_ref(struct btrfs_trans_handle *trans, 361int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
337 struct btrfs_root *tree_root, 362 struct btrfs_root *tree_root,
338 u64 root_id, u8 type, u64 ref_id, 363 u64 root_id, u64 ref_id, u64 dirid, u64 sequence,
339 u64 dirid, u64 sequence,
340 const char *name, int name_len) 364 const char *name, int name_len)
341{ 365{
342 struct btrfs_key key; 366 struct btrfs_key key;
@@ -346,13 +370,14 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
346 struct extent_buffer *leaf; 370 struct extent_buffer *leaf;
347 unsigned long ptr; 371 unsigned long ptr;
348 372
349
350 path = btrfs_alloc_path(); 373 path = btrfs_alloc_path();
374 if (!path)
375 return -ENOMEM;
351 376
352 key.objectid = root_id; 377 key.objectid = root_id;
353 key.type = type; 378 key.type = BTRFS_ROOT_BACKREF_KEY;
354 key.offset = ref_id; 379 key.offset = ref_id;
355 380again:
356 ret = btrfs_insert_empty_item(trans, tree_root, path, &key, 381 ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
357 sizeof(*ref) + name_len); 382 sizeof(*ref) + name_len);
358 BUG_ON(ret); 383 BUG_ON(ret);
@@ -366,6 +391,14 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
366 write_extent_buffer(leaf, name, ptr, name_len); 391 write_extent_buffer(leaf, name, ptr, name_len);
367 btrfs_mark_buffer_dirty(leaf); 392 btrfs_mark_buffer_dirty(leaf);
368 393
394 if (key.type == BTRFS_ROOT_BACKREF_KEY) {
395 btrfs_release_path(tree_root, path);
396 key.objectid = ref_id;
397 key.type = BTRFS_ROOT_REF_KEY;
398 key.offset = root_id;
399 goto again;
400 }
401
369 btrfs_free_path(path); 402 btrfs_free_path(path);
370 return ret; 403 return 0;
371} 404}