start of support for subvolumes
[btrfs-progs-unstable.git] / dir-item.c
blob7058b89f2e0f38c0d376fd8b8be10e1fe74dd5e6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "kerncompat.h"
4 #include "radix-tree.h"
5 #include "ctree.h"
6 #include "disk-io.h"
7 #include "hash.h"
8 #include "transaction.h"
10 int insert_with_overflow(struct btrfs_trans_handle *trans, struct btrfs_root
11 *root, struct btrfs_path *path, struct btrfs_key
12 *cpu_key, u32 data_size)
14 int overflow;
15 int ret;
17 ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
18 overflow = btrfs_key_overflow(cpu_key);
20 while(ret == -EEXIST && overflow < BTRFS_KEY_OVERFLOW_MAX) {
21 overflow++;
22 btrfs_set_key_overflow(cpu_key, overflow);
23 btrfs_release_path(root, path);
24 ret = btrfs_insert_empty_item(trans, root, path, cpu_key,
25 data_size);
27 return ret;
30 int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
31 *root, char *name, int name_len, u64 dir,
32 struct btrfs_key *location, u8 type)
34 int ret = 0;
35 struct btrfs_path path;
36 struct btrfs_dir_item *dir_item;
37 char *name_ptr;
38 struct btrfs_key key;
39 u32 data_size;
41 key.objectid = dir;
42 key.flags = 0;
43 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
44 if (name_len == 1 && *name == '.')
45 key.offset = 1;
46 else if (name_len == 2 && name[0] == '.' && name[1] == '.')
47 key.offset = 2;
48 else
49 ret = btrfs_name_hash(name, name_len, &key.offset);
50 BUG_ON(ret);
51 btrfs_init_path(&path);
52 data_size = sizeof(*dir_item) + name_len;
53 ret = insert_with_overflow(trans, root, &path, &key, data_size);
54 if (ret)
55 goto out;
57 dir_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
58 struct btrfs_dir_item);
59 btrfs_cpu_key_to_disk(&dir_item->location, location);
60 btrfs_set_dir_type(dir_item, type);
61 btrfs_set_dir_flags(dir_item, 0);
62 btrfs_set_dir_name_len(dir_item, name_len);
63 name_ptr = (char *)(dir_item + 1);
64 memcpy(name_ptr, name, name_len);
66 /* FIXME, use some real flag for selecting the extra index */
67 if (root == root->fs_info->tree_root)
68 goto out;
70 btrfs_release_path(root, &path);
71 btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
72 key.offset = location->objectid;
73 ret = insert_with_overflow(trans, root, &path, &key, data_size);
74 if (ret)
75 goto out;
77 dir_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
78 struct btrfs_dir_item);
79 btrfs_cpu_key_to_disk(&dir_item->location, location);
80 btrfs_set_dir_type(dir_item, type);
81 btrfs_set_dir_flags(dir_item, 0);
82 btrfs_set_dir_name_len(dir_item, name_len);
83 name_ptr = (char *)(dir_item + 1);
84 memcpy(name_ptr, name, name_len);
85 out:
86 btrfs_release_path(root, &path);
87 return ret;
90 int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
91 *root, struct btrfs_path *path, u64 dir, char *name,
92 int name_len, int mod)
94 int ret;
95 struct btrfs_key key;
96 int ins_len = mod < 0 ? -1 : 0;
97 int cow = mod != 0;
99 key.objectid = dir;
100 key.flags = 0;
101 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
102 btrfs_set_key_overflow(&key, BTRFS_KEY_OVERFLOW_MAX);
103 ret = btrfs_name_hash(name, name_len, &key.offset);
104 BUG_ON(ret);
105 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
106 return ret;
109 int btrfs_match_dir_item_name(struct btrfs_root *root,
110 struct btrfs_path *path, char
111 *name, int name_len)
113 struct btrfs_dir_item *dir_item;
114 char *name_ptr;
116 dir_item = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0],
117 struct btrfs_dir_item);
118 if (btrfs_dir_name_len(dir_item) != name_len)
119 return 0;
120 name_ptr = (char *)(dir_item + 1);
121 if (memcmp(name_ptr, name, name_len))
122 return 0;
123 return 1;