]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcache/fs-gc.c
Delete more unused shim code, update bcache code
[bcachefs-tools-debian] / libbcache / fs-gc.c
1
2 #include "bcache.h"
3 #include "btree_update.h"
4 #include "dirent.h"
5 #include "error.h"
6 #include "fs.h"
7 #include "fs-gc.h"
8 #include "inode.h"
9 #include "keylist.h"
10 #include "super.h"
11
12 #include <linux/generic-radix-tree.h>
13
14 #define QSTR(n) { { { .len = strlen(n) } }, .name = n }
15
16 static int remove_dirent(struct cache_set *c, struct btree_iter *iter,
17                          struct bkey_s_c_dirent dirent)
18 {
19         struct qstr name;
20         struct bch_inode_unpacked dir_inode;
21         struct bch_hash_info dir_hash_info;
22         u64 dir_inum = dirent.k->p.inode;
23         int ret;
24         char *buf;
25
26         name.len = bch_dirent_name_bytes(dirent);
27         buf = kmalloc(name.len + 1, GFP_KERNEL);
28         if (!buf)
29                 return -ENOMEM;
30
31         memcpy(buf, dirent.v->d_name, name.len);
32         buf[name.len] = '\0';
33         name.name = buf;
34
35         /* Unlock iter so we don't deadlock, after copying name: */
36         bch_btree_iter_unlock(iter);
37
38         ret = bch_inode_find_by_inum(c, dir_inum, &dir_inode);
39         if (ret)
40                 goto err;
41
42         dir_hash_info = bch_hash_info_init(&dir_inode);
43
44         ret = bch_dirent_delete(c, dir_inum, &dir_hash_info, &name, NULL);
45 err:
46         kfree(buf);
47         return ret;
48 }
49
50 static int reattach_inode(struct cache_set *c,
51                           struct bch_inode_unpacked *lostfound_inode,
52                           u64 inum)
53 {
54         struct bch_hash_info lostfound_hash_info =
55                 bch_hash_info_init(lostfound_inode);
56         struct bkey_inode_buf packed;
57         char name_buf[20];
58         struct qstr name;
59         int ret;
60
61         snprintf(name_buf, sizeof(name_buf), "%llu", inum);
62         name = (struct qstr) QSTR(name_buf);
63
64         lostfound_inode->i_nlink++;
65
66         bch_inode_pack(&packed, lostfound_inode);
67
68         ret = bch_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
69                                NULL, NULL, NULL, 0);
70         if (ret)
71                 return ret;
72
73         return bch_dirent_create(c, lostfound_inode->inum,
74                                  &lostfound_hash_info,
75                                  DT_DIR, &name, inum, NULL, 0);
76 }
77
78 struct inode_walker {
79         bool                    first_this_inode;
80         bool                    have_inode;
81         u64                     cur_inum;
82         struct bch_inode_unpacked inode;
83 };
84
85 static struct inode_walker inode_walker_init(void)
86 {
87         return (struct inode_walker) {
88                 .cur_inum       = -1,
89                 .have_inode     = false,
90         };
91 }
92
93 static int walk_inode(struct cache_set *c, struct inode_walker *w, u64 inum)
94 {
95         w->first_this_inode     = inum != w->cur_inum;
96         w->cur_inum             = inum;
97
98         if (w->first_this_inode) {
99                 int ret = bch_inode_find_by_inum(c, inum, &w->inode);
100
101                 if (ret && ret != -ENOENT)
102                         return ret;
103
104                 w->have_inode = !ret;
105         }
106
107         return 0;
108 }
109
110 /*
111  * Walk extents: verify that extents have a corresponding S_ISREG inode, and
112  * that i_size an i_sectors are consistent
113  */
114 noinline_for_stack
115 static int check_extents(struct cache_set *c)
116 {
117         struct inode_walker w = inode_walker_init();
118         struct btree_iter iter;
119         struct bkey_s_c k;
120         u64 i_sectors;
121         int ret = 0;
122
123         for_each_btree_key(&iter, c, BTREE_ID_EXTENTS,
124                            POS(BCACHE_ROOT_INO, 0), k) {
125                 if (k.k->type == KEY_TYPE_DISCARD)
126                         continue;
127
128                 ret = walk_inode(c, &w, k.k->p.inode);
129                 if (ret)
130                         break;
131
132                 unfixable_fsck_err_on(!w.have_inode, c,
133                         "extent type %u for missing inode %llu",
134                         k.k->type, k.k->p.inode);
135
136                 unfixable_fsck_err_on(w.first_this_inode && w.have_inode &&
137                         w.inode.i_sectors !=
138                         (i_sectors = bch_count_inode_sectors(c, w.cur_inum)),
139                         c, "i_sectors wrong: got %llu, should be %llu",
140                         w.inode.i_sectors, i_sectors);
141
142                 unfixable_fsck_err_on(w.have_inode &&
143                         !S_ISREG(w.inode.i_mode) && !S_ISLNK(w.inode.i_mode), c,
144                         "extent type %u for non regular file, inode %llu mode %o",
145                         k.k->type, k.k->p.inode, w.inode.i_mode);
146
147                 unfixable_fsck_err_on(k.k->type != BCH_RESERVATION &&
148                         k.k->p.offset > round_up(w.inode.i_size, PAGE_SIZE) >> 9, c,
149                         "extent type %u offset %llu past end of inode %llu, i_size %llu",
150                         k.k->type, k.k->p.offset, k.k->p.inode, w.inode.i_size);
151         }
152 fsck_err:
153         return bch_btree_iter_unlock(&iter) ?: ret;
154 }
155
156 /*
157  * Walk dirents: verify that they all have a corresponding S_ISDIR inode,
158  * validate d_type
159  */
160 noinline_for_stack
161 static int check_dirents(struct cache_set *c)
162 {
163         struct inode_walker w = inode_walker_init();
164         struct btree_iter iter;
165         struct bkey_s_c k;
166         int ret = 0;
167
168         for_each_btree_key(&iter, c, BTREE_ID_DIRENTS,
169                            POS(BCACHE_ROOT_INO, 0), k) {
170                 struct bkey_s_c_dirent d;
171                 struct bch_inode_unpacked target;
172                 bool have_target;
173                 u64 d_inum;
174
175                 ret = walk_inode(c, &w, k.k->p.inode);
176                 if (ret)
177                         break;
178
179                 unfixable_fsck_err_on(!w.have_inode, c,
180                                       "dirent in nonexisting directory %llu",
181                                       k.k->p.inode);
182
183                 unfixable_fsck_err_on(!S_ISDIR(w.inode.i_mode), c,
184                                       "dirent in non directory inode %llu, type %u",
185                                       k.k->p.inode, mode_to_type(w.inode.i_mode));
186
187                 if (k.k->type != BCH_DIRENT)
188                         continue;
189
190                 d = bkey_s_c_to_dirent(k);
191                 d_inum = le64_to_cpu(d.v->d_inum);
192
193                 if (fsck_err_on(d_inum == d.k->p.inode, c,
194                                 "dirent points to own directory")) {
195                         ret = remove_dirent(c, &iter, d);
196                         if (ret)
197                                 goto err;
198                         continue;
199                 }
200
201                 ret = bch_inode_find_by_inum(c, d_inum, &target);
202                 if (ret && ret != -ENOENT)
203                         break;
204
205                 have_target = !ret;
206                 ret = 0;
207
208                 if (fsck_err_on(!have_target, c,
209                                 "dirent points to missing inode %llu, type %u filename %s",
210                                 d_inum, d.v->d_type, d.v->d_name)) {
211                         ret = remove_dirent(c, &iter, d);
212                         if (ret)
213                                 goto err;
214                         continue;
215                 }
216
217                 if (fsck_err_on(have_target &&
218                                 d.v->d_type !=
219                                 mode_to_type(le16_to_cpu(target.i_mode)), c,
220                                 "incorrect d_type: got %u should be %u, filename %s",
221                                 d.v->d_type,
222                                 mode_to_type(le16_to_cpu(target.i_mode)),
223                                 d.v->d_name)) {
224                         struct bkey_i_dirent *n;
225
226                         n = kmalloc(bkey_bytes(d.k), GFP_KERNEL);
227                         if (!n) {
228                                 ret = -ENOMEM;
229                                 goto err;
230                         }
231
232                         bkey_reassemble(&n->k_i, d.s_c);
233                         n->v.d_type = mode_to_type(le16_to_cpu(target.i_mode));
234
235                         ret = bch_btree_insert_at(c, NULL, NULL, NULL,
236                                         BTREE_INSERT_NOFAIL,
237                                         BTREE_INSERT_ENTRY(&iter, &n->k_i));
238                         kfree(n);
239                         if (ret)
240                                 goto err;
241
242                 }
243         }
244 err:
245 fsck_err:
246         return bch_btree_iter_unlock(&iter) ?: ret;
247 }
248
249 /*
250  * Walk xattrs: verify that they all have a corresponding inode
251  */
252 noinline_for_stack
253 static int check_xattrs(struct cache_set *c)
254 {
255         struct inode_walker w = inode_walker_init();
256         struct btree_iter iter;
257         struct bkey_s_c k;
258         int ret = 0;
259
260         for_each_btree_key(&iter, c, BTREE_ID_XATTRS,
261                            POS(BCACHE_ROOT_INO, 0), k) {
262                 ret = walk_inode(c, &w, k.k->p.inode);
263                 if (ret)
264                         break;
265
266                 unfixable_fsck_err_on(!w.have_inode, c,
267                         "xattr for missing inode %llu",
268                         k.k->p.inode);
269         }
270 fsck_err:
271         return bch_btree_iter_unlock(&iter) ?: ret;
272 }
273
274 /* Get root directory, create if it doesn't exist: */
275 static int check_root(struct cache_set *c, struct bch_inode_unpacked *root_inode)
276 {
277         struct bkey_inode_buf packed;
278         int ret;
279
280         ret = bch_inode_find_by_inum(c, BCACHE_ROOT_INO, root_inode);
281         if (ret && ret != -ENOENT)
282                 return ret;
283
284         if (fsck_err_on(ret, c, "root directory missing"))
285                 goto create_root;
286
287         if (fsck_err_on(!S_ISDIR(root_inode->i_mode), c,
288                         "root inode not a directory"))
289                 goto create_root;
290
291         return 0;
292 fsck_err:
293         return ret;
294 create_root:
295         bch_inode_init(c, root_inode, 0, 0, S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0);
296         root_inode->inum = BCACHE_ROOT_INO;
297
298         bch_inode_pack(&packed, root_inode);
299
300         return bch_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
301                                 NULL, NULL, NULL, 0);
302 }
303
304 /* Get lost+found, create if it doesn't exist: */
305 static int check_lostfound(struct cache_set *c,
306                            struct bch_inode_unpacked *root_inode,
307                            struct bch_inode_unpacked *lostfound_inode)
308 {
309         struct qstr lostfound = QSTR("lost+found");
310         struct bch_hash_info root_hash_info =
311                 bch_hash_info_init(root_inode);
312         struct bkey_inode_buf packed;
313         u64 inum;
314         int ret;
315
316         inum = bch_dirent_lookup(c, BCACHE_ROOT_INO, &root_hash_info,
317                                  &lostfound);
318         if (!inum) {
319                 bch_notice(c, "creating lost+found");
320                 goto create_lostfound;
321         }
322
323         ret = bch_inode_find_by_inum(c, inum, lostfound_inode);
324         if (ret && ret != -ENOENT)
325                 return ret;
326
327         if (fsck_err_on(ret, c, "lost+found missing"))
328                 goto create_lostfound;
329
330         if (fsck_err_on(!S_ISDIR(lostfound_inode->i_mode), c,
331                         "lost+found inode not a directory"))
332                 goto create_lostfound;
333
334         return 0;
335 fsck_err:
336         return ret;
337 create_lostfound:
338         root_inode->i_nlink++;
339
340         bch_inode_pack(&packed, root_inode);
341
342         ret = bch_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
343                                NULL, NULL, NULL, 0);
344         if (ret)
345                 return ret;
346
347         bch_inode_init(c, lostfound_inode, 0, 0, S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0);
348         bch_inode_pack(&packed, lostfound_inode);
349
350         ret = bch_inode_create(c, &packed.inode.k_i, BLOCKDEV_INODE_MAX, 0,
351                                &c->unused_inode_hint);
352         if (ret)
353                 return ret;
354
355         lostfound_inode->inum = packed.inode.k.p.inode;
356
357         ret = bch_dirent_create(c, BCACHE_ROOT_INO, &root_hash_info, DT_DIR,
358                                 &lostfound, lostfound_inode->inum, NULL, 0);
359         if (ret)
360                 return ret;
361
362         return 0;
363 }
364
365 struct inode_bitmap {
366         unsigned long   *bits;
367         size_t          size;
368 };
369
370 static inline bool inode_bitmap_test(struct inode_bitmap *b, size_t nr)
371 {
372         return nr < b->size ? test_bit(nr, b->bits) : false;
373 }
374
375 static inline int inode_bitmap_set(struct inode_bitmap *b, size_t nr)
376 {
377         if (nr >= b->size) {
378                 size_t new_size = max(max(PAGE_SIZE * 8,
379                                           b->size * 2),
380                                           nr + 1);
381                 void *n;
382
383                 new_size = roundup_pow_of_two(new_size);
384                 n = krealloc(b->bits, new_size / 8, GFP_KERNEL|__GFP_ZERO);
385                 if (!n)
386                         return -ENOMEM;
387
388                 b->bits = n;
389                 b->size = new_size;
390         }
391
392         __set_bit(nr, b->bits);
393         return 0;
394 }
395
396 struct pathbuf {
397         size_t          nr;
398         size_t          size;
399
400         struct pathbuf_entry {
401                 u64     inum;
402                 u64     offset;
403         }               *entries;
404 };
405
406 static int path_down(struct pathbuf *p, u64 inum)
407 {
408         if (p->nr == p->size) {
409                 size_t new_size = max(256UL, p->size * 2);
410                 void *n = krealloc(p->entries,
411                                    new_size * sizeof(p->entries[0]),
412                                    GFP_KERNEL);
413                 if (!n)
414                         return -ENOMEM;
415
416                 p->entries = n;
417                 p->size = new_size;
418         };
419
420         p->entries[p->nr++] = (struct pathbuf_entry) {
421                 .inum = inum,
422                 .offset = 0,
423         };
424         return 0;
425 }
426
427 noinline_for_stack
428 static int check_directory_structure(struct cache_set *c,
429                                      struct bch_inode_unpacked *lostfound_inode)
430 {
431         struct inode_bitmap dirs_done = { NULL, 0 };
432         struct pathbuf path = { 0, 0, NULL };
433         struct pathbuf_entry *e;
434         struct btree_iter iter;
435         struct bkey_s_c k;
436         struct bkey_s_c_dirent dirent;
437         bool had_unreachable;
438         u64 d_inum;
439         int ret = 0;
440
441         /* DFS: */
442 restart_dfs:
443         ret = inode_bitmap_set(&dirs_done, BCACHE_ROOT_INO);
444         if (ret)
445                 goto err;
446
447         ret = path_down(&path, BCACHE_ROOT_INO);
448         if (ret)
449                 return ret;
450
451         while (path.nr) {
452 next:
453                 e = &path.entries[path.nr - 1];
454
455                 if (e->offset == U64_MAX)
456                         goto up;
457
458                 for_each_btree_key(&iter, c, BTREE_ID_DIRENTS,
459                                    POS(e->inum, e->offset + 1), k) {
460                         if (k.k->p.inode != e->inum)
461                                 break;
462
463                         e->offset = k.k->p.offset;
464
465                         if (k.k->type != BCH_DIRENT)
466                                 continue;
467
468                         dirent = bkey_s_c_to_dirent(k);
469
470                         if (dirent.v->d_type != DT_DIR)
471                                 continue;
472
473                         d_inum = le64_to_cpu(dirent.v->d_inum);
474
475                         if (fsck_err_on(inode_bitmap_test(&dirs_done, d_inum), c,
476                                         "directory with multiple hardlinks")) {
477                                 ret = remove_dirent(c, &iter, dirent);
478                                 if (ret)
479                                         goto err;
480                                 continue;
481                         }
482
483                         ret = inode_bitmap_set(&dirs_done, d_inum);
484                         if (ret)
485                                 goto err;
486
487                         ret = path_down(&path, d_inum);
488                         if (ret)
489                                 goto err;
490
491                         bch_btree_iter_unlock(&iter);
492                         goto next;
493                 }
494                 ret = bch_btree_iter_unlock(&iter);
495                 if (ret)
496                         goto err;
497 up:
498                 path.nr--;
499         }
500
501         had_unreachable = false;
502
503         for_each_btree_key(&iter, c, BTREE_ID_INODES, POS_MIN, k) {
504                 if (k.k->type != BCH_INODE_FS ||
505                     !S_ISDIR(le16_to_cpu(bkey_s_c_to_inode(k).v->i_mode)))
506                         continue;
507
508                 if (fsck_err_on(!inode_bitmap_test(&dirs_done, k.k->p.inode), c,
509                                 "unreachable directory found (inum %llu)",
510                                 k.k->p.inode)) {
511                         bch_btree_iter_unlock(&iter);
512
513                         ret = reattach_inode(c, lostfound_inode, k.k->p.inode);
514                         if (ret)
515                                 goto err;
516
517                         had_unreachable = true;
518                 }
519         }
520         ret = bch_btree_iter_unlock(&iter);
521         if (ret)
522                 goto err;
523
524         if (had_unreachable) {
525                 bch_info(c, "reattached unreachable directories, restarting pass to check for loops");
526                 kfree(dirs_done.bits);
527                 kfree(path.entries);
528                 memset(&dirs_done, 0, sizeof(dirs_done));
529                 memset(&path, 0, sizeof(path));
530                 goto restart_dfs;
531         }
532
533 out:
534         kfree(dirs_done.bits);
535         kfree(path.entries);
536         return ret;
537 err:
538 fsck_err:
539         ret = bch_btree_iter_unlock(&iter) ?: ret;
540         goto out;
541 }
542
543 struct nlink {
544         u32     count;
545         u32     dir_count;
546 };
547
548 DECLARE_GENRADIX_TYPE(nlinks, struct nlink);
549
550 static void inc_link(struct cache_set *c, struct nlinks *links,
551                      u64 range_start, u64 *range_end,
552                      u64 inum, bool dir)
553 {
554         struct nlink *link;
555
556         if (inum < range_start || inum >= *range_end)
557                 return;
558
559         link = genradix_ptr_alloc(links, inum - range_start, GFP_KERNEL);
560         if (!link) {
561                 bch_verbose(c, "allocation failed during fs gc - will need another pass");
562                 *range_end = inum;
563                 return;
564         }
565
566         if (dir)
567                 link->dir_count++;
568         else
569                 link->count++;
570 }
571
572 noinline_for_stack
573 static int bch_gc_walk_dirents(struct cache_set *c, struct nlinks *links,
574                                u64 range_start, u64 *range_end)
575 {
576         struct btree_iter iter;
577         struct bkey_s_c k;
578         struct bkey_s_c_dirent d;
579         u64 d_inum;
580         int ret;
581
582         inc_link(c, links, range_start, range_end, BCACHE_ROOT_INO, false);
583
584         for_each_btree_key(&iter, c, BTREE_ID_DIRENTS, POS_MIN, k) {
585                 switch (k.k->type) {
586                 case BCH_DIRENT:
587                         d = bkey_s_c_to_dirent(k);
588                         d_inum = le64_to_cpu(d.v->d_inum);
589
590                         if (d.v->d_type == DT_DIR)
591                                 inc_link(c, links, range_start, range_end,
592                                          d.k->p.inode, true);
593
594                         inc_link(c, links, range_start, range_end,
595                                  d_inum, false);
596
597                         break;
598                 }
599
600                 bch_btree_iter_cond_resched(&iter);
601         }
602         ret = bch_btree_iter_unlock(&iter);
603         if (ret)
604                 bch_err(c, "error in fs gc: btree error %i while walking dirents", ret);
605
606         return ret;
607 }
608
609 s64 bch_count_inode_sectors(struct cache_set *c, u64 inum)
610 {
611         struct btree_iter iter;
612         struct bkey_s_c k;
613         u64 sectors = 0;
614
615         for_each_btree_key(&iter, c, BTREE_ID_EXTENTS, POS(inum, 0), k) {
616                 if (k.k->p.inode != inum)
617                         break;
618
619                 if (bkey_extent_is_allocation(k.k))
620                         sectors += k.k->size;
621         }
622
623         return bch_btree_iter_unlock(&iter) ?: sectors;
624 }
625
626 static int bch_gc_do_inode(struct cache_set *c,
627                            struct bch_inode_unpacked *lostfound_inode,
628                            struct btree_iter *iter,
629                            struct bkey_s_c_inode inode, struct nlink link)
630 {
631         struct bch_inode_unpacked u;
632         int ret = 0;
633         u32 i_nlink, real_i_nlink;
634         bool do_update = false;
635
636         ret = bch_inode_unpack(inode, &u);
637         if (bch_fs_inconsistent_on(ret, c,
638                          "error unpacking inode %llu in fs-gc",
639                          inode.k->p.inode))
640                 return ret;
641
642         i_nlink = u.i_nlink + nlink_bias(u.i_mode);
643
644         fsck_err_on(i_nlink < link.count, c,
645                     "inode %llu i_link too small (%u < %u, type %i)",
646                     inode.k->p.inode, i_nlink,
647                     link.count, mode_to_type(u.i_mode));
648
649         /* These should have been caught/fixed by earlier passes: */
650         if (S_ISDIR(u.i_mode)) {
651                 need_fsck_err_on(link.count > 1, c,
652                         "directory %llu with multiple hardlinks: %u",
653                         inode.k->p.inode, link.count);
654
655                 real_i_nlink = link.count * 2 + link.dir_count;
656         } else {
657                 need_fsck_err_on(link.dir_count, c,
658                         "found dirents for non directory %llu",
659                         inode.k->p.inode);
660
661                 real_i_nlink = link.count + link.dir_count;
662         }
663
664         if (!link.count) {
665                 fsck_err_on(c->sb.clean, c,
666                             "filesystem marked clean, "
667                             "but found orphaned inode %llu",
668                             inode.k->p.inode);
669
670                 if (fsck_err_on(S_ISDIR(u.i_mode) &&
671                                 bch_empty_dir(c, inode.k->p.inode), c,
672                                 "non empty directory with link count 0, "
673                                 "inode nlink %u, dir links found %u",
674                                 i_nlink, link.dir_count)) {
675                         ret = reattach_inode(c, lostfound_inode,
676                                              inode.k->p.inode);
677                         if (ret)
678                                 return ret;
679                 }
680
681                 bch_verbose(c, "deleting inode %llu", inode.k->p.inode);
682
683                 ret = bch_inode_rm(c, inode.k->p.inode);
684                 if (ret)
685                         bch_err(c, "error in fs gc: error %i "
686                                 "while deleting inode", ret);
687                 return ret;
688         }
689
690         if (u.i_flags & BCH_INODE_I_SIZE_DIRTY) {
691                 fsck_err_on(c->sb.clean, c,
692                             "filesystem marked clean, "
693                             "but inode %llu has i_size dirty",
694                             inode.k->p.inode);
695
696                 bch_verbose(c, "truncating inode %llu", inode.k->p.inode);
697
698                 /*
699                  * XXX: need to truncate partial blocks too here - or ideally
700                  * just switch units to bytes and that issue goes away
701                  */
702
703                 ret = bch_inode_truncate(c, inode.k->p.inode,
704                                 round_up(u.i_size, PAGE_SIZE) >> 9,
705                                 NULL, NULL);
706                 if (ret) {
707                         bch_err(c, "error in fs gc: error %i "
708                                 "truncating inode", ret);
709                         return ret;
710                 }
711
712                 /*
713                  * We truncated without our normal sector accounting hook, just
714                  * make sure we recalculate it:
715                  */
716                 u.i_flags |= BCH_INODE_I_SECTORS_DIRTY;
717
718                 u.i_flags &= ~BCH_INODE_I_SIZE_DIRTY;
719                 do_update = true;
720         }
721
722         if (u.i_flags & BCH_INODE_I_SECTORS_DIRTY) {
723                 s64 sectors;
724
725                 fsck_err_on(c->sb.clean, c,
726                             "filesystem marked clean, "
727                             "but inode %llu has i_sectors dirty",
728                             inode.k->p.inode);
729
730                 bch_verbose(c, "recounting sectors for inode %llu",
731                             inode.k->p.inode);
732
733                 sectors = bch_count_inode_sectors(c, inode.k->p.inode);
734                 if (sectors < 0) {
735                         bch_err(c, "error in fs gc: error %i "
736                                 "recounting inode sectors",
737                                 (int) sectors);
738                         return sectors;
739                 }
740
741                 u.i_sectors = sectors;
742                 u.i_flags &= ~BCH_INODE_I_SECTORS_DIRTY;
743                 do_update = true;
744         }
745
746         if (i_nlink != real_i_nlink) {
747                 fsck_err_on(c->sb.clean, c,
748                             "filesystem marked clean, "
749                             "but inode %llu has wrong i_nlink "
750                             "(type %u i_nlink %u, should be %u)",
751                             inode.k->p.inode, mode_to_type(u.i_mode),
752                             i_nlink, real_i_nlink);
753
754                 bch_verbose(c, "setting inode %llu nlinks from %u to %u",
755                             inode.k->p.inode, i_nlink, real_i_nlink);
756                 u.i_nlink = real_i_nlink - nlink_bias(u.i_mode);;
757                 do_update = true;
758         }
759
760         if (do_update) {
761                 struct bkey_inode_buf p;
762
763                 bch_inode_pack(&p, &u);
764
765                 ret = bch_btree_insert_at(c, NULL, NULL, NULL,
766                                           BTREE_INSERT_NOFAIL,
767                                           BTREE_INSERT_ENTRY(iter, &p.inode.k_i));
768                 if (ret && ret != -EINTR)
769                         bch_err(c, "error in fs gc: error %i "
770                                 "updating inode", ret);
771         }
772 fsck_err:
773         return ret;
774 }
775
776 noinline_for_stack
777 static int bch_gc_walk_inodes(struct cache_set *c,
778                               struct bch_inode_unpacked *lostfound_inode,
779                               struct nlinks *links,
780                               u64 range_start, u64 range_end)
781 {
782         struct btree_iter iter;
783         struct bkey_s_c k;
784         struct nlink *link, zero_links = { 0, 0 };
785         struct genradix_iter nlinks_iter;
786         int ret = 0, ret2 = 0;
787         u64 nlinks_pos;
788
789         bch_btree_iter_init(&iter, c, BTREE_ID_INODES, POS(range_start, 0));
790         genradix_iter_init(&nlinks_iter);
791
792         while ((k = bch_btree_iter_peek(&iter)).k &&
793                !btree_iter_err(k)) {
794 peek_nlinks:    link = genradix_iter_peek(&nlinks_iter, links);
795
796                 if (!link && (!k.k || iter.pos.inode >= range_end))
797                         break;
798
799                 nlinks_pos = range_start + nlinks_iter.pos;
800                 if (iter.pos.inode > nlinks_pos) {
801                         /* Should have been caught by dirents pass: */
802                         need_fsck_err_on(link && link->count, c,
803                                 "missing inode %llu (nlink %u)",
804                                 nlinks_pos, link->count);
805                         genradix_iter_advance(&nlinks_iter, links);
806                         goto peek_nlinks;
807                 }
808
809                 if (iter.pos.inode < nlinks_pos || !link)
810                         link = &zero_links;
811
812                 if (k.k && k.k->type == BCH_INODE_FS) {
813                         /*
814                          * Avoid potential deadlocks with iter for
815                          * truncate/rm/etc.:
816                          */
817                         bch_btree_iter_unlock(&iter);
818
819                         ret = bch_gc_do_inode(c, lostfound_inode, &iter,
820                                               bkey_s_c_to_inode(k), *link);
821                         if (ret == -EINTR)
822                                 continue;
823                         if (ret)
824                                 break;
825
826                         if (link->count)
827                                 atomic_long_inc(&c->nr_inodes);
828                 } else {
829                         /* Should have been caught by dirents pass: */
830                         need_fsck_err_on(link->count, c,
831                                 "missing inode %llu (nlink %u)",
832                                 nlinks_pos, link->count);
833                 }
834
835                 if (nlinks_pos == iter.pos.inode)
836                         genradix_iter_advance(&nlinks_iter, links);
837
838                 bch_btree_iter_advance_pos(&iter);
839                 bch_btree_iter_cond_resched(&iter);
840         }
841 fsck_err:
842         ret2 = bch_btree_iter_unlock(&iter);
843         if (ret2)
844                 bch_err(c, "error in fs gc: btree error %i while walking inodes", ret2);
845
846         return ret ?: ret2;
847 }
848
849 noinline_for_stack
850 static int check_inode_nlinks(struct cache_set *c,
851                               struct bch_inode_unpacked *lostfound_inode)
852 {
853         struct nlinks links;
854         u64 this_iter_range_start, next_iter_range_start = 0;
855         int ret = 0;
856
857         genradix_init(&links);
858
859         do {
860                 this_iter_range_start = next_iter_range_start;
861                 next_iter_range_start = U64_MAX;
862
863                 ret = bch_gc_walk_dirents(c, &links,
864                                           this_iter_range_start,
865                                           &next_iter_range_start);
866                 if (ret)
867                         break;
868
869                 ret = bch_gc_walk_inodes(c, lostfound_inode, &links,
870                                          this_iter_range_start,
871                                          next_iter_range_start);
872                 if (ret)
873                         break;
874
875                 genradix_free(&links);
876         } while (next_iter_range_start != U64_MAX);
877
878         genradix_free(&links);
879
880         return ret;
881 }
882
883 /*
884  * Checks for inconsistencies that shouldn't happen, unless we have a bug.
885  * Doesn't fix them yet, mainly because they haven't yet been observed:
886  */
887 int bch_fsck(struct cache_set *c, bool full_fsck)
888 {
889         struct bch_inode_unpacked root_inode, lostfound_inode;
890         int ret;
891
892         ret = check_root(c, &root_inode);
893         if (ret)
894                 return ret;
895
896         ret = check_lostfound(c, &root_inode, &lostfound_inode);
897         if (ret)
898                 return ret;
899
900         if (!full_fsck)
901                 goto check_nlinks;
902
903         ret = check_extents(c);
904         if (ret)
905                 return ret;
906
907         ret = check_dirents(c);
908         if (ret)
909                 return ret;
910
911         ret = check_xattrs(c);
912         if (ret)
913                 return ret;
914
915         ret = check_directory_structure(c, &lostfound_inode);
916         if (ret)
917                 return ret;
918 check_nlinks:
919         ret = check_inode_nlinks(c, &lostfound_inode);
920         if (ret)
921                 return ret;
922
923         return 0;
924 }