1 // SPDX-License-Identifier: GPL-2.0
5 #include "btree_update.h"
15 #include <linux/dcache.h> /* struct qstr */
16 #include <linux/generic-radix-tree.h>
18 #define QSTR(n) { { { .len = strlen(n) } }, .name = n }
20 static s64 bch2_count_inode_sectors(struct btree_trans *trans, u64 inum)
22 struct btree_iter *iter;
27 for_each_btree_key(trans, iter, BTREE_ID_extents,
28 POS(inum, 0), 0, k, ret) {
29 if (k.k->p.inode != inum)
32 if (bkey_extent_is_allocation(k.k))
36 bch2_trans_iter_free(trans, iter);
38 return ret ?: sectors;
41 static int __lookup_inode(struct btree_trans *trans, u64 inode_nr,
42 struct bch_inode_unpacked *inode,
45 struct btree_iter *iter;
49 iter = bch2_trans_get_iter(trans, BTREE_ID_inodes,
51 k = bch2_btree_iter_peek_slot(iter);
57 *snapshot = iter->pos.snapshot;
58 ret = k.k->type == KEY_TYPE_inode
59 ? bch2_inode_unpack(bkey_s_c_to_inode(k), inode)
62 bch2_trans_iter_free(trans, iter);
66 static int lookup_inode(struct btree_trans *trans, u64 inode_nr,
67 struct bch_inode_unpacked *inode,
70 return lockrestart_do(trans, __lookup_inode(trans, inode_nr, inode, snapshot));
73 static int __write_inode(struct btree_trans *trans,
74 struct bch_inode_unpacked *inode,
77 struct btree_iter *inode_iter =
78 bch2_trans_get_iter(trans, BTREE_ID_inodes,
79 SPOS(0, inode->bi_inum, snapshot),
81 int ret = bch2_inode_write(trans, inode_iter, inode);
82 bch2_trans_iter_put(trans, inode_iter);
86 static int write_inode(struct btree_trans *trans,
87 struct bch_inode_unpacked *inode,
90 int ret = __bch2_trans_do(trans, NULL, NULL,
93 __write_inode(trans, inode, snapshot));
95 bch_err(trans->c, "error in fsck: error %i updating inode", ret);
99 static int __remove_dirent(struct btree_trans *trans, struct bpos pos)
101 struct bch_fs *c = trans->c;
102 struct btree_iter *iter;
103 struct bch_inode_unpacked dir_inode;
104 struct bch_hash_info dir_hash_info;
107 ret = lookup_inode(trans, pos.inode, &dir_inode, NULL);
111 dir_hash_info = bch2_hash_info_init(c, &dir_inode);
113 iter = bch2_trans_get_iter(trans, BTREE_ID_dirents, pos, BTREE_ITER_INTENT);
115 ret = bch2_hash_delete_at(trans, bch2_dirent_hash_desc,
116 &dir_hash_info, iter);
117 bch2_trans_iter_put(trans, iter);
121 static int remove_dirent(struct btree_trans *trans, struct bpos pos)
123 int ret = __bch2_trans_do(trans, NULL, NULL,
125 BTREE_INSERT_LAZY_RW,
126 __remove_dirent(trans, pos));
128 bch_err(trans->c, "remove_dirent: err %i deleting dirent", ret);
132 /* Get lost+found, create if it doesn't exist: */
133 static int lookup_lostfound(struct btree_trans *trans,
134 struct bch_inode_unpacked *lostfound)
136 struct bch_fs *c = trans->c;
137 struct bch_inode_unpacked root;
138 struct bch_hash_info root_hash_info;
139 struct qstr lostfound_str = QSTR("lost+found");
144 ret = lookup_inode(trans, BCACHEFS_ROOT_INO, &root, &snapshot);
145 if (ret && ret != -ENOENT)
148 root_hash_info = bch2_hash_info_init(c, &root);
149 inum = bch2_dirent_lookup(c, BCACHEFS_ROOT_INO, &root_hash_info,
152 bch_notice(c, "creating lost+found");
153 goto create_lostfound;
156 ret = lookup_inode(trans, inum, lostfound, &snapshot);
157 if (ret && ret != -ENOENT) {
159 * The check_dirents pass has already run, dangling dirents
160 * shouldn't exist here:
162 bch_err(c, "error looking up lost+found: %i", ret);
166 if (ret == -ENOENT) {
168 bch2_inode_init_early(c, lostfound);
170 ret = __bch2_trans_do(trans, NULL, NULL,
172 BTREE_INSERT_LAZY_RW,
173 bch2_create_trans(trans,
174 BCACHEFS_ROOT_INO, &root,
177 0, 0, S_IFDIR|0700, 0, NULL, NULL));
179 bch_err(c, "error creating lost+found: %i", ret);
185 static int reattach_inode(struct btree_trans *trans,
186 struct bch_inode_unpacked *inode)
188 struct bch_hash_info dir_hash;
189 struct bch_inode_unpacked lostfound;
195 ret = lookup_lostfound(trans, &lostfound);
199 if (S_ISDIR(inode->bi_mode)) {
200 lostfound.bi_nlink++;
202 ret = write_inode(trans, &lostfound, U32_MAX);
207 dir_hash = bch2_hash_info_init(trans->c, &lostfound);
209 snprintf(name_buf, sizeof(name_buf), "%llu", inode->bi_inum);
210 name = (struct qstr) QSTR(name_buf);
212 ret = __bch2_trans_do(trans, NULL, NULL, BTREE_INSERT_LAZY_RW,
213 bch2_dirent_create(trans, lostfound.bi_inum, &dir_hash,
214 mode_to_type(inode->bi_mode),
215 &name, inode->bi_inum, &dir_offset,
216 BCH_HASH_SET_MUST_CREATE));
218 bch_err(trans->c, "error %i reattaching inode %llu",
219 ret, inode->bi_inum);
223 inode->bi_dir = lostfound.bi_inum;
224 inode->bi_dir_offset = dir_offset;
226 return write_inode(trans, inode, U32_MAX);
229 static int remove_backpointer(struct btree_trans *trans,
230 struct bch_inode_unpacked *inode)
232 struct btree_iter *iter;
236 iter = bch2_trans_get_iter(trans, BTREE_ID_dirents,
237 POS(inode->bi_dir, inode->bi_dir_offset), 0);
238 k = bch2_btree_iter_peek_slot(iter);
242 if (k.k->type != KEY_TYPE_dirent) {
247 ret = remove_dirent(trans, k.k->p);
249 bch2_trans_iter_put(trans, iter);
253 struct inode_walker {
254 bool first_this_inode;
258 struct bch_inode_unpacked inode;
261 static struct inode_walker inode_walker_init(void)
263 return (struct inode_walker) {
269 static int walk_inode(struct btree_trans *trans,
270 struct inode_walker *w, u64 inum)
272 if (inum != w->cur_inum) {
273 int ret = lookup_inode(trans, inum, &w->inode, &w->snapshot);
275 if (ret && ret != -ENOENT)
278 w->have_inode = !ret;
280 w->first_this_inode = true;
282 w->first_this_inode = false;
288 static int hash_redo_key(struct btree_trans *trans,
289 const struct bch_hash_desc desc,
290 struct bch_hash_info *hash_info,
291 struct btree_iter *k_iter, struct bkey_s_c k)
293 struct bkey_i delete;
296 tmp = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
300 bkey_reassemble(tmp, k);
302 bkey_init(&delete.k);
303 delete.k.p = k_iter->pos;
304 bch2_trans_update(trans, k_iter, &delete, 0);
306 return bch2_hash_set(trans, desc, hash_info, k_iter->pos.inode,
310 static int fsck_hash_delete_at(struct btree_trans *trans,
311 const struct bch_hash_desc desc,
312 struct bch_hash_info *info,
313 struct btree_iter *iter)
317 ret = bch2_hash_delete_at(trans, desc, info, iter) ?:
318 bch2_trans_commit(trans, NULL, NULL,
320 BTREE_INSERT_LAZY_RW);
322 ret = bch2_btree_iter_traverse(iter);
330 static int hash_check_key(struct btree_trans *trans,
331 const struct bch_hash_desc desc,
332 struct bch_hash_info *hash_info,
333 struct btree_iter *k_iter, struct bkey_s_c hash_k)
335 struct bch_fs *c = trans->c;
336 struct btree_iter *iter = NULL;
342 if (hash_k.k->type != desc.key_type)
345 hash = desc.hash_bkey(hash_info, hash_k);
347 if (likely(hash == hash_k.k->p.offset))
350 if (hash_k.k->p.offset < hash)
353 for_each_btree_key(trans, iter, desc.btree_id, POS(hash_k.k->p.inode, hash),
354 BTREE_ITER_SLOTS, k, ret) {
355 if (!bkey_cmp(k.k->p, hash_k.k->p))
358 if (fsck_err_on(k.k->type == desc.key_type &&
359 !desc.cmp_bkey(k, hash_k), c,
360 "duplicate hash table keys:\n%s",
361 (bch2_bkey_val_to_text(&PBUF(buf), c,
363 ret = fsck_hash_delete_at(trans, desc, hash_info, k_iter);
370 if (bkey_deleted(k.k)) {
371 bch2_trans_iter_free(trans, iter);
376 bch2_trans_iter_free(trans, iter);
379 if (fsck_err(c, "hash table key at wrong offset: btree %u inode %llu offset %llu, "
380 "hashed to %llu should be at %llu\n%s",
381 desc.btree_id, hash_k.k->p.inode, hash_k.k->p.offset,
382 hash, iter->pos.offset,
383 (bch2_bkey_val_to_text(&PBUF(buf), c, hash_k), buf)) == FSCK_ERR_IGNORE)
386 ret = __bch2_trans_do(trans, NULL, NULL,
387 BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
388 hash_redo_key(trans, desc, hash_info, k_iter, hash_k));
390 bch_err(c, "hash_redo_key err %i", ret);
398 static int check_inode(struct btree_trans *trans,
399 struct btree_iter *iter,
400 struct bkey_s_c_inode inode)
402 struct bch_fs *c = trans->c;
403 struct bch_inode_unpacked u;
404 bool do_update = false;
407 ret = bch2_inode_unpack(inode, &u);
409 if (bch2_fs_inconsistent_on(ret, c,
410 "error unpacking inode %llu in fsck",
414 if (u.bi_flags & BCH_INODE_UNLINKED &&
416 fsck_err(c, "filesystem marked clean, but inode %llu unlinked",
418 bch_verbose(c, "deleting inode %llu", u.bi_inum);
420 bch2_trans_unlock(trans);
423 ret = bch2_inode_rm(c, u.bi_inum, false);
425 bch_err(c, "error in fsck: error %i while deleting inode", ret);
429 if (u.bi_flags & BCH_INODE_I_SIZE_DIRTY &&
431 fsck_err(c, "filesystem marked clean, but inode %llu has i_size dirty",
433 bch_verbose(c, "truncating inode %llu", u.bi_inum);
435 bch2_trans_unlock(trans);
439 * XXX: need to truncate partial blocks too here - or ideally
440 * just switch units to bytes and that issue goes away
442 ret = bch2_btree_delete_range_trans(trans, BTREE_ID_extents,
443 POS(u.bi_inum, round_up(u.bi_size, block_bytes(c))),
444 POS(u.bi_inum, U64_MAX),
447 bch_err(c, "error in fsck: error %i truncating inode", ret);
452 * We truncated without our normal sector accounting hook, just
453 * make sure we recalculate it:
455 u.bi_flags |= BCH_INODE_I_SECTORS_DIRTY;
457 u.bi_flags &= ~BCH_INODE_I_SIZE_DIRTY;
461 if (u.bi_flags & BCH_INODE_I_SECTORS_DIRTY &&
463 fsck_err(c, "filesystem marked clean, but inode %llu has i_sectors dirty",
467 bch_verbose(c, "recounting sectors for inode %llu",
470 sectors = bch2_count_inode_sectors(trans, u.bi_inum);
472 bch_err(c, "error in fsck: error %i recounting inode sectors",
477 u.bi_sectors = sectors;
478 u.bi_flags &= ~BCH_INODE_I_SECTORS_DIRTY;
482 if (u.bi_flags & BCH_INODE_BACKPTR_UNTRUSTED) {
485 u.bi_flags &= ~BCH_INODE_BACKPTR_UNTRUSTED;
490 ret = __bch2_trans_do(trans, NULL, NULL,
492 BTREE_INSERT_LAZY_RW,
493 bch2_inode_write(trans, iter, &u));
495 bch_err(c, "error in fsck: error %i "
496 "updating inode", ret);
503 static int check_inodes(struct bch_fs *c, bool full)
505 struct btree_trans trans;
506 struct btree_iter *iter;
508 struct bkey_s_c_inode inode;
511 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
513 for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN, 0, k, ret) {
514 if (k.k->type != KEY_TYPE_inode)
517 inode = bkey_s_c_to_inode(k);
520 (inode.v->bi_flags & (BCH_INODE_I_SIZE_DIRTY|
521 BCH_INODE_I_SECTORS_DIRTY|
522 BCH_INODE_UNLINKED))) {
523 ret = check_inode(&trans, iter, inode);
528 bch2_trans_iter_put(&trans, iter);
530 BUG_ON(ret == -EINTR);
532 return bch2_trans_exit(&trans) ?: ret;
535 static int fix_overlapping_extent(struct btree_trans *trans,
536 struct bkey_s_c k, struct bpos cut_at)
538 struct btree_iter *iter;
542 u = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
543 ret = PTR_ERR_OR_ZERO(u);
547 bkey_reassemble(u, k);
548 bch2_cut_front(cut_at, u);
552 * We don't want to go through the extent_handle_overwrites path:
554 * XXX: this is going to screw up disk accounting, extent triggers
555 * assume things about extent overwrites - we should be running the
556 * triggers manually here
558 iter = bch2_trans_get_iter(trans, BTREE_ID_extents, u->k.p,
559 BTREE_ITER_INTENT|BTREE_ITER_NOT_EXTENTS);
561 BUG_ON(iter->flags & BTREE_ITER_IS_EXTENTS);
562 bch2_trans_update(trans, iter, u, BTREE_TRIGGER_NORUN);
563 bch2_trans_iter_put(trans, iter);
565 return bch2_trans_commit(trans, NULL, NULL,
567 BTREE_INSERT_LAZY_RW);
570 static int inode_backpointer_exists(struct btree_trans *trans,
571 struct bch_inode_unpacked *inode)
573 struct btree_iter *iter;
577 iter = bch2_trans_get_iter(trans, BTREE_ID_dirents,
578 POS(inode->bi_dir, inode->bi_dir_offset), 0);
579 k = bch2_btree_iter_peek_slot(iter);
583 if (k.k->type != KEY_TYPE_dirent)
586 ret = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum) == inode->bi_inum;
588 bch2_trans_iter_free(trans, iter);
592 static bool inode_backpointer_matches(struct bkey_s_c_dirent d,
593 struct bch_inode_unpacked *inode)
595 return d.k->p.inode == inode->bi_dir &&
596 d.k->p.offset == inode->bi_dir_offset;
600 * Walk extents: verify that extents have a corresponding S_ISREG inode, and
601 * that i_size an i_sectors are consistent
604 static int check_extents(struct bch_fs *c)
606 struct inode_walker w = inode_walker_init();
607 struct btree_trans trans;
608 struct btree_iter *iter;
610 struct bkey_buf prev;
614 bch2_bkey_buf_init(&prev);
615 prev.k->k = KEY(0, 0, 0);
616 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
618 bch_verbose(c, "checking extents");
620 iter = bch2_trans_get_iter(&trans, BTREE_ID_extents,
621 POS(BCACHEFS_ROOT_INO, 0),
624 while ((k = bch2_btree_iter_peek(iter)).k &&
625 !(ret = bkey_err(k))) {
627 w.cur_inum != k.k->p.inode &&
628 !(w.inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY) &&
629 fsck_err_on(w.inode.bi_sectors != i_sectors, c,
630 "inode %llu has incorrect i_sectors: got %llu, should be %llu",
632 w.inode.bi_sectors, i_sectors)) {
633 w.inode.bi_sectors = i_sectors;
635 ret = write_inode(&trans, &w.inode, w.snapshot);
640 if (bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) {
644 bch2_bkey_val_to_text(&PBUF(buf1), c, bkey_i_to_s_c(prev.k));
645 bch2_bkey_val_to_text(&PBUF(buf2), c, k);
647 if (fsck_err(c, "overlapping extents:\n%s\n%s", buf1, buf2))
648 return fix_overlapping_extent(&trans, k, prev.k->k.p) ?: -EINTR;
651 ret = walk_inode(&trans, &w, k.k->p.inode);
655 if (w.first_this_inode)
658 if (fsck_err_on(!w.have_inode, c,
659 "extent type %u for missing inode %llu",
660 k.k->type, k.k->p.inode) ||
661 fsck_err_on(w.have_inode &&
662 !S_ISREG(w.inode.bi_mode) && !S_ISLNK(w.inode.bi_mode), c,
663 "extent type %u for non regular file, inode %llu mode %o",
664 k.k->type, k.k->p.inode, w.inode.bi_mode)) {
666 return bch2_btree_delete_range_trans(&trans, BTREE_ID_extents,
667 POS(k.k->p.inode, 0),
668 POS(k.k->p.inode, U64_MAX),
672 if (fsck_err_on(w.have_inode &&
673 !(w.inode.bi_flags & BCH_INODE_I_SIZE_DIRTY) &&
674 k.k->type != KEY_TYPE_reservation &&
675 k.k->p.offset > round_up(w.inode.bi_size, block_bytes(c)) >> 9, c,
676 "extent type %u offset %llu past end of inode %llu, i_size %llu",
677 k.k->type, k.k->p.offset, k.k->p.inode, w.inode.bi_size)) {
679 return bch2_btree_delete_range_trans(&trans, BTREE_ID_extents,
680 POS(k.k->p.inode, round_up(w.inode.bi_size, block_bytes(c))),
681 POS(k.k->p.inode, U64_MAX),
685 if (bkey_extent_is_allocation(k.k))
686 i_sectors += k.k->size;
687 bch2_bkey_buf_reassemble(&prev, c, k);
689 bch2_btree_iter_advance(iter);
694 bch2_trans_iter_put(&trans, iter);
695 bch2_bkey_buf_exit(&prev, c);
696 return bch2_trans_exit(&trans) ?: ret;
700 * Walk dirents: verify that they all have a corresponding S_ISDIR inode,
704 static int check_dirents(struct bch_fs *c)
706 struct inode_walker w = inode_walker_init();
707 struct bch_hash_info hash_info;
708 struct btree_trans trans;
709 struct btree_iter *iter;
712 unsigned nr_subdirs = 0;
715 bch_verbose(c, "checking dirents");
717 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
719 iter = bch2_trans_get_iter(&trans, BTREE_ID_dirents,
720 POS(BCACHEFS_ROOT_INO, 0), 0);
722 while ((k = bch2_btree_iter_peek(iter)).k &&
723 !(ret = bkey_err(k))) {
724 struct bkey_s_c_dirent d;
725 struct bch_inode_unpacked target;
728 bool backpointer_exists = true;
732 w.cur_inum != k.k->p.inode &&
733 fsck_err_on(w.inode.bi_nlink != nr_subdirs, c,
734 "directory %llu with wrong i_nlink: got %u, should be %u",
735 w.inode.bi_inum, w.inode.bi_nlink, nr_subdirs)) {
736 w.inode.bi_nlink = nr_subdirs;
737 ret = write_inode(&trans, &w.inode, w.snapshot);
742 ret = walk_inode(&trans, &w, k.k->p.inode);
746 if (w.first_this_inode)
749 if (fsck_err_on(!w.have_inode, c,
750 "dirent in nonexisting directory:\n%s",
751 (bch2_bkey_val_to_text(&PBUF(buf), c,
753 fsck_err_on(!S_ISDIR(w.inode.bi_mode), c,
754 "dirent in non directory inode type %u:\n%s",
755 mode_to_type(w.inode.bi_mode),
756 (bch2_bkey_val_to_text(&PBUF(buf), c,
758 ret = lockrestart_do(&trans,
759 bch2_btree_delete_at(&trans, iter, 0));
768 if (w.first_this_inode)
769 hash_info = bch2_hash_info_init(c, &w.inode);
771 ret = hash_check_key(&trans, bch2_dirent_hash_desc,
772 &hash_info, iter, k);
780 if (k.k->type != KEY_TYPE_dirent)
783 d = bkey_s_c_to_dirent(k);
784 d_inum = le64_to_cpu(d.v->d_inum);
786 ret = lookup_inode(&trans, d_inum, &target, &target_snapshot);
787 if (ret && ret != -ENOENT)
793 if (fsck_err_on(!have_target, c,
794 "dirent points to missing inode:\n%s",
795 (bch2_bkey_val_to_text(&PBUF(buf), c,
797 ret = remove_dirent(&trans, d.k->p);
806 if (!target.bi_dir &&
807 !target.bi_dir_offset) {
808 target.bi_dir = k.k->p.inode;
809 target.bi_dir_offset = k.k->p.offset;
811 ret = write_inode(&trans, &target, target_snapshot);
816 if (!inode_backpointer_matches(d, &target)) {
817 ret = inode_backpointer_exists(&trans, &target);
821 backpointer_exists = ret;
824 if (fsck_err_on(S_ISDIR(target.bi_mode) &&
825 backpointer_exists, c,
826 "directory %llu with multiple links",
828 ret = remove_dirent(&trans, d.k->p);
834 if (fsck_err_on(backpointer_exists &&
836 "inode %llu has multiple links but i_nlink 0",
839 target.bi_flags &= ~BCH_INODE_UNLINKED;
841 ret = write_inode(&trans, &target, target_snapshot);
846 if (fsck_err_on(!backpointer_exists, c,
847 "inode %llu has wrong backpointer:\n"
849 "should be %llu:%llu",
852 target.bi_dir_offset,
855 target.bi_dir = k.k->p.inode;
856 target.bi_dir_offset = k.k->p.offset;
858 ret = write_inode(&trans, &target, target_snapshot);
864 if (fsck_err_on(d.v->d_type != mode_to_type(target.bi_mode), c,
865 "incorrect d_type: should be %u:\n%s",
866 mode_to_type(target.bi_mode),
867 (bch2_bkey_val_to_text(&PBUF(buf), c,
869 struct bkey_i_dirent *n;
871 n = kmalloc(bkey_bytes(d.k), GFP_KERNEL);
877 bkey_reassemble(&n->k_i, d.s_c);
878 n->v.d_type = mode_to_type(target.bi_mode);
880 ret = __bch2_trans_do(&trans, NULL, NULL,
882 BTREE_INSERT_LAZY_RW,
883 (bch2_trans_update(&trans, iter, &n->k_i, 0), 0));
890 nr_subdirs += d.v->d_type == DT_DIR;
892 bch2_btree_iter_advance(iter);
899 bch2_trans_iter_put(&trans, iter);
900 return bch2_trans_exit(&trans) ?: ret;
904 * Walk xattrs: verify that they all have a corresponding inode
907 static int check_xattrs(struct bch_fs *c)
909 struct inode_walker w = inode_walker_init();
910 struct bch_hash_info hash_info;
911 struct btree_trans trans;
912 struct btree_iter *iter;
916 bch_verbose(c, "checking xattrs");
918 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
920 iter = bch2_trans_get_iter(&trans, BTREE_ID_xattrs,
921 POS(BCACHEFS_ROOT_INO, 0), 0);
923 while ((k = bch2_btree_iter_peek(iter)).k &&
924 !(ret = bkey_err(k))) {
925 ret = walk_inode(&trans, &w, k.k->p.inode);
929 if (fsck_err_on(!w.have_inode, c,
930 "xattr for missing inode %llu",
932 ret = bch2_btree_delete_at(&trans, iter, 0);
938 if (w.first_this_inode && w.have_inode)
939 hash_info = bch2_hash_info_init(c, &w.inode);
941 ret = hash_check_key(&trans, bch2_xattr_hash_desc,
942 &hash_info, iter, k);
946 bch2_btree_iter_advance(iter);
952 bch2_trans_iter_put(&trans, iter);
953 return bch2_trans_exit(&trans) ?: ret;
956 /* Get root directory, create if it doesn't exist: */
957 static int check_root(struct bch_fs *c, struct bch_inode_unpacked *root_inode)
959 struct bkey_inode_buf packed;
963 bch_verbose(c, "checking root directory");
965 ret = bch2_trans_do(c, NULL, NULL, 0,
966 lookup_inode(&trans, BCACHEFS_ROOT_INO, root_inode, &snapshot));
967 if (ret && ret != -ENOENT)
970 if (fsck_err_on(ret, c, "root directory missing"))
973 if (fsck_err_on(!S_ISDIR(root_inode->bi_mode), c,
974 "root inode not a directory"))
981 bch2_inode_init(c, root_inode, 0, 0, S_IFDIR|0755,
983 root_inode->bi_inum = BCACHEFS_ROOT_INO;
985 bch2_inode_pack(c, &packed, root_inode);
987 return bch2_btree_insert(c, BTREE_ID_inodes, &packed.inode.k_i,
990 BTREE_INSERT_LAZY_RW);
997 struct pathbuf_entry {
1002 static int path_down(struct pathbuf *p, u64 inum)
1004 if (p->nr == p->size) {
1005 size_t new_size = max_t(size_t, 256UL, p->size * 2);
1006 void *n = krealloc(p->entries,
1007 new_size * sizeof(p->entries[0]),
1017 p->entries[p->nr++] = (struct pathbuf_entry) {
1023 static int check_path(struct btree_trans *trans,
1025 struct bch_inode_unpacked *inode)
1027 struct bch_fs *c = trans->c;
1034 while (inode->bi_inum != BCACHEFS_ROOT_INO) {
1035 ret = lockrestart_do(trans,
1036 inode_backpointer_exists(trans, inode));
1041 if (fsck_err(c, "unreachable inode %llu, type %u nlink %u backptr %llu:%llu",
1043 mode_to_type(inode->bi_mode),
1046 inode->bi_dir_offset))
1047 ret = reattach_inode(trans, inode);
1052 if (!S_ISDIR(inode->bi_mode))
1055 ret = path_down(p, inode->bi_inum);
1057 bch_err(c, "memory allocation failure");
1061 for (i = 0; i < p->nr; i++) {
1062 if (inode->bi_dir != p->entries[i].inum)
1065 /* XXX print path */
1066 if (!fsck_err(c, "directory structure loop"))
1069 ret = lockrestart_do(trans,
1070 remove_backpointer(trans, inode));
1072 bch_err(c, "error removing dirent: %i", ret);
1076 ret = reattach_inode(trans, inode);
1080 ret = lookup_inode(trans, inode->bi_dir, inode, &snapshot);
1082 /* Should have been caught in dirents pass */
1083 bch_err(c, "error looking up parent directory: %i", ret);
1089 bch_err(c, "%s: err %i", __func__, ret);
1094 * Check for unreachable inodes, as well as loops in the directory structure:
1095 * After check_dirents(), if an inode backpointer doesn't exist that means it's
1098 static int check_directory_structure(struct bch_fs *c)
1100 struct btree_trans trans;
1101 struct btree_iter *iter;
1103 struct bch_inode_unpacked u;
1104 struct pathbuf path = { 0, 0, NULL };
1107 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
1109 for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN, 0, k, ret) {
1110 if (k.k->type != KEY_TYPE_inode)
1113 ret = bch2_inode_unpack(bkey_s_c_to_inode(k), &u);
1115 /* Should have been caught earlier in fsck: */
1116 bch_err(c, "error unpacking inode %llu: %i", k.k->p.offset, ret);
1120 ret = check_path(&trans, &path, &u);
1124 bch2_trans_iter_put(&trans, iter);
1126 BUG_ON(ret == -EINTR);
1128 kfree(path.entries);
1130 return bch2_trans_exit(&trans) ?: ret;
1137 typedef GENRADIX(struct nlink) nlink_table;
1139 static void inc_link(struct bch_fs *c, nlink_table *links,
1140 u64 range_start, u64 *range_end, u64 inum)
1144 if (inum < range_start || inum >= *range_end)
1147 if (inum - range_start >= SIZE_MAX / sizeof(struct nlink)) {
1152 link = genradix_ptr_alloc(links, inum - range_start, GFP_KERNEL);
1154 bch_verbose(c, "allocation failed during fsck - will need another pass");
1163 static int bch2_gc_walk_dirents(struct bch_fs *c, nlink_table *links,
1164 u64 range_start, u64 *range_end)
1166 struct btree_trans trans;
1167 struct btree_iter *iter;
1169 struct bkey_s_c_dirent d;
1172 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
1174 for_each_btree_key(&trans, iter, BTREE_ID_dirents, POS_MIN, 0, k, ret) {
1175 switch (k.k->type) {
1176 case KEY_TYPE_dirent:
1177 d = bkey_s_c_to_dirent(k);
1179 if (d.v->d_type != DT_DIR)
1180 inc_link(c, links, range_start, range_end,
1181 le64_to_cpu(d.v->d_inum));
1185 bch2_trans_cond_resched(&trans);
1187 bch2_trans_iter_put(&trans, iter);
1189 ret = bch2_trans_exit(&trans) ?: ret;
1191 bch_err(c, "error in fsck: btree error %i while walking dirents", ret);
1196 static int check_inode_nlink(struct btree_trans *trans,
1197 struct btree_iter *iter,
1198 struct bkey_s_c_inode inode,
1201 struct bch_fs *c = trans->c;
1202 struct bch_inode_unpacked u;
1206 * Backpointer and directory structure checks are sufficient for
1207 * directories, since they can't have hardlinks:
1209 if (S_ISDIR(le16_to_cpu(inode.v->bi_mode)))
1213 bch_err(c, "no links found to inode %llu", inode.k->p.offset);
1217 ret = bch2_inode_unpack(inode, &u);
1219 /* Should never happen, checked by bch2_inode_invalid: */
1220 if (bch2_fs_inconsistent_on(ret, c,
1221 "error unpacking inode %llu in fsck",
1225 if (fsck_err_on(bch2_inode_nlink_get(&u) != nlink, c,
1226 "inode %llu has wrong i_nlink (type %u i_nlink %u, should be %u)",
1227 u.bi_inum, mode_to_type(u.bi_mode),
1228 bch2_inode_nlink_get(&u), nlink)) {
1229 bch2_inode_nlink_set(&u, nlink);
1231 ret = __bch2_trans_do(trans, NULL, NULL,
1232 BTREE_INSERT_NOFAIL|
1233 BTREE_INSERT_LAZY_RW,
1234 bch2_inode_write(trans, iter, &u));
1236 bch_err(c, "error in fsck: error %i updating inode", ret);
1243 static int bch2_gc_walk_inodes(struct bch_fs *c,
1245 u64 range_start, u64 range_end)
1247 struct btree_trans trans;
1248 struct btree_iter *iter;
1253 bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
1255 for_each_btree_key(&trans, iter, BTREE_ID_inodes,
1256 POS(0, range_start), 0, k, ret) {
1257 if (!k.k || k.k->p.offset >= range_end)
1260 if (k.k->type != KEY_TYPE_inode)
1263 link = genradix_ptr(links, k.k->p.offset - range_start);
1264 ret = check_inode_nlink(&trans, iter,
1265 bkey_s_c_to_inode(k), link ? link->count : 0);
1270 bch2_trans_iter_put(&trans, iter);
1271 bch2_trans_exit(&trans);
1274 bch_err(c, "error in fsck: btree error %i while walking inodes", ret);
1280 static int check_nlinks(struct bch_fs *c)
1283 u64 this_iter_range_start, next_iter_range_start = 0;
1286 bch_verbose(c, "checking inode nlinks");
1288 genradix_init(&links);
1291 this_iter_range_start = next_iter_range_start;
1292 next_iter_range_start = U64_MAX;
1294 ret = bch2_gc_walk_dirents(c, &links,
1295 this_iter_range_start,
1296 &next_iter_range_start);
1300 ret = bch2_gc_walk_inodes(c, &links,
1301 this_iter_range_start,
1302 next_iter_range_start);
1306 genradix_free(&links);
1307 } while (next_iter_range_start != U64_MAX);
1309 genradix_free(&links);
1315 * Checks for inconsistencies that shouldn't happen, unless we have a bug.
1316 * Doesn't fix them yet, mainly because they haven't yet been observed:
1318 int bch2_fsck_full(struct bch_fs *c)
1320 struct bch_inode_unpacked root_inode;
1322 return check_inodes(c, true) ?:
1326 check_root(c, &root_inode) ?:
1327 check_directory_structure(c) ?:
1331 int bch2_fsck_walk_inodes_only(struct bch_fs *c)
1333 return check_inodes(c, false);