]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/dir2.c
xfsprogs: Release v6.7.0
[thirdparty/xfsprogs-dev.git] / repair / dir2.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "avl.h"
9 #include "globals.h"
10 #include "incore.h"
11 #include "err_protos.h"
12 #include "dinode.h"
13 #include "dir2.h"
14 #include "bmap.h"
15 #include "da_util.h"
16 #include "prefetch.h"
17 #include "progress.h"
18
19 /*
20 * Known bad inode list. These are seen when the leaf and node
21 * block linkages are incorrect.
22 */
23 typedef struct dir2_bad {
24 xfs_ino_t ino;
25 struct dir2_bad *next;
26 } dir2_bad_t;
27
28 static dir2_bad_t *dir2_bad_list;
29
30 static void
31 dir2_add_badlist(
32 xfs_ino_t ino)
33 {
34 dir2_bad_t *l;
35
36 if ((l = malloc(sizeof(dir2_bad_t))) == NULL) {
37 do_error(
38 _("malloc failed (%zu bytes) dir2_add_badlist:ino %" PRIu64 "\n"),
39 sizeof(dir2_bad_t), ino);
40 exit(1);
41 }
42 l->next = dir2_bad_list;
43 dir2_bad_list = l;
44 l->ino = ino;
45 }
46
47 static int
48 dir_namecheck(
49 uint8_t *name,
50 int length)
51 {
52 return namecheck((char *)name, length, true);
53 }
54
55 int
56 dir2_is_badino(
57 xfs_ino_t ino)
58 {
59 dir2_bad_t *l;
60
61 for (l = dir2_bad_list; l; l = l->next)
62 if (l->ino == ino)
63 return 1;
64 return 0;
65 }
66
67 /*
68 * Fix up a shortform directory which was in long form (i8count set)
69 * and is now in short form (i8count clear).
70 * Return pointer to the end of the data when done.
71 */
72 void
73 process_sf_dir2_fixi8(
74 struct xfs_mount *mp,
75 struct xfs_dir2_sf_hdr *sfp,
76 xfs_dir2_sf_entry_t **next_sfep)
77 {
78 xfs_ino_t ino;
79 struct xfs_dir2_sf_hdr *newsfp;
80 xfs_dir2_sf_entry_t *newsfep;
81 struct xfs_dir2_sf_hdr *oldsfp;
82 xfs_dir2_sf_entry_t *oldsfep;
83 int oldsize;
84
85 newsfp = sfp;
86 oldsize = (intptr_t)*next_sfep - (intptr_t)sfp;
87 oldsfp = malloc(oldsize);
88 if (oldsfp == NULL) {
89 do_error(_("couldn't malloc dir2 shortform copy\n"));
90 exit(1);
91 }
92 memmove(oldsfp, newsfp, oldsize);
93 newsfp->count = oldsfp->count;
94 newsfp->i8count = 0;
95 ino = M_DIROPS(mp)->sf_get_parent_ino(sfp);
96 M_DIROPS(mp)->sf_put_parent_ino(newsfp, ino);
97 oldsfep = xfs_dir2_sf_firstentry(oldsfp);
98 newsfep = xfs_dir2_sf_firstentry(newsfp);
99 while ((int)((char *)oldsfep - (char *)oldsfp) < oldsize) {
100 newsfep->namelen = oldsfep->namelen;
101 xfs_dir2_sf_put_offset(newsfep,
102 xfs_dir2_sf_get_offset(oldsfep));
103 memmove(newsfep->name, oldsfep->name, newsfep->namelen);
104 ino = M_DIROPS(mp)->sf_get_ino(oldsfp, oldsfep);
105 M_DIROPS(mp)->sf_put_ino(newsfp, newsfep, ino);
106 oldsfep = M_DIROPS(mp)->sf_nextentry(oldsfp, oldsfep);
107 newsfep = M_DIROPS(mp)->sf_nextentry(newsfp, newsfep);
108 }
109 *next_sfep = newsfep;
110 free(oldsfp);
111 }
112
113 /*
114 * Regenerate legal (minimal) offsets for the shortform directory.
115 */
116 static void
117 process_sf_dir2_fixoff(
118 xfs_mount_t *mp,
119 xfs_dinode_t *dip)
120 {
121 int i;
122 int offset;
123 xfs_dir2_sf_entry_t *sfep;
124 struct xfs_dir2_sf_hdr *sfp;
125
126 sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
127 sfep = xfs_dir2_sf_firstentry(sfp);
128 offset = M_DIROPS(mp)->data_first_offset;
129
130 for (i = 0; i < sfp->count; i++) {
131 xfs_dir2_sf_put_offset(sfep, offset);
132 offset += M_DIROPS(mp)->data_entsize(sfep->namelen);
133 sfep = M_DIROPS(mp)->sf_nextentry(sfp, sfep);
134 }
135 }
136
137 /*
138 * this routine performs inode discovery and tries to fix things
139 * in place. available redundancy -- inode data size should match
140 * used directory space in inode.
141 * a non-zero return value means the directory is bogus and should be blasted.
142 */
143 /* ARGSUSED */
144 static int
145 process_sf_dir2(
146 xfs_mount_t *mp,
147 xfs_ino_t ino,
148 xfs_dinode_t *dip,
149 int ino_discovery,
150 int *dino_dirty, /* out - 1 if dinode buffer dirty */
151 char *dirname, /* directory pathname */
152 xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */
153 int *repair) /* out - 1 if dir was fixed up */
154 {
155 int bad_offset;
156 int bad_sfnamelen;
157 int i;
158 int i8;
159 int64_t ino_dir_size;
160 int ino_off;
161 ino_tree_node_t *irec_p;
162 int junkit;
163 char *junkreason = NULL;
164 xfs_ino_t lino;
165 int max_size;
166 char name[MAXNAMELEN + 1];
167 int namelen;
168 xfs_dir2_sf_entry_t *next_sfep;
169 int num_entries;
170 int offset;
171 struct xfs_dir2_sf_hdr *sfp;
172 xfs_dir2_sf_entry_t *sfep;
173 int tmp_elen;
174 int tmp_len;
175 xfs_dir2_sf_entry_t *tmp_sfep;
176 xfs_ino_t zero = 0;
177
178 sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
179 max_size = XFS_DFORK_DSIZE(dip, mp);
180 num_entries = sfp->count;
181 ino_dir_size = be64_to_cpu(dip->di_size);
182 offset = M_DIROPS(mp)->data_first_offset;
183 bad_offset = *repair = 0;
184
185 ASSERT(ino_dir_size <= max_size);
186
187 /*
188 * Initialize i8 based on size of parent inode number.
189 */
190 i8 = (M_DIROPS(mp)->sf_get_parent_ino(sfp) > XFS_DIR2_MAX_SHORT_INUM);
191
192 /*
193 * check for bad entry count
194 */
195 if (num_entries * M_DIROPS(mp)->sf_entsize(sfp, 1) +
196 xfs_dir2_sf_hdr_size(0) > max_size || num_entries == 0)
197 num_entries = 0xFF;
198
199 /*
200 * run through entries, stop at first bad entry, don't need
201 * to check for .. since that's encoded in its own field
202 */
203 next_sfep = xfs_dir2_sf_firstentry(sfp);
204 for (i = 0;
205 i < num_entries && ino_dir_size > (char *)next_sfep - (char *)sfp;
206 i++) {
207 tmp_sfep = NULL;
208 sfep = next_sfep;
209 junkit = 0;
210 bad_sfnamelen = 0;
211 lino = M_DIROPS(mp)->sf_get_ino(sfp, sfep);
212 /*
213 * if entry points to self, junk it since only '.' or '..'
214 * should do that and shortform dirs don't contain either
215 * entry. if inode number is invalid, trash entry.
216 * if entry points to special inodes, trash it.
217 * if inode is unknown but number is valid,
218 * add it to the list of uncertain inodes. don't
219 * have to worry about an entry pointing to a
220 * deleted lost+found inode because the entry was
221 * deleted at the same time that the inode was cleared.
222 */
223 if (lino == ino) {
224 junkit = 1;
225 junkreason = _("current");
226 } else if (verify_inum(mp, lino)) {
227 junkit = 1;
228 junkreason = _("invalid");
229 } else if (lino == mp->m_sb.sb_rbmino) {
230 junkit = 1;
231 junkreason = _("realtime bitmap");
232 } else if (lino == mp->m_sb.sb_rsumino) {
233 junkit = 1;
234 junkreason = _("realtime summary");
235 } else if (lino == mp->m_sb.sb_uquotino) {
236 junkit = 1;
237 junkreason = _("user quota");
238 } else if (lino == mp->m_sb.sb_gquotino) {
239 junkit = 1;
240 junkreason = _("group quota");
241 } else if (lino == mp->m_sb.sb_pquotino) {
242 junkit = 1;
243 junkreason = _("project quota");
244 } else if ((irec_p = find_inode_rec(mp,
245 XFS_INO_TO_AGNO(mp, lino),
246 XFS_INO_TO_AGINO(mp, lino))) != NULL) {
247 /*
248 * if inode is marked free and we're in inode
249 * discovery mode, leave the entry alone for now.
250 * if the inode turns out to be used, we'll figure
251 * that out when we scan it. If the inode really
252 * is free, we'll hit this code again in phase 4
253 * after we've finished inode discovery and blow
254 * out the entry then.
255 */
256 ino_off = XFS_INO_TO_AGINO(mp, lino) -
257 irec_p->ino_startnum;
258 ASSERT(is_inode_confirmed(irec_p, ino_off));
259 if (is_inode_free(irec_p, ino_off) && !ino_discovery) {
260 junkit = 1;
261 junkreason = _("free");
262 }
263 } else if (ino_discovery) {
264 /*
265 * put the inode on the uncertain list. we'll
266 * pull the inode off the list and check it later.
267 * if the inode turns out be bogus, we'll delete
268 * this entry in phase 6.
269 */
270 add_inode_uncertain(mp, lino, 0);
271 } else {
272 /*
273 * blow the entry out. we know about all
274 * undiscovered entries now (past inode discovery
275 * phase) so this is clearly a bogus entry.
276 */
277 junkit = 1;
278 junkreason = _("non-existent");
279 }
280 namelen = sfep->namelen;
281 if (junkit)
282 do_warn(
283 _("entry \"%*.*s\" in shortform directory %" PRIu64 " references %s inode %" PRIu64 "\n"),
284 namelen, namelen, sfep->name, ino, junkreason,
285 lino);
286
287 /* is dir namelen 0 or does this entry extend past dir size? */
288 if (namelen == 0) {
289 junkreason = _("is zero length");
290 bad_sfnamelen = 1;
291 } else if ((intptr_t) sfep - (intptr_t) sfp +
292 M_DIROPS(mp)->sf_entsize(sfp, sfep->namelen)
293 > ino_dir_size) {
294 junkreason = _("extends past end of dir");
295 bad_sfnamelen = 1;
296 }
297
298 if (bad_sfnamelen) {
299 do_warn(
300 _("entry #%d %s in shortform dir %" PRIu64),
301 i, junkreason, ino);
302 if (!no_modify)
303 do_warn(_(", junking %d entries\n"),
304 num_entries - i);
305 else
306 do_warn(_(", would junk %d entries\n"),
307 num_entries - i);
308 /*
309 * don't process the rest of the directory,
310 * break out of processing loop
311 */
312 break;
313 }
314
315 /*
316 * check for illegal chars in name.
317 * no need to check for bad length because
318 * the length value is stored in a byte
319 * so it can't be too big, it can only wrap
320 */
321 if (dir_namecheck(sfep->name, namelen)) {
322 /*
323 * junk entry
324 */
325 do_warn(
326 _("entry contains illegal character in shortform dir %" PRIu64 "\n"),
327 ino);
328 junkit = 1;
329 }
330
331 if (xfs_dir2_sf_get_offset(sfep) < offset) {
332 do_warn(
333 _("entry contains offset out of order in shortform dir %" PRIu64 "\n"),
334 ino);
335 bad_offset = 1;
336 }
337 offset = xfs_dir2_sf_get_offset(sfep) +
338 M_DIROPS(mp)->data_entsize(namelen);
339
340 /*
341 * junk the entry by copying up the rest of the
342 * fork over the current entry and decrementing
343 * the entry count. if we're in no_modify mode,
344 * just issue the warning instead. then continue
345 * the loop with the next_sfep pointer set to the
346 * correct place in the fork and other counters
347 * properly set to reflect the deletion if it
348 * happened.
349 */
350 if (junkit) {
351 memmove(name, sfep->name, namelen);
352 name[namelen] = '\0';
353
354 if (!no_modify) {
355 tmp_elen = M_DIROPS(mp)->sf_entsize(sfp,
356 sfep->namelen);
357 be64_add_cpu(&dip->di_size, -tmp_elen);
358 ino_dir_size -= tmp_elen;
359
360 tmp_sfep = (xfs_dir2_sf_entry_t *)
361 ((intptr_t) sfep + tmp_elen);
362 tmp_len = max_size - ((intptr_t) tmp_sfep
363 - (intptr_t) sfp);
364
365 memmove(sfep, tmp_sfep, tmp_len);
366
367 sfp->count -= 1;
368 num_entries--;
369 memset((void *) ((intptr_t) sfep + tmp_len), 0,
370 tmp_elen);
371
372 /*
373 * reset the tmp value to the current
374 * pointer so we'll process the entry
375 * we just moved up
376 */
377 tmp_sfep = sfep;
378
379 /*
380 * WARNING: drop the index i by one
381 * so it matches the decremented count
382 * for accurate comparisons later
383 */
384 i--;
385
386 *dino_dirty = 1;
387 *repair = 1;
388
389 do_warn(
390 _("junking entry \"%s\" in directory inode %" PRIu64 "\n"),
391 name, ino);
392 } else {
393 do_warn(
394 _("would have junked entry \"%s\" in directory inode %" PRIu64 "\n"),
395 name, ino);
396 }
397 } else if (lino > XFS_DIR2_MAX_SHORT_INUM)
398 i8++;
399 /*
400 * go onto next entry unless we've just junked an
401 * entry in which the current entry pointer points
402 * to an unprocessed entry. have to take into zero-len
403 * entries into account in no modify mode since we
404 * calculate size based on next_sfep.
405 */
406 next_sfep = (tmp_sfep == NULL)
407 ? (xfs_dir2_sf_entry_t *) ((intptr_t) sfep
408 + ((!bad_sfnamelen)
409 ? M_DIROPS(mp)->sf_entsize(sfp, sfep->namelen)
410 : M_DIROPS(mp)->sf_entsize(sfp, namelen)))
411 : tmp_sfep;
412 }
413
414 /* sync up sizes and entry counts */
415
416 if (sfp->count != i) {
417 if (no_modify) {
418 do_warn(
419 _("would have corrected entry count in directory %" PRIu64 " from %d to %d\n"),
420 ino, sfp->count, i);
421 } else {
422 do_warn(
423 _("corrected entry count in directory %" PRIu64 ", was %d, now %d\n"),
424 ino, sfp->count, i);
425 sfp->count = i;
426 *dino_dirty = 1;
427 *repair = 1;
428 }
429 }
430
431 if (sfp->i8count != i8) {
432 if (no_modify) {
433 do_warn(
434 _("would have corrected i8 count in directory %" PRIu64 " from %d to %d\n"),
435 ino, sfp->i8count, i8);
436 } else {
437 do_warn(
438 _("corrected i8 count in directory %" PRIu64 ", was %d, now %d\n"),
439 ino, sfp->i8count, i8);
440 if (i8 == 0)
441 process_sf_dir2_fixi8(mp, sfp, &next_sfep);
442 else
443 sfp->i8count = i8;
444 *dino_dirty = 1;
445 *repair = 1;
446 }
447 }
448
449 if ((intptr_t)next_sfep - (intptr_t)sfp != ino_dir_size) {
450 if (no_modify) {
451 do_warn(
452 _("would have corrected directory %" PRIu64 " size from %" PRId64 " to %" PRIdPTR "\n"),
453 ino, ino_dir_size,
454 (intptr_t)next_sfep - (intptr_t)sfp);
455 } else {
456 do_warn(
457 _("corrected directory %" PRIu64 " size, was %" PRId64 ", now %" PRIdPTR "\n"),
458 ino, ino_dir_size,
459 (intptr_t)next_sfep - (intptr_t)sfp);
460
461 dip->di_size = cpu_to_be64(
462 (intptr_t)next_sfep - (intptr_t)sfp);
463 *dino_dirty = 1;
464 *repair = 1;
465 }
466 }
467 if (offset + (sfp->count + 2) * sizeof(xfs_dir2_leaf_entry_t) +
468 sizeof(xfs_dir2_block_tail_t) > mp->m_dir_geo->blksize) {
469 do_warn(_("directory %" PRIu64 " offsets too high\n"), ino);
470 bad_offset = 1;
471 }
472 if (bad_offset) {
473 if (no_modify) {
474 do_warn(
475 _("would have corrected entry offsets in directory %" PRIu64 "\n"),
476 ino);
477 } else {
478 do_warn(
479 _("corrected entry offsets in directory %" PRIu64 "\n"),
480 ino);
481 process_sf_dir2_fixoff(mp, dip);
482 *dino_dirty = 1;
483 *repair = 1;
484 }
485 }
486
487 /*
488 * check parent (..) entry
489 */
490 *parent = M_DIROPS(mp)->sf_get_parent_ino(sfp);
491
492 /*
493 * if parent entry is bogus, null it out. we'll fix it later .
494 * If the validation fails for the root inode we fix it in
495 * the next else case.
496 */
497 if (verify_inum(mp, *parent) && ino != mp->m_sb.sb_rootino) {
498
499 do_warn(
500 _("bogus .. inode number (%" PRIu64 ") in directory inode %" PRIu64 ", "),
501 *parent, ino);
502 *parent = NULLFSINO;
503 if (!no_modify) {
504 do_warn(_("clearing inode number\n"));
505
506 M_DIROPS(mp)->sf_put_parent_ino(sfp, zero);
507 *dino_dirty = 1;
508 *repair = 1;
509 } else {
510 do_warn(_("would clear inode number\n"));
511 }
512 } else if (ino == mp->m_sb.sb_rootino && ino != *parent) {
513 /*
514 * root directories must have .. == .
515 */
516 if (!no_modify) {
517 do_warn(
518 _("corrected root directory %" PRIu64 " .. entry, was %" PRIu64 ", now %" PRIu64 "\n"),
519 ino, *parent, ino);
520 *parent = ino;
521 M_DIROPS(mp)->sf_put_parent_ino(sfp, ino);
522 *dino_dirty = 1;
523 *repair = 1;
524 } else {
525 do_warn(
526 _("would have corrected root directory %" PRIu64 " .. entry from %" PRIu64" to %" PRIu64 "\n"),
527 ino, *parent, ino);
528 }
529 } else if (ino == *parent && ino != mp->m_sb.sb_rootino) {
530 /*
531 * likewise, non-root directories can't have .. pointing
532 * to .
533 */
534 *parent = NULLFSINO;
535 do_warn(
536 _("bad .. entry in directory inode %" PRIu64 ", points to self, "),
537 ino);
538 if (!no_modify) {
539 do_warn(_("clearing inode number\n"));
540
541 M_DIROPS(mp)->sf_put_parent_ino(sfp, zero);
542 *dino_dirty = 1;
543 *repair = 1;
544 } else {
545 do_warn(_("would clear inode number\n"));
546 }
547 }
548
549 return(0);
550 }
551
552 /*
553 * Process one directory data block.
554 */
555 /* ARGSUSED */
556 static int
557 process_dir2_data(
558 xfs_mount_t *mp,
559 xfs_ino_t ino,
560 xfs_dinode_t *dip,
561 int ino_discovery,
562 char *dirname, /* directory pathname */
563 xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */
564 struct xfs_buf *bp,
565 int *dot, /* out - 1 if there is a dot, else 0 */
566 int *dotdot, /* out - 1 if there's a dotdot, else 0 */
567 xfs_dablk_t da_bno,
568 char *endptr,
569 int *dirty)
570 {
571 int badbest;
572 xfs_dir2_data_free_t *bf;
573 int clearino;
574 char *clearreason = NULL;
575 struct xfs_dir2_data_hdr *d;
576 xfs_dir2_data_entry_t *dep;
577 xfs_dir2_data_free_t *dfp;
578 xfs_dir2_data_unused_t *dup;
579 int freeseen;
580 int i;
581 int ino_off;
582 ino_tree_node_t *irec_p;
583 int junkit;
584 int lastfree;
585 int nm_illegal;
586 char *ptr;
587 xfs_ino_t ent_ino;
588
589 d = bp->b_addr;
590 bf = M_DIROPS(mp)->data_bestfree_p(d);
591 ptr = (char *)M_DIROPS(mp)->data_entry_p(d);
592 badbest = lastfree = freeseen = 0;
593 if (be16_to_cpu(bf[0].length) == 0) {
594 badbest |= be16_to_cpu(bf[0].offset) != 0;
595 freeseen |= 1 << 0;
596 }
597 if (be16_to_cpu(bf[1].length) == 0) {
598 badbest |= be16_to_cpu(bf[1].offset) != 0;
599 freeseen |= 1 << 1;
600 }
601 if (be16_to_cpu(bf[2].length) == 0) {
602 badbest |= be16_to_cpu(bf[2].offset) != 0;
603 freeseen |= 1 << 2;
604 }
605 badbest |= be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length);
606 badbest |= be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length);
607 while (ptr < endptr) {
608 dup = (xfs_dir2_data_unused_t *)ptr;
609 /*
610 * If it's unused, look for the space in the bestfree table.
611 * If we find it, account for that, else make sure it doesn't
612 * need to be there.
613 */
614 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
615 if (ptr + be16_to_cpu(dup->length) > endptr ||
616 be16_to_cpu(dup->length) == 0 ||
617 (be16_to_cpu(dup->length) & (XFS_DIR2_DATA_ALIGN - 1)))
618 break;
619 if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
620 (char *)dup - (char *)d)
621 break;
622 badbest |= lastfree != 0;
623 dfp = xfs_dir2_data_freefind(d, bf, dup);
624 if (dfp) {
625 i = dfp - bf;
626 badbest |= (freeseen & (1 << i)) != 0;
627 freeseen |= 1 << i;
628 } else
629 badbest |= be16_to_cpu(dup->length) >
630 be16_to_cpu(bf[2].length);
631 ptr += be16_to_cpu(dup->length);
632 lastfree = 1;
633 continue;
634 }
635 dep = (xfs_dir2_data_entry_t *)ptr;
636 if (ptr + M_DIROPS(mp)->data_entsize(dep->namelen) > endptr)
637 break;
638 if (be16_to_cpu(*M_DIROPS(mp)->data_entry_tag_p(dep)) !=
639 (char *)dep - (char *)d)
640 break;
641 ptr += M_DIROPS(mp)->data_entsize(dep->namelen);
642 lastfree = 0;
643 }
644 /*
645 * Dropped out before we processed everything, give up.
646 * Phase 6 will kill this block if we don't kill the inode.
647 */
648 if (ptr != endptr) {
649 do_warn(_("corrupt block %u in directory inode %" PRIu64 "\n"),
650 da_bno, ino);
651 if (!no_modify)
652 do_warn(_("\twill junk block\n"));
653 else
654 do_warn(_("\twould junk block\n"));
655 return 1;
656 }
657 ptr = (char *)M_DIROPS(mp)->data_entry_p(d);
658 /*
659 * Process the entries now.
660 */
661 while (ptr < endptr) {
662 dup = (xfs_dir2_data_unused_t *)ptr;
663 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
664 ptr += be16_to_cpu(dup->length);
665 continue;
666 }
667 dep = (xfs_dir2_data_entry_t *)ptr;
668 ent_ino = be64_to_cpu(dep->inumber);
669 clearino = 1;
670 clearreason = NULL;
671 /*
672 * We may have to blow out an entry because of bad inode
673 * numbers. Do NOT touch the name until after we've computed
674 * the hashvalue and done a namecheck() on the name.
675 *
676 * Conditions must either set clearino to zero or set
677 * clearreason why it's being cleared.
678 */
679 if (!ino_discovery && dep->name[0] == '/') {
680 /*
681 * Don't do a damned thing. We already found this
682 * (or did it ourselves) during phase 3.
683 */
684 clearino = 0;
685 } else if (verify_inum(mp, ent_ino)) {
686 /*
687 * Bad inode number. Clear the inode number and the
688 * entry will get removed later. We don't trash the
689 * directory since it's still structurally intact.
690 */
691 clearreason = _("invalid");
692 } else if (ent_ino == mp->m_sb.sb_rbmino) {
693 clearreason = _("realtime bitmap");
694 } else if (ent_ino == mp->m_sb.sb_rsumino) {
695 clearreason = _("realtime summary");
696 } else if (ent_ino == mp->m_sb.sb_uquotino) {
697 clearreason = _("user quota");
698 } else if (ent_ino == mp->m_sb.sb_gquotino) {
699 clearreason = _("group quota");
700 } else if (ent_ino == mp->m_sb.sb_pquotino) {
701 clearreason = _("project quota");
702 } else {
703 irec_p = find_inode_rec(mp,
704 XFS_INO_TO_AGNO(mp, ent_ino),
705 XFS_INO_TO_AGINO(mp, ent_ino));
706 if (irec_p == NULL) {
707 if (ino_discovery) {
708 add_inode_uncertain(mp, ent_ino, 0);
709 clearino = 0;
710 } else
711 clearreason = _("non-existent");
712 } else {
713 /*
714 * Inode recs should have only confirmed
715 * inodes in them.
716 */
717 ino_off = XFS_INO_TO_AGINO(mp, ent_ino)
718 - irec_p->ino_startnum;
719 ASSERT(is_inode_confirmed(irec_p, ino_off));
720 /*
721 * If inode is marked free and we're in inode
722 * discovery mode, leave the entry alone for
723 * now. If the inode turns out to be used,
724 * we'll figure that out when we scan it.
725 * If the inode really is free, we'll hit this
726 * code again in phase 4 after we've finished
727 * inode discovery and blow out the entry then.
728 */
729 if (!ino_discovery && is_inode_free(irec_p,
730 ino_off))
731 clearreason = _("free");
732 else
733 clearino = 0;
734 }
735 }
736 ASSERT((clearino == 0 && clearreason == NULL) ||
737 (clearino != 0 && clearreason != NULL));
738 if (clearino)
739 do_warn(
740 _("entry \"%*.*s\" at block %d offset %" PRIdPTR " in directory inode %" PRIu64
741 " references %s inode %" PRIu64 "\n"),
742 dep->namelen, dep->namelen, dep->name,
743 da_bno, (intptr_t)ptr - (intptr_t)d, ino,
744 clearreason, ent_ino);
745
746 /*
747 * We have a special dot & dotdot fixer-upper below which can
748 * sort out the proper inode number, so don't clear it.
749 */
750 if ((dep->namelen == 1 && dep->name[0] == '.') ||
751 (dep->namelen == 2 &&
752 dep->name[0] == '.' && dep->name[1] == '.')) {
753 clearino = 0;
754 clearreason = NULL;
755 }
756
757 /*
758 * If the name length is 0 (illegal) make it 1 and blast
759 * the entry.
760 */
761 if (dep->namelen == 0) {
762 do_warn(
763 _("entry at block %u offset %" PRIdPTR " in directory inode %" PRIu64
764 "has 0 namelength\n"),
765 da_bno, (intptr_t)ptr - (intptr_t)d, ino);
766 if (!no_modify)
767 dep->namelen = 1;
768 clearino = 1;
769 }
770 /*
771 * If needed to clear the inode number, do it now.
772 */
773 if (clearino) {
774 if (!no_modify) {
775 do_warn(
776 _("\tclearing inode number in entry at offset %" PRIdPTR "...\n"),
777 (intptr_t)ptr - (intptr_t)d);
778 dep->name[0] = '/';
779 *dirty = 1;
780 } else {
781 do_warn(
782 _("\twould clear inode number in entry at offset %" PRIdPTR "...\n"),
783 (intptr_t)ptr - (intptr_t)d);
784 }
785 }
786 /*
787 * Only complain about illegal names in phase 3 (when inode
788 * discovery is turned on). Otherwise, we'd complain a lot
789 * during phase 4.
790 */
791 junkit = dep->name[0] == '/';
792 nm_illegal = dir_namecheck(dep->name, dep->namelen);
793 if (ino_discovery && nm_illegal) {
794 do_warn(
795 _("entry at block %u offset %" PRIdPTR " in directory inode %" PRIu64 " has illegal name \"%*.*s\": "),
796 da_bno, (intptr_t)ptr - (intptr_t)d, ino,
797 dep->namelen, dep->namelen, dep->name);
798 junkit = 1;
799 }
800
801 /*
802 * Ensure we write back bad entries for later processing
803 */
804 if (!no_modify && dep->name[0] == '/') {
805 *dirty = 1;
806 junkit = 0;
807 }
808
809 /*
810 * Special .. entry processing.
811 */
812 if (dep->namelen == 2 &&
813 dep->name[0] == '.' && dep->name[1] == '.') {
814 if (!*dotdot) {
815 (*dotdot)++;
816 *parent = ent_ino;
817 /*
818 * What if .. == .? Legal only in the root
819 * inode. Blow out entry and set parent to
820 * NULLFSINO otherwise.
821 */
822 if (ino == ent_ino &&
823 ino != mp->m_sb.sb_rootino) {
824 *parent = NULLFSINO;
825 do_warn(
826 _("bad .. entry in directory inode %" PRIu64 ", points to self: "),
827 ino);
828 junkit = 1;
829 }
830 /*
831 * We have to make sure that . == .. in the
832 * root inode.
833 */
834 else if (ino != ent_ino &&
835 ino == mp->m_sb.sb_rootino) {
836 do_warn(
837 _("bad .. entry in root directory inode %" PRIu64 ", was %" PRIu64 ": "),
838 ino, ent_ino);
839 if (!no_modify) {
840 do_warn(_("correcting\n"));
841 dep->inumber = cpu_to_be64(ino);
842 *dirty = 1;
843 } else {
844 do_warn(_("would correct\n"));
845 }
846 *parent = ino;
847 }
848 /*
849 * Make sure our parent directory doesn't point
850 * off into space.
851 */
852 if (!junkit &&
853 *parent != NULLFSINO &&
854 !libxfs_verify_ino(mp, *parent)) {
855 do_warn(
856 _("bad .. entry in directory inode %" PRIu64 ", was %" PRIu64 ": "),
857 ino, *parent);
858 if (!no_modify) {
859 do_warn(_("correcting\n"));
860 } else {
861 do_warn(_("would correct\n"));
862 }
863 *parent = NULLFSINO;
864 }
865 }
866 /*
867 * Can't fix the directory unless we know which ..
868 * entry is the right one. Both have valid inode
869 * numbers or we wouldn't be here. So since both
870 * seem equally valid, trash this one.
871 */
872 else {
873 do_warn(
874 _("multiple .. entries in directory inode %" PRIu64 ": "),
875 ino);
876 junkit = 1;
877 }
878 }
879 /*
880 * Special . entry processing.
881 */
882 else if (dep->namelen == 1 && dep->name[0] == '.') {
883 if (!*dot) {
884 (*dot)++;
885 if (ent_ino != ino) {
886 do_warn(
887 _("bad . entry in directory inode %" PRIu64 ", was %" PRIu64 ": "),
888 ino, ent_ino);
889 if (!no_modify) {
890 do_warn(_("correcting\n"));
891 dep->inumber = cpu_to_be64(ino);
892 *dirty = 1;
893 } else {
894 do_warn(_("would correct\n"));
895 }
896 }
897 } else {
898 do_warn(
899 _("multiple . entries in directory inode %" PRIu64 ": "),
900 ino);
901 junkit = 1;
902 }
903 }
904 /*
905 * All other entries -- make sure only . references self.
906 */
907 else if (ent_ino == ino) {
908 do_warn(
909 _("entry \"%*.*s\" in directory inode %" PRIu64 " points to self: "),
910 dep->namelen, dep->namelen, dep->name, ino);
911 junkit = 1;
912 }
913 /*
914 * Clear junked entries.
915 */
916 if (junkit) {
917 if (!no_modify) {
918 dep->name[0] = '/';
919 *dirty = 1;
920 do_warn(_("clearing entry\n"));
921 } else {
922 do_warn(_("would clear entry\n"));
923 }
924 }
925 /*
926 * Advance to the next entry.
927 */
928 ptr += M_DIROPS(mp)->data_entsize(dep->namelen);
929 }
930 /*
931 * Check the bestfree table.
932 */
933 if (freeseen != 7 || badbest) {
934 do_warn(
935 _("bad bestfree table in block %u in directory inode %" PRIu64 ": "),
936 da_bno, ino);
937 if (!no_modify) {
938 do_warn(_("repairing table\n"));
939 libxfs_dir2_data_freescan_int(mp->m_dir_geo,
940 M_DIROPS(mp), d, &i);
941 *dirty = 1;
942 } else {
943 do_warn(_("would repair table\n"));
944 }
945 }
946 return 0;
947 }
948
949 /*
950 * Process a block-format directory.
951 */
952 /* ARGSUSED */
953 static int
954 process_block_dir2(
955 xfs_mount_t *mp,
956 xfs_ino_t ino,
957 xfs_dinode_t *dip,
958 int ino_discovery,
959 int *dino_dirty, /* out - 1 if dinode buffer dirty */
960 char *dirname, /* directory pathname */
961 xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */
962 blkmap_t *blkmap,
963 int *dot, /* out - 1 if there is a dot, else 0 */
964 int *dotdot, /* out - 1 if there's a dotdot, else 0 */
965 int *repair) /* out - 1 if something was fixed */
966 {
967 struct xfs_dir2_data_hdr *block;
968 xfs_dir2_leaf_entry_t *blp;
969 bmap_ext_t *bmp;
970 struct xfs_buf *bp;
971 xfs_dir2_block_tail_t *btp;
972 int nex;
973 int rval;
974 bmap_ext_t lbmp;
975 int dirty = 0;
976
977 *repair = *dot = *dotdot = 0;
978 *parent = NULLFSINO;
979 nex = blkmap_getn(blkmap, mp->m_dir_geo->datablk,
980 mp->m_dir_geo->fsbcount, &bmp, &lbmp);
981 if (nex == 0) {
982 do_warn(
983 _("block %u for directory inode %" PRIu64 " is missing\n"),
984 mp->m_dir_geo->datablk, ino);
985 return 1;
986 }
987 bp = da_read_buf(mp, nex, bmp, &xfs_dir3_block_buf_ops);
988 if (bmp != &lbmp)
989 free(bmp);
990 if (bp == NULL) {
991 do_warn(
992 _("can't read block %u for directory inode %" PRIu64 "\n"),
993 mp->m_dir_geo->datablk, ino);
994 return 1;
995 }
996 /*
997 * Verify the block
998 */
999 block = bp->b_addr;
1000 if (!(be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC ||
1001 be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC))
1002 do_warn(
1003 _("bad directory block magic # %#x in block %u for directory inode %" PRIu64 "\n"),
1004 be32_to_cpu(block->magic), mp->m_dir_geo->datablk, ino);
1005 /*
1006 * process the data area
1007 * this also checks & fixes the bestfree
1008 */
1009 btp = xfs_dir2_block_tail_p(mp->m_dir_geo, block);
1010 blp = xfs_dir2_block_leaf_p(btp);
1011 /*
1012 * Don't let this go past the end of the block.
1013 */
1014 if ((char *)blp > (char *)btp)
1015 blp = (xfs_dir2_leaf_entry_t *)btp;
1016 rval = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent,
1017 bp, dot, dotdot, mp->m_dir_geo->datablk, (char *)blp, &dirty);
1018 /* If block looks ok but CRC didn't match, make sure to recompute it. */
1019 if (!rval && bp->b_error == -EFSBADCRC)
1020 dirty = 1;
1021 if (dirty && !no_modify) {
1022 *repair = 1;
1023 libxfs_writebuf(bp, 0);
1024 } else
1025 libxfs_putbuf(bp);
1026 return rval;
1027 }
1028
1029 /*
1030 * Validates leaf contents, node format directories only.
1031 * magic number and sibling pointers checked by caller.
1032 * Returns 0 if block is ok, 1 if the block is bad.
1033 * Looking for: out of order hash values, bad stale counts.
1034 */
1035 static int
1036 process_leaf_block_dir2(
1037 xfs_mount_t *mp,
1038 xfs_dir2_leaf_t *leaf,
1039 xfs_dablk_t da_bno,
1040 xfs_ino_t ino,
1041 xfs_dahash_t last_hashval,
1042 xfs_dahash_t *next_hashval)
1043 {
1044 int i;
1045 int stale;
1046 struct xfs_dir2_leaf_entry *ents;
1047 struct xfs_dir3_icleaf_hdr leafhdr;
1048
1049 M_DIROPS(mp)->leaf_hdr_from_disk(&leafhdr, leaf);
1050 ents = M_DIROPS(mp)->leaf_ents_p(leaf);
1051
1052 for (i = stale = 0; i < leafhdr.count; i++) {
1053 if ((char *)&ents[i] >= (char *)leaf + mp->m_dir_geo->blksize) {
1054 do_warn(
1055 _("bad entry count in block %u of directory inode %" PRIu64 "\n"),
1056 da_bno, ino);
1057 return 1;
1058 }
1059 if (be32_to_cpu(ents[i].address) == XFS_DIR2_NULL_DATAPTR)
1060 stale++;
1061 else if (be32_to_cpu(ents[i].hashval) < last_hashval) {
1062 do_warn(
1063 _("bad hash ordering in block %u of directory inode %" PRIu64 "\n"),
1064 da_bno, ino);
1065 return 1;
1066 }
1067 *next_hashval = last_hashval = be32_to_cpu(ents[i].hashval);
1068 }
1069 if (stale != leafhdr.stale) {
1070 do_warn(
1071 _("bad stale count in block %u of directory inode %" PRIu64 "\n"),
1072 da_bno, ino);
1073 return 1;
1074 }
1075 return 0;
1076 }
1077
1078 /*
1079 * Returns 0 if the directory is ok, 1 if it has to be rebuilt.
1080 */
1081 static int
1082 process_leaf_level_dir2(
1083 xfs_mount_t *mp,
1084 da_bt_cursor_t *da_cursor,
1085 int *repair)
1086 {
1087 bmap_ext_t *bmp;
1088 struct xfs_buf *bp;
1089 int buf_dirty;
1090 xfs_dahash_t current_hashval;
1091 xfs_dablk_t da_bno;
1092 xfs_dahash_t greatest_hashval;
1093 xfs_ino_t ino;
1094 xfs_dir2_leaf_t *leaf;
1095 int nex;
1096 xfs_dablk_t prev_bno;
1097 bmap_ext_t lbmp;
1098 struct xfs_dir3_icleaf_hdr leafhdr;
1099
1100 da_bno = da_cursor->level[0].bno;
1101 ino = da_cursor->ino;
1102 prev_bno = 0;
1103 bmp = NULL;
1104 current_hashval = 0;
1105 greatest_hashval = 0;
1106 buf_dirty = 0;
1107
1108 do {
1109 nex = blkmap_getn(da_cursor->blkmap, da_bno,
1110 mp->m_dir_geo->fsbcount, &bmp, &lbmp);
1111 /*
1112 * Directory code uses 0 as the NULL block pointer since 0
1113 * is the root block and no directory block pointer can point
1114 * to the root block of the btree.
1115 */
1116 ASSERT(da_bno != 0);
1117
1118 if (nex == 0) {
1119 do_warn(
1120 _("can't map block %u for directory inode %" PRIu64 "\n"),
1121 da_bno, ino);
1122 goto error_out;
1123 }
1124 bp = da_read_buf(mp, nex, bmp, &xfs_dir3_leafn_buf_ops);
1125 if (bmp != &lbmp)
1126 free(bmp);
1127 bmp = NULL;
1128 if (bp == NULL) {
1129 do_warn(
1130 _("can't read file block %u for directory inode %" PRIu64 "\n"),
1131 da_bno, ino);
1132 goto error_out;
1133 }
1134 leaf = bp->b_addr;
1135 M_DIROPS(mp)->leaf_hdr_from_disk(&leafhdr, leaf);
1136 /*
1137 * Check magic number for leaf directory btree block.
1138 */
1139 if (!(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
1140 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC)) {
1141 do_warn(
1142 _("bad directory leaf magic # %#x for directory inode %" PRIu64 " block %u\n"),
1143 leafhdr.magic, ino, da_bno);
1144 libxfs_putbuf(bp);
1145 goto error_out;
1146 }
1147 buf_dirty = 0;
1148 /*
1149 * For each block, process the block, verify its path,
1150 * then get next block. Update cursor values along the way.
1151 */
1152 if (process_leaf_block_dir2(mp, leaf, da_bno, ino,
1153 current_hashval, &greatest_hashval)) {
1154 libxfs_putbuf(bp);
1155 goto error_out;
1156 }
1157 /*
1158 * Index can be set to hdr.count so match the indices of the
1159 * interior blocks -- which at the end of the block will point
1160 * to 1 after the final real entry in the block.
1161 */
1162 da_cursor->level[0].hashval = greatest_hashval;
1163 da_cursor->level[0].bp = bp;
1164 da_cursor->level[0].bno = da_bno;
1165 da_cursor->level[0].index = leafhdr.count;
1166 da_cursor->level[0].dirty = buf_dirty;
1167
1168 if (leafhdr.back != prev_bno) {
1169 do_warn(
1170 _("bad sibling back pointer for block %u in directory inode %" PRIu64 "\n"),
1171 da_bno, ino);
1172 libxfs_putbuf(bp);
1173 goto error_out;
1174 }
1175 prev_bno = da_bno;
1176 da_bno = leafhdr.forw;
1177 if (da_bno != 0) {
1178 if (verify_da_path(mp, da_cursor, 0, XFS_DATA_FORK)) {
1179 libxfs_putbuf(bp);
1180 goto error_out;
1181 }
1182 }
1183 current_hashval = greatest_hashval;
1184 /*
1185 * If block looks ok but CRC didn't match, make sure to
1186 * recompute it.
1187 */
1188 if (!no_modify && bp->b_error == -EFSBADCRC)
1189 buf_dirty = 1;
1190 ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify));
1191 if (buf_dirty && !no_modify) {
1192 *repair = 1;
1193 libxfs_writebuf(bp, 0);
1194 } else
1195 libxfs_putbuf(bp);
1196 } while (da_bno != 0);
1197 if (verify_final_da_path(mp, da_cursor, 0, XFS_DATA_FORK)) {
1198 /*
1199 * Verify the final path up (right-hand-side) if still ok.
1200 */
1201 do_warn(_("bad hash path in directory %" PRIu64 "\n"), ino);
1202 goto error_out;
1203 }
1204 /*
1205 * Redundant but just for testing.
1206 */
1207 release_da_cursor(mp, da_cursor, 0);
1208 return 0;
1209
1210 error_out:
1211 /*
1212 * Release all buffers holding interior btree blocks.
1213 */
1214 err_release_da_cursor(mp, da_cursor, 0);
1215 if (bmp && (bmp != &lbmp))
1216 free(bmp);
1217 return 1;
1218 }
1219
1220 /*
1221 * Return 1 if the directory's leaf/node space is corrupted and
1222 * needs to be rebuilt, 0 if it's ok.
1223 */
1224 static int
1225 process_node_dir2(
1226 xfs_mount_t *mp,
1227 xfs_ino_t ino,
1228 xfs_dinode_t *dip,
1229 blkmap_t *blkmap,
1230 int *repair)
1231 {
1232 xfs_dablk_t bno;
1233 da_bt_cursor_t da_cursor;
1234
1235 /*
1236 * Try again -- traverse down left-side of tree until we hit the
1237 * left-most leaf block setting up the btree cursor along the way.
1238 * Then walk the leaf blocks left-to-right, calling a parent
1239 * verification routine each time we traverse a block.
1240 */
1241 memset(&da_cursor, 0, sizeof(da_cursor));
1242 da_cursor.ino = ino;
1243 da_cursor.dip = dip;
1244 da_cursor.blkmap = blkmap;
1245
1246 /*
1247 * Now process interior node.
1248 */
1249 if (traverse_int_dablock(mp, &da_cursor, &bno, XFS_DATA_FORK) == 0)
1250 return 1;
1251
1252 /*
1253 * Skip directories with a root marked XFS_DIR2_LEAFN_MAGIC
1254 *
1255 * Be careful here: If any level of the da cursor was filled out then
1256 * the directory has a da btree containing an invalid before pointer to
1257 * dblock 0, and we should move on to rebuilding the directory. If no
1258 * levels in the da cursor got filled out, then we just have a single
1259 * leafn block and we're done.
1260 */
1261 if (bno == 0) {
1262 if (da_cursor.active > 0) {
1263 err_release_da_cursor(mp, &da_cursor, 0);
1264 return 1;
1265 } else {
1266 release_da_cursor(mp, &da_cursor, 0);
1267 return 0;
1268 }
1269 } else {
1270 /*
1271 * Now pass cursor and bno into leaf-block processing routine.
1272 * The leaf dir level routine checks the interior paths up to
1273 * the root including the final right-most path.
1274 */
1275 return process_leaf_level_dir2(mp, &da_cursor, repair);
1276 }
1277 }
1278
1279 /*
1280 * Process leaf and node directories.
1281 * Process the data blocks then, if it's a node directory, check
1282 * the consistency of those blocks.
1283 */
1284 static int
1285 process_leaf_node_dir2(
1286 xfs_mount_t *mp,
1287 xfs_ino_t ino,
1288 xfs_dinode_t *dip,
1289 int ino_discovery,
1290 char *dirname, /* directory pathname */
1291 xfs_ino_t *parent, /* out - NULLFSINO if entry not exist */
1292 blkmap_t *blkmap,
1293 int *dot, /* out - 1 if there is a dot, else 0 */
1294 int *dotdot, /* out - 1 if there's a dotdot, else 0 */
1295 int *repair, /* out - 1 if something was fixed */
1296 int isnode) /* node directory not leaf */
1297 {
1298 bmap_ext_t *bmp;
1299 struct xfs_buf *bp;
1300 struct xfs_dir2_data_hdr *data;
1301 xfs_fileoff_t dbno;
1302 int good;
1303 int i;
1304 xfs_fileoff_t ndbno;
1305 int nex;
1306 int t;
1307 bmap_ext_t lbmp;
1308 int dirty = 0;
1309
1310 *repair = *dot = *dotdot = good = 0;
1311 *parent = NULLFSINO;
1312 ndbno = NULLFILEOFF;
1313 while ((dbno = blkmap_next_off(blkmap, ndbno, &t)) < mp->m_dir_geo->leafblk) {
1314 nex = blkmap_getn(blkmap, dbno, mp->m_dir_geo->fsbcount, &bmp, &lbmp);
1315 /* Advance through map to last dfs block in this dir block */
1316 ndbno = dbno;
1317 while (ndbno < dbno + mp->m_dir_geo->fsbcount - 1) {
1318 ndbno = blkmap_next_off(blkmap, ndbno, &t);
1319 }
1320 if (nex == 0) {
1321 do_warn(
1322 _("block %" PRIu64 " for directory inode %" PRIu64 " is missing\n"),
1323 dbno, ino);
1324 continue;
1325 }
1326 bp = da_read_buf(mp, nex, bmp, &xfs_dir3_data_buf_ops);
1327 if (bmp != &lbmp)
1328 free(bmp);
1329 if (bp == NULL) {
1330 do_warn(
1331 _("can't read block %" PRIu64 " for directory inode %" PRIu64 "\n"),
1332 dbno, ino);
1333 continue;
1334 }
1335 data = bp->b_addr;
1336 if (!(be32_to_cpu(data->magic) == XFS_DIR2_DATA_MAGIC ||
1337 be32_to_cpu(data->magic) == XFS_DIR3_DATA_MAGIC))
1338 do_warn(
1339 _("bad directory block magic # %#x in block %" PRIu64 " for directory inode %" PRIu64 "\n"),
1340 be32_to_cpu(data->magic), dbno, ino);
1341 i = process_dir2_data(mp, ino, dip, ino_discovery, dirname,
1342 parent, bp, dot, dotdot, (xfs_dablk_t)dbno,
1343 (char *)data + mp->m_dir_geo->blksize, &dirty);
1344 if (i == 0) {
1345 good++;
1346 /* Maybe just CRC is wrong. Make sure we correct it. */
1347 if (bp->b_error == -EFSBADCRC)
1348 dirty = 1;
1349 }
1350 if (dirty && !no_modify) {
1351 *repair = 1;
1352 libxfs_writebuf(bp, 0);
1353 } else
1354 libxfs_putbuf(bp);
1355 }
1356 if (good == 0)
1357 return 1;
1358 if (!isnode)
1359 return 0;
1360 if (dir2_is_badino(ino))
1361 return 0;
1362
1363 if (process_node_dir2(mp, ino, dip, blkmap, repair))
1364 dir2_add_badlist(ino);
1365 return 0;
1366
1367 }
1368
1369 /*
1370 * Returns 1 if things are bad (directory needs to be junked)
1371 * and 0 if things are ok. If ino_discovery is 1, add unknown
1372 * inodes to uncertain inode list.
1373 */
1374 int
1375 process_dir2(
1376 xfs_mount_t *mp,
1377 xfs_ino_t ino,
1378 xfs_dinode_t *dip,
1379 int ino_discovery,
1380 int *dino_dirty,
1381 char *dirname,
1382 xfs_ino_t *parent,
1383 blkmap_t *blkmap)
1384 {
1385 int dot;
1386 int dotdot;
1387 xfs_fileoff_t last;
1388 int repair;
1389 int res;
1390
1391 *parent = NULLFSINO;
1392 dot = dotdot = 0;
1393 last = 0;
1394
1395 /*
1396 * branch off depending on the type of inode. This routine
1397 * is only called ONCE so all the subordinate routines will
1398 * fix '.' and junk '..' if they're bogus.
1399 */
1400 if (blkmap)
1401 last = blkmap_last_off(blkmap);
1402 if (be64_to_cpu(dip->di_size) <= XFS_DFORK_DSIZE(dip, mp) &&
1403 dip->di_format == XFS_DINODE_FMT_LOCAL) {
1404 dot = dotdot = 1;
1405 res = process_sf_dir2(mp, ino, dip, ino_discovery, dino_dirty,
1406 dirname, parent, &repair);
1407 } else if (last == mp->m_dir_geo->fsbcount &&
1408 (dip->di_format == XFS_DINODE_FMT_EXTENTS ||
1409 dip->di_format == XFS_DINODE_FMT_BTREE)) {
1410 res = process_block_dir2(mp, ino, dip, ino_discovery,
1411 dino_dirty, dirname, parent, blkmap, &dot, &dotdot,
1412 &repair);
1413 } else if (last >= mp->m_dir_geo->leafblk + mp->m_dir_geo->fsbcount &&
1414 (dip->di_format == XFS_DINODE_FMT_EXTENTS ||
1415 dip->di_format == XFS_DINODE_FMT_BTREE)) {
1416 res = process_leaf_node_dir2(mp, ino, dip, ino_discovery,
1417 dirname, parent, blkmap, &dot, &dotdot, &repair,
1418 last > mp->m_dir_geo->leafblk + mp->m_dir_geo->fsbcount);
1419 } else {
1420 do_warn(_("bad size/format for directory %" PRIu64 "\n"), ino);
1421 return 1;
1422 }
1423 /*
1424 * bad . entries in all directories will be fixed up in phase 6
1425 */
1426 if (dot == 0) {
1427 do_warn(_("no . entry for directory %" PRIu64 "\n"), ino);
1428 }
1429
1430 /*
1431 * shortform dirs always have a .. entry. .. for all longform
1432 * directories will get fixed in phase 6. .. for other shortform
1433 * dirs also get fixed there. .. for a shortform root was
1434 * fixed in place since we know what it should be
1435 */
1436 if (dotdot == 0 && ino != mp->m_sb.sb_rootino) {
1437 do_warn(_("no .. entry for directory %" PRIu64 "\n"), ino);
1438 } else if (dotdot == 0 && ino == mp->m_sb.sb_rootino) {
1439 do_warn(_("no .. entry for root directory %" PRIu64 "\n"), ino);
1440 need_root_dotdot = 1;
1441 }
1442
1443 ASSERT((ino != mp->m_sb.sb_rootino && ino != *parent) ||
1444 (ino == mp->m_sb.sb_rootino &&
1445 (ino == *parent || need_root_dotdot == 1)));
1446
1447 return res;
1448 }