btrfs-progs: fsck-tests: add test case with keyed data backref with reloc tree blocks
[btrfs-progs-unstable/devel.git] / inode.c
blob2398bca4a1096bb20cf4d8cf632b99e8b527c66c
1 /*
2 * Copyright (C) 2014 Fujitsu. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
20 * Unlike inode.c in kernel, which can use most of the kernel infrastructure
21 * like inode/dentry things, in user-land, we can only use inode number to
22 * do directly operation on extent buffer, which may cause extra searching,
23 * but should not be a huge problem since progs is less performance sensitive.
25 #include <sys/stat.h>
27 #include "ctree.h"
28 #include "transaction.h"
29 #include "disk-io.h"
30 #include "time.h"
31 #include "messages.h"
34 * Find a free inode index for later btrfs_add_link().
35 * Currently just search from the largest dir_index and +1.
37 static int btrfs_find_free_dir_index(struct btrfs_root *root, u64 dir_ino,
38 u64 *ret_ino)
40 struct btrfs_path *path;
41 struct btrfs_key key;
42 struct btrfs_key found_key;
43 u64 ret_val = 2;
44 int ret = 0;
46 if (!ret_ino)
47 return 0;
49 path = btrfs_alloc_path();
50 if (!path)
51 return -ENOMEM;
53 key.objectid = dir_ino;
54 key.type = BTRFS_DIR_INDEX_KEY;
55 key.offset = (u64)-1;
57 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
58 if (ret < 0)
59 goto out;
60 ret = 0;
61 if (path->slots[0] == 0) {
62 ret = btrfs_prev_leaf(root, path);
63 if (ret < 0)
64 goto out;
65 if (ret > 0) {
67 * This shouldn't happen since there must be a leaf
68 * containing the DIR_ITEM.
69 * Can only happen when the previous leaf is corrupted.
71 ret = -EIO;
72 goto out;
74 } else {
75 path->slots[0]--;
77 btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]);
78 if (found_key.objectid != dir_ino ||
79 found_key.type != BTRFS_DIR_INDEX_KEY)
80 goto out;
81 ret_val = found_key.offset + 1;
82 out:
83 btrfs_free_path(path);
84 if (ret == 0)
85 *ret_ino = ret_val;
86 return ret;
89 /* Check the dir_item/index conflicts before insert */
90 int check_dir_conflict(struct btrfs_root *root, char *name, int namelen,
91 u64 dir, u64 index)
93 struct btrfs_path *path;
94 struct btrfs_key key;
95 struct btrfs_inode_item *inode_item;
96 struct btrfs_dir_item *dir_item;
97 int ret = 0;
99 path = btrfs_alloc_path();
100 if (!path)
101 return -ENOMEM;
103 /* Given dir exists? */
104 key.objectid = dir;
105 key.type = BTRFS_INODE_ITEM_KEY;
106 key.offset = 0;
107 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
108 if (ret < 0)
109 goto out;
110 if (ret > 0) {
111 ret = -ENOENT;
112 goto out;
115 /* Is it a dir? */
116 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
117 struct btrfs_inode_item);
118 if (!(btrfs_inode_mode(path->nodes[0], inode_item) & S_IFDIR)) {
119 ret = -ENOTDIR;
120 goto out;
122 btrfs_release_path(path);
124 /* Name conflicting? */
125 dir_item = btrfs_lookup_dir_item(NULL, root, path, dir, name,
126 namelen, 0);
127 if (IS_ERR(dir_item)) {
128 ret = PTR_ERR(dir_item);
129 goto out;
131 if (dir_item) {
132 ret = -EEXIST;
133 goto out;
135 btrfs_release_path(path);
137 /* Index conflicting? */
138 dir_item = btrfs_lookup_dir_index(NULL, root, path, dir, name,
139 namelen, index, 0);
140 if (IS_ERR(dir_item) && PTR_ERR(dir_item) == -ENOENT)
141 dir_item = NULL;
142 if (IS_ERR(dir_item)) {
143 ret = PTR_ERR(dir_item);
144 goto out;
146 if (dir_item) {
147 ret = -EEXIST;
148 goto out;
151 out:
152 btrfs_free_path(path);
153 return ret;
157 * Add dir_item/index for 'parent_ino' if add_backref is true, also insert a
158 * backref from the ino to parent dir and update the nlink(Kernel version does
159 * not do this thing)
161 * Currently only supports adding link from an inode to another inode.
163 int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root,
164 u64 ino, u64 parent_ino, char *name, int namelen,
165 u8 type, u64 *index, int add_backref, int ignore_existed)
167 struct btrfs_path *path;
168 struct btrfs_key key;
169 struct btrfs_inode_item *inode_item;
170 u32 nlink;
171 u64 inode_size;
172 u64 ret_index = 0;
173 int ret = 0;
175 path = btrfs_alloc_path();
176 if (!path)
177 return -ENOMEM;
179 if (index && *index) {
180 ret_index = *index;
181 } else {
182 ret = btrfs_find_free_dir_index(root, parent_ino, &ret_index);
183 if (ret < 0)
184 goto out;
187 ret = check_dir_conflict(root, name, namelen, parent_ino, ret_index);
188 if (ret < 0 && !(ignore_existed && ret == -EEXIST))
189 goto out;
191 /* Add inode ref */
192 if (add_backref) {
193 ret = btrfs_insert_inode_ref(trans, root, name, namelen,
194 ino, parent_ino, ret_index);
195 if (ret < 0 && !(ignore_existed && ret == -EEXIST))
196 goto out;
198 /* do not update nlinks if existed */
199 if (!ret) {
200 /* Update nlinks for the inode */
201 key.objectid = ino;
202 key.type = BTRFS_INODE_ITEM_KEY;
203 key.offset = 0;
204 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
205 if (ret) {
206 if (ret > 0)
207 ret = -ENOENT;
208 goto out;
210 inode_item = btrfs_item_ptr(path->nodes[0],
211 path->slots[0], struct btrfs_inode_item);
212 nlink = btrfs_inode_nlink(path->nodes[0], inode_item);
213 nlink++;
214 btrfs_set_inode_nlink(path->nodes[0], inode_item,
215 nlink);
216 btrfs_mark_buffer_dirty(path->nodes[0]);
217 btrfs_release_path(path);
221 /* Add dir_item and dir_index */
222 key.objectid = ino;
223 key.type = BTRFS_INODE_ITEM_KEY;
224 key.offset = 0;
225 ret = btrfs_insert_dir_item(trans, root, name, namelen, parent_ino,
226 &key, type, ret_index);
227 if (ret < 0)
228 goto out;
230 /* Update inode size of the parent inode */
231 key.objectid = parent_ino;
232 key.type = BTRFS_INODE_ITEM_KEY;
233 key.offset = 0;
234 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
235 if (ret)
236 goto out;
237 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
238 struct btrfs_inode_item);
239 inode_size = btrfs_inode_size(path->nodes[0], inode_item);
240 inode_size += namelen * 2;
241 btrfs_set_inode_size(path->nodes[0], inode_item, inode_size);
242 btrfs_mark_buffer_dirty(path->nodes[0]);
243 btrfs_release_path(path);
245 out:
246 btrfs_free_path(path);
247 if (ret == 0 && index)
248 *index = ret_index;
249 return ret;
252 int btrfs_add_orphan_item(struct btrfs_trans_handle *trans,
253 struct btrfs_root *root, struct btrfs_path *path,
254 u64 ino)
256 struct btrfs_key key;
258 key.objectid = BTRFS_ORPHAN_OBJECTID;
259 key.type = BTRFS_ORPHAN_ITEM_KEY;
260 key.offset = ino;
262 return btrfs_insert_empty_item(trans, root, path, &key, 0);
266 * Unlink an inode, which will remove its backref and corresponding dir_index/
267 * dir_item if any of them exists.
269 * If an inode's nlink is reduced to 0 and 'add_orphan' is true, it will be
270 * added to orphan inode and waiting to be deleted by next kernel mount.
272 int btrfs_unlink(struct btrfs_trans_handle *trans, struct btrfs_root *root,
273 u64 ino, u64 parent_ino, u64 index, const char *name,
274 int namelen, int add_orphan)
276 struct btrfs_path *path;
277 struct btrfs_key key;
278 struct btrfs_inode_item *inode_item;
279 struct btrfs_inode_ref *inode_ref;
280 struct btrfs_dir_item *dir_item;
281 u64 inode_size;
282 u32 nlinks;
283 int del_inode_ref = 0;
284 int del_dir_item = 0;
285 int del_dir_index = 0;
286 int ret = 0;
288 path = btrfs_alloc_path();
289 if (!path)
290 return -ENOMEM;
292 /* check the ref and backref exists */
293 inode_ref = btrfs_lookup_inode_ref(trans, root, path, name, namelen,
294 ino, parent_ino, 0);
295 if (IS_ERR(inode_ref)) {
296 ret = PTR_ERR(inode_ref);
297 goto out;
299 if (inode_ref)
300 del_inode_ref = 1;
301 btrfs_release_path(path);
303 dir_item = btrfs_lookup_dir_item(NULL, root, path, parent_ino,
304 name, namelen, 0);
305 if (IS_ERR(dir_item)) {
306 ret = PTR_ERR(dir_item);
307 goto out;
309 if (dir_item)
310 del_dir_item = 1;
311 btrfs_release_path(path);
313 dir_item = btrfs_lookup_dir_index(NULL, root, path, parent_ino,
314 name, namelen, index, 0);
316 * Since lookup_dir_index() will return -ENOENT when not found,
317 * we need to do extra check.
319 if (IS_ERR(dir_item) && PTR_ERR(dir_item) == -ENOENT)
320 dir_item = NULL;
321 if (IS_ERR(dir_item)) {
322 ret = PTR_ERR(dir_item);
323 goto out;
325 if (dir_item)
326 del_dir_index = 1;
327 btrfs_release_path(path);
329 if (!del_inode_ref && !del_dir_item && !del_dir_index) {
330 /* All not found, shouldn't happen */
331 ret = -ENOENT;
332 goto out;
335 if (del_inode_ref) {
336 /* Only decrease nlink when deleting inode_ref */
337 key.objectid = ino;
338 key.type = BTRFS_INODE_ITEM_KEY;
339 key.offset = 0;
340 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
341 if (ret) {
342 if (ret > 0)
343 ret = -ENOENT;
344 goto out;
346 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
347 struct btrfs_inode_item);
348 nlinks = btrfs_inode_nlink(path->nodes[0], inode_item);
349 if (nlinks > 0)
350 nlinks--;
351 btrfs_set_inode_nlink(path->nodes[0], inode_item, nlinks);
352 btrfs_mark_buffer_dirty(path->nodes[0]);
353 btrfs_release_path(path);
355 /* For nlinks == 0, add it to orphan list if needed */
356 if (nlinks == 0 && add_orphan) {
357 ret = btrfs_add_orphan_item(trans, root, path, ino);
358 if (ret < 0)
359 goto out;
360 btrfs_mark_buffer_dirty(path->nodes[0]);
361 btrfs_release_path(path);
364 ret = btrfs_del_inode_ref(trans, root, name, namelen, ino,
365 parent_ino, &index);
366 if (ret < 0)
367 goto out;
370 if (del_dir_index) {
371 dir_item = btrfs_lookup_dir_index(trans, root, path,
372 parent_ino, name, namelen,
373 index, -1);
374 if (IS_ERR(dir_item)) {
375 ret = PTR_ERR(dir_item);
376 goto out;
378 if (!dir_item) {
379 ret = -ENOENT;
380 goto out;
382 ret = btrfs_delete_one_dir_name(trans, root, path, dir_item);
383 if (ret)
384 goto out;
385 btrfs_release_path(path);
387 /* Update inode size of the parent inode */
388 key.objectid = parent_ino;
389 key.type = BTRFS_INODE_ITEM_KEY;
390 key.offset = 0;
391 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
392 if (ret)
393 goto out;
394 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
395 struct btrfs_inode_item);
396 inode_size = btrfs_inode_size(path->nodes[0], inode_item);
397 if (inode_size >= namelen)
398 inode_size -= namelen;
399 btrfs_set_inode_size(path->nodes[0], inode_item, inode_size);
400 btrfs_mark_buffer_dirty(path->nodes[0]);
401 btrfs_release_path(path);
404 if (del_dir_item) {
405 dir_item = btrfs_lookup_dir_item(trans, root, path, parent_ino,
406 name, namelen, -1);
407 if (IS_ERR(dir_item)) {
408 ret = PTR_ERR(dir_item);
409 goto out;
411 if (!dir_item) {
412 ret = -ENOENT;
413 goto out;
415 ret = btrfs_delete_one_dir_name(trans, root, path, dir_item);
416 if (ret < 0)
417 goto out;
418 btrfs_release_path(path);
420 /* Update inode size of the parent inode */
421 key.objectid = parent_ino;
422 key.type = BTRFS_INODE_ITEM_KEY;
423 key.offset = 0;
424 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
425 if (ret)
426 goto out;
427 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
428 struct btrfs_inode_item);
429 inode_size = btrfs_inode_size(path->nodes[0], inode_item);
430 if (inode_size >= namelen)
431 inode_size -= namelen;
432 btrfs_set_inode_size(path->nodes[0], inode_item, inode_size);
433 btrfs_mark_buffer_dirty(path->nodes[0]);
434 btrfs_release_path(path);
437 out:
438 btrfs_free_path(path);
439 return ret;
442 /* Fill inode item with 'mode'. Uid/gid to root/root */
443 static void fill_inode_item(struct btrfs_trans_handle *trans,
444 struct btrfs_inode_item *inode_item,
445 u32 mode, u32 nlink)
447 time_t now = time(NULL);
449 btrfs_set_stack_inode_generation(inode_item, trans->transid);
450 btrfs_set_stack_inode_uid(inode_item, 0);
451 btrfs_set_stack_inode_gid(inode_item, 0);
452 btrfs_set_stack_inode_size(inode_item, 0);
453 btrfs_set_stack_inode_mode(inode_item, mode);
454 btrfs_set_stack_inode_nlink(inode_item, nlink);
455 btrfs_set_stack_timespec_sec(&inode_item->atime, now);
456 btrfs_set_stack_timespec_nsec(&inode_item->atime, 0);
457 btrfs_set_stack_timespec_sec(&inode_item->mtime, now);
458 btrfs_set_stack_timespec_nsec(&inode_item->mtime, 0);
459 btrfs_set_stack_timespec_sec(&inode_item->ctime, now);
460 btrfs_set_stack_timespec_nsec(&inode_item->ctime, 0);
464 * Unlike kernel btrfs_new_inode(), we only create the INODE_ITEM, without
465 * its backref.
466 * The backref is added by btrfs_add_link().
468 int btrfs_new_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root,
469 u64 ino, u32 mode)
471 struct btrfs_inode_item inode_item = {0};
472 int ret = 0;
474 fill_inode_item(trans, &inode_item, mode, 0);
475 ret = btrfs_insert_inode(trans, root, ino, &inode_item);
476 return ret;
480 * Change inode flags to given value
482 int btrfs_change_inode_flags(struct btrfs_trans_handle *trans,
483 struct btrfs_root *root, u64 ino, u64 flags)
485 struct btrfs_inode_item *item;
486 struct btrfs_path *path;
487 struct btrfs_key key;
488 int ret;
490 path = btrfs_alloc_path();
491 if (!path)
492 return -ENOMEM;
494 key.objectid = ino;
495 key.type = BTRFS_INODE_ITEM_KEY;
496 key.offset = 0;
498 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
499 if (ret > 0) {
500 ret = -ENOENT;
501 goto out;
503 if (ret < 0)
504 goto out;
506 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
507 struct btrfs_inode_item);
508 btrfs_set_inode_flags(path->nodes[0], item, flags);
509 btrfs_mark_buffer_dirty(path->nodes[0]);
510 out:
511 btrfs_free_path(path);
512 return ret;
516 * Make a dir under the parent inode 'parent_ino' with 'name'
517 * and 'mode', The owner will be root/root.
519 int btrfs_mkdir(struct btrfs_trans_handle *trans, struct btrfs_root *root,
520 char *name, int namelen, u64 parent_ino, u64 *ino, int mode)
522 struct btrfs_dir_item *dir_item;
523 struct btrfs_path *path;
524 u64 ret_ino = 0;
525 int ret = 0;
527 path = btrfs_alloc_path();
528 if (!path)
529 return -ENOMEM;
531 if (ino && *ino)
532 ret_ino = *ino;
534 dir_item = btrfs_lookup_dir_item(NULL, root, path, parent_ino,
535 name, namelen, 0);
536 if (IS_ERR(dir_item)) {
537 ret = PTR_ERR(dir_item);
538 goto out;
541 if (dir_item) {
542 struct btrfs_key found_key;
545 * Already have conflicting name, check if it is a dir.
546 * Either way, no need to continue.
548 btrfs_dir_item_key_to_cpu(path->nodes[0], dir_item, &found_key);
549 ret_ino = found_key.objectid;
550 if (btrfs_dir_type(path->nodes[0], dir_item) != BTRFS_FT_DIR)
551 ret = -EEXIST;
552 goto out;
555 if (!ret_ino)
557 * This is *UNSAFE* if some leaf is corrupted,
558 * only used as a fallback method. Caller should either
559 * ensure the fs is OK or pass ino with unused inode number.
561 ret = btrfs_find_free_objectid(NULL, root, parent_ino,
562 &ret_ino);
563 if (ret)
564 goto out;
565 ret = btrfs_new_inode(trans, root, ret_ino, mode | S_IFDIR);
566 if (ret)
567 goto out;
568 ret = btrfs_add_link(trans, root, ret_ino, parent_ino, name, namelen,
569 BTRFS_FT_DIR, NULL, 1, 0);
570 if (ret)
571 goto out;
572 out:
573 btrfs_free_path(path);
574 if (ret == 0 && ino)
575 *ino = ret_ino;
576 return ret;
579 struct btrfs_root *btrfs_mksubvol(struct btrfs_root *root,
580 const char *base, u64 root_objectid,
581 bool convert)
583 struct btrfs_trans_handle *trans;
584 struct btrfs_fs_info *fs_info = root->fs_info;
585 struct btrfs_root *tree_root = fs_info->tree_root;
586 struct btrfs_root *new_root = NULL;
587 struct btrfs_path path;
588 struct btrfs_inode_item *inode_item;
589 struct extent_buffer *leaf;
590 struct btrfs_key key;
591 u64 dirid = btrfs_root_dirid(&root->root_item);
592 u64 index = 2;
593 char buf[BTRFS_NAME_LEN + 1]; /* for snprintf null */
594 int len;
595 int i;
596 int ret;
598 len = strlen(base);
599 if (len == 0 || len > BTRFS_NAME_LEN)
600 return NULL;
602 btrfs_init_path(&path);
603 key.objectid = dirid;
604 key.type = BTRFS_DIR_INDEX_KEY;
605 key.offset = (u64)-1;
607 ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
608 if (ret <= 0) {
609 error("search for DIR_INDEX dirid %llu failed: %d",
610 (unsigned long long)dirid, ret);
611 goto fail;
614 if (path.slots[0] > 0) {
615 path.slots[0]--;
616 btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
617 if (key.objectid == dirid && key.type == BTRFS_DIR_INDEX_KEY)
618 index = key.offset + 1;
620 btrfs_release_path(&path);
622 trans = btrfs_start_transaction(root, 1);
623 if (IS_ERR(trans)) {
624 error("unable to start transaction");
625 goto fail;
628 key.objectid = dirid;
629 key.offset = 0;
630 key.type = BTRFS_INODE_ITEM_KEY;
632 ret = btrfs_lookup_inode(trans, root, &path, &key, 1);
633 if (ret) {
634 error("search for INODE_ITEM %llu failed: %d",
635 (unsigned long long)dirid, ret);
636 goto fail;
638 leaf = path.nodes[0];
639 inode_item = btrfs_item_ptr(leaf, path.slots[0],
640 struct btrfs_inode_item);
642 key.objectid = root_objectid;
643 key.offset = (u64)-1;
644 key.type = BTRFS_ROOT_ITEM_KEY;
646 memcpy(buf, base, len);
647 if (convert) {
648 for (i = 0; i < 1024; i++) {
649 ret = btrfs_insert_dir_item(trans, root, buf, len,
650 dirid, &key, BTRFS_FT_DIR, index);
651 if (ret != -EEXIST)
652 break;
653 len = snprintf(buf, ARRAY_SIZE(buf), "%s%d", base, i);
654 if (len < 1 || len > BTRFS_NAME_LEN) {
655 ret = -EINVAL;
656 break;
659 } else {
660 ret = btrfs_insert_dir_item(trans, root, buf, len, dirid, &key,
661 BTRFS_FT_DIR, index);
663 if (ret)
664 goto fail;
666 btrfs_set_inode_size(leaf, inode_item, len * 2 +
667 btrfs_inode_size(leaf, inode_item));
668 btrfs_mark_buffer_dirty(leaf);
669 btrfs_release_path(&path);
671 /* add the backref first */
672 ret = btrfs_add_root_ref(trans, tree_root, root_objectid,
673 BTRFS_ROOT_BACKREF_KEY,
674 root->root_key.objectid,
675 dirid, index, buf, len);
676 if (ret) {
677 error("unable to add root backref for %llu: %d",
678 root->root_key.objectid, ret);
679 goto fail;
682 /* now add the forward ref */
683 ret = btrfs_add_root_ref(trans, tree_root, root->root_key.objectid,
684 BTRFS_ROOT_REF_KEY, root_objectid,
685 dirid, index, buf, len);
686 if (ret) {
687 error("unable to add root ref for %llu: %d",
688 root->root_key.objectid, ret);
689 goto fail;
692 ret = btrfs_commit_transaction(trans, root);
693 if (ret) {
694 error("transaction commit failed: %d", ret);
695 goto fail;
698 new_root = btrfs_read_fs_root(fs_info, &key);
699 if (IS_ERR(new_root)) {
700 error("unable to fs read root: %lu", PTR_ERR(new_root));
701 new_root = NULL;
703 fail:
704 btrfs_init_path(&path);
705 return new_root;