diff options
Diffstat (limited to 'fs/btrfs/dir-test.c')
-rw-r--r-- | fs/btrfs/dir-test.c | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/fs/btrfs/dir-test.c b/fs/btrfs/dir-test.c index e908c0c588cc..56f06c3ba573 100644 --- a/fs/btrfs/dir-test.c +++ b/fs/btrfs/dir-test.c | |||
@@ -45,13 +45,26 @@ static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
45 | int ret; | 45 | int ret; |
46 | char buf[128]; | 46 | char buf[128]; |
47 | unsigned long oid; | 47 | unsigned long oid; |
48 | u64 objectid; | ||
48 | struct btrfs_path path; | 49 | struct btrfs_path path; |
50 | struct btrfs_key inode_map; | ||
49 | 51 | ||
50 | find_num(radix, &oid, 0); | 52 | find_num(radix, &oid, 0); |
51 | sprintf(buf, "str-%lu", oid); | 53 | sprintf(buf, "str-%lu", oid); |
52 | 54 | ||
55 | ret = btrfs_find_free_objectid(trans, root, dir_oid + 1, &objectid); | ||
56 | if (ret) | ||
57 | goto error; | ||
58 | |||
59 | inode_map.objectid = objectid; | ||
60 | inode_map.flags = 0; | ||
61 | inode_map.offset = 0; | ||
62 | |||
63 | ret = btrfs_insert_inode_map(trans, root, objectid, &inode_map); | ||
64 | if (ret) | ||
65 | goto error; | ||
53 | ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid, | 66 | ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf), dir_oid, |
54 | file_oid, 1); | 67 | objectid, 1); |
55 | if (ret) | 68 | if (ret) |
56 | goto error; | 69 | goto error; |
57 | 70 | ||
@@ -120,6 +133,53 @@ static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root | |||
120 | return 0; | 133 | return 0; |
121 | } | 134 | } |
122 | 135 | ||
136 | static int del_dir_item(struct btrfs_trans_handle *trans, | ||
137 | struct btrfs_root *root, | ||
138 | struct radix_tree_root *radix, | ||
139 | unsigned long radix_index, | ||
140 | struct btrfs_path *path) | ||
141 | { | ||
142 | int ret; | ||
143 | unsigned long *ptr; | ||
144 | u64 file_objectid; | ||
145 | struct btrfs_dir_item *di; | ||
146 | struct btrfs_path map_path; | ||
147 | |||
148 | /* find the inode number of the file */ | ||
149 | di = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0], | ||
150 | struct btrfs_dir_item); | ||
151 | file_objectid = btrfs_dir_objectid(di); | ||
152 | |||
153 | /* delete the directory item */ | ||
154 | ret = btrfs_del_item(trans, root, path); | ||
155 | if (ret) | ||
156 | goto out; | ||
157 | |||
158 | /* delete the inode mapping */ | ||
159 | btrfs_init_path(&map_path); | ||
160 | ret = btrfs_lookup_inode_map(trans, root, &map_path, file_objectid, -1); | ||
161 | if (ret) | ||
162 | goto out_release; | ||
163 | ret = btrfs_del_item(trans, root->fs_info->inode_root, &map_path); | ||
164 | if (ret) | ||
165 | goto out_release; | ||
166 | |||
167 | if (root->fs_info->last_inode_alloc > file_objectid) | ||
168 | root->fs_info->last_inode_alloc = file_objectid; | ||
169 | btrfs_release_path(root, &map_path); | ||
170 | ptr = radix_tree_delete(radix, radix_index); | ||
171 | if (!ptr) { | ||
172 | ret = -5555; | ||
173 | goto out; | ||
174 | } | ||
175 | return 0; | ||
176 | out_release: | ||
177 | btrfs_release_path(root, &map_path); | ||
178 | out: | ||
179 | printf("failed to delete %lu %d\n", radix_index, ret); | ||
180 | return -1; | ||
181 | } | ||
182 | |||
123 | static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 183 | static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
124 | struct radix_tree_root *radix) | 184 | struct radix_tree_root *radix) |
125 | { | 185 | { |
@@ -127,7 +187,6 @@ static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
127 | char buf[128]; | 187 | char buf[128]; |
128 | unsigned long oid; | 188 | unsigned long oid; |
129 | struct btrfs_path path; | 189 | struct btrfs_path path; |
130 | unsigned long *ptr; | ||
131 | 190 | ||
132 | ret = find_num(radix, &oid, 1); | 191 | ret = find_num(radix, &oid, 1); |
133 | if (ret < 0) | 192 | if (ret < 0) |
@@ -138,19 +197,14 @@ static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
138 | strlen(buf), -1); | 197 | strlen(buf), -1); |
139 | if (ret) | 198 | if (ret) |
140 | goto out_release; | 199 | goto out_release; |
141 | ret = btrfs_del_item(trans, root, &path); | 200 | |
201 | ret = del_dir_item(trans, root, radix, oid, &path); | ||
142 | if (ret) | 202 | if (ret) |
143 | goto out_release; | 203 | goto out_release; |
144 | btrfs_release_path(root, &path); | 204 | btrfs_release_path(root, &path); |
145 | ptr = radix_tree_delete(radix, oid); | 205 | return ret; |
146 | if (!ptr) { | ||
147 | ret = -5555; | ||
148 | goto out; | ||
149 | } | ||
150 | return 0; | ||
151 | out_release: | 206 | out_release: |
152 | btrfs_release_path(root, &path); | 207 | btrfs_release_path(root, &path); |
153 | out: | ||
154 | printf("failed to delete %lu %d\n", oid, ret); | 208 | printf("failed to delete %lu %d\n", oid, ret); |
155 | return -1; | 209 | return -1; |
156 | } | 210 | } |
@@ -162,6 +216,8 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
162 | char buf[128]; | 216 | char buf[128]; |
163 | int ret; | 217 | int ret; |
164 | unsigned long oid; | 218 | unsigned long oid; |
219 | u64 objectid; | ||
220 | struct btrfs_dir_item *di; | ||
165 | 221 | ||
166 | ret = find_num(radix, &oid, 1); | 222 | ret = find_num(radix, &oid, 1); |
167 | if (ret < 0) | 223 | if (ret < 0) |
@@ -170,6 +226,14 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root | |||
170 | btrfs_init_path(&path); | 226 | btrfs_init_path(&path); |
171 | ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf, | 227 | ret = btrfs_lookup_dir_item(trans, root, &path, dir_oid, buf, |
172 | strlen(buf), 0); | 228 | strlen(buf), 0); |
229 | if (!ret) { | ||
230 | di = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], | ||
231 | struct btrfs_dir_item); | ||
232 | objectid = btrfs_dir_objectid(di); | ||
233 | btrfs_release_path(root, &path); | ||
234 | btrfs_init_path(&path); | ||
235 | ret = btrfs_lookup_inode_map(trans, root, &path, objectid, 0); | ||
236 | } | ||
173 | btrfs_release_path(root, &path); | 237 | btrfs_release_path(root, &path); |
174 | if (ret) { | 238 | if (ret) { |
175 | printf("unable to find key %lu\n", oid); | 239 | printf("unable to find key %lu\n", oid); |
@@ -210,7 +274,6 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
210 | u32 found_len; | 274 | u32 found_len; |
211 | int ret; | 275 | int ret; |
212 | int slot; | 276 | int slot; |
213 | int *ptr; | ||
214 | int count = 0; | 277 | int count = 0; |
215 | char buf[128]; | 278 | char buf[128]; |
216 | struct btrfs_dir_item *di; | 279 | struct btrfs_dir_item *di; |
@@ -241,7 +304,7 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
241 | BUG_ON(found_len > 128); | 304 | BUG_ON(found_len > 128); |
242 | buf[found_len] = '\0'; | 305 | buf[found_len] = '\0'; |
243 | found = atoi(buf + 4); | 306 | found = atoi(buf + 4); |
244 | ret = btrfs_del_item(trans, root, &path); | 307 | ret = del_dir_item(trans, root, radix, found, &path); |
245 | count++; | 308 | count++; |
246 | if (ret) { | 309 | if (ret) { |
247 | fprintf(stderr, | 310 | fprintf(stderr, |
@@ -250,14 +313,10 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
250 | return -1; | 313 | return -1; |
251 | } | 314 | } |
252 | btrfs_release_path(root, &path); | 315 | btrfs_release_path(root, &path); |
253 | ptr = radix_tree_delete(radix, found); | ||
254 | if (!ptr) | ||
255 | goto error; | ||
256 | if (!keep_running) | 316 | if (!keep_running) |
257 | break; | 317 | break; |
258 | } | 318 | } |
259 | return 0; | 319 | return 0; |
260 | error: | ||
261 | fprintf(stderr, "failed to delete from the radix %lu\n", found); | 320 | fprintf(stderr, "failed to delete from the radix %lu\n", found); |
262 | return -1; | 321 | return -1; |
263 | } | 322 | } |