]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/phase6.c
xfs_repair: warn when we would have rebuilt a directory
[thirdparty/xfsprogs-dev.git] / repair / phase6.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "threads.h"
9 #include "prefetch.h"
10 #include "avl.h"
11 #include "globals.h"
12 #include "agheader.h"
13 #include "incore.h"
14 #include "dir2.h"
15 #include "protos.h"
16 #include "err_protos.h"
17 #include "dinode.h"
18 #include "progress.h"
19 #include "versions.h"
20
21 static struct cred zerocr;
22 static struct fsxattr zerofsx;
23 static xfs_ino_t orphanage_ino;
24
25 static struct xfs_name xfs_name_dot = {(unsigned char *)".",
26 1,
27 XFS_DIR3_FT_DIR};
28
29 /*
30 * When we're checking directory inodes, we're allowed to set a directory's
31 * dotdot entry to zero to signal that the parent needs to be reconnected
32 * during phase 6. If we're handling a shortform directory the ifork
33 * verifiers will fail, so temporarily patch out this canary so that we can
34 * verify the rest of the fork and move on to fixing the dir.
35 */
36 static xfs_failaddr_t
37 phase6_verify_dir(
38 struct xfs_inode *ip)
39 {
40 struct xfs_mount *mp = ip->i_mount;
41 struct xfs_ifork *ifp;
42 struct xfs_dir2_sf_hdr *sfp;
43 xfs_failaddr_t fa;
44 xfs_ino_t old_parent;
45 bool parent_bypass = false;
46 int size;
47
48 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
49 sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data;
50 size = ifp->if_bytes;
51
52 /*
53 * If this is a shortform directory, phase4 may have set the parent
54 * inode to zero to indicate that it must be fixed. Temporarily
55 * set a valid parent so that the directory verifier will pass.
56 */
57 if (size > offsetof(struct xfs_dir2_sf_hdr, parent) &&
58 size >= xfs_dir2_sf_hdr_size(sfp->i8count)) {
59 old_parent = libxfs_dir2_sf_get_parent_ino(sfp);
60 if (old_parent == 0) {
61 libxfs_dir2_sf_put_parent_ino(sfp, mp->m_sb.sb_rootino);
62 parent_bypass = true;
63 }
64 }
65
66 fa = libxfs_default_ifork_ops.verify_dir(ip);
67
68 /* Put it back. */
69 if (parent_bypass)
70 libxfs_dir2_sf_put_parent_ino(sfp, old_parent);
71
72 return fa;
73 }
74
75 static struct xfs_ifork_ops phase6_ifork_ops = {
76 .verify_attr = xfs_attr_shortform_verify,
77 .verify_dir = phase6_verify_dir,
78 .verify_symlink = xfs_symlink_shortform_verify,
79 };
80
81 /*
82 * Data structures used to keep track of directories where the ".."
83 * entries are updated. These must be rebuilt after the initial pass
84 */
85 typedef struct dotdot_update {
86 struct list_head list;
87 ino_tree_node_t *irec;
88 xfs_agnumber_t agno;
89 int ino_offset;
90 } dotdot_update_t;
91
92 static LIST_HEAD(dotdot_update_list);
93 static int dotdot_update;
94
95 static void
96 add_dotdot_update(
97 xfs_agnumber_t agno,
98 ino_tree_node_t *irec,
99 int ino_offset)
100 {
101 dotdot_update_t *dir = malloc(sizeof(dotdot_update_t));
102
103 if (!dir)
104 do_error(_("malloc failed add_dotdot_update (%zu bytes)\n"),
105 sizeof(dotdot_update_t));
106
107 INIT_LIST_HEAD(&dir->list);
108 dir->irec = irec;
109 dir->agno = agno;
110 dir->ino_offset = ino_offset;
111
112 list_add(&dir->list, &dotdot_update_list);
113 }
114
115 /*
116 * Data structures and routines to keep track of directory entries
117 * and whether their leaf entry has been seen. Also used for name
118 * duplicate checking and rebuilding step if required.
119 */
120 typedef struct dir_hash_ent {
121 struct dir_hash_ent *nextbyaddr; /* next in addr bucket */
122 struct dir_hash_ent *nextbyhash; /* next in name bucket */
123 struct dir_hash_ent *nextbyorder; /* next in order added */
124 xfs_dahash_t hashval; /* hash value of name */
125 uint32_t address; /* offset of data entry */
126 xfs_ino_t inum; /* inode num of entry */
127 short junkit; /* name starts with / */
128 short seen; /* have seen leaf entry */
129 struct xfs_name name;
130 } dir_hash_ent_t;
131
132 typedef struct dir_hash_tab {
133 int size; /* size of hash tables */
134 int names_duped; /* 1 = ent names malloced */
135 dir_hash_ent_t *first; /* ptr to first added entry */
136 dir_hash_ent_t *last; /* ptr to last added entry */
137 dir_hash_ent_t **byhash; /* ptr to name hash buckets */
138 dir_hash_ent_t **byaddr; /* ptr to addr hash buckets */
139 } dir_hash_tab_t;
140
141 #define DIR_HASH_TAB_SIZE(n) \
142 (sizeof(dir_hash_tab_t) + (sizeof(dir_hash_ent_t *) * (n) * 2))
143 #define DIR_HASH_FUNC(t,a) ((a) % (t)->size)
144
145 /*
146 * Track the contents of the freespace table in a directory.
147 */
148 typedef struct freetab {
149 int naents; /* expected number of data blocks */
150 int nents; /* number of data blocks processed */
151 struct freetab_ent {
152 xfs_dir2_data_off_t v;
153 short s;
154 } ents[1];
155 } freetab_t;
156 #define FREETAB_SIZE(n) \
157 (offsetof(freetab_t, ents) + (sizeof(struct freetab_ent) * (n)))
158
159 #define DIR_HASH_CK_OK 0
160 #define DIR_HASH_CK_DUPLEAF 1
161 #define DIR_HASH_CK_BADHASH 2
162 #define DIR_HASH_CK_NODATA 3
163 #define DIR_HASH_CK_NOLEAF 4
164 #define DIR_HASH_CK_BADSTALE 5
165 #define DIR_HASH_CK_TOTAL 6
166
167 /*
168 * Need to handle CRC and validation errors specially here. If there is a
169 * validator error, re-read without the verifier so that we get a buffer we can
170 * check and repair. Re-attach the ops to the buffer after the read so that when
171 * it is rewritten the CRC is recalculated.
172 *
173 * If the buffer was not read, we return an error. If the buffer was read but
174 * had a CRC or corruption error, we reread it without the verifier and if it is
175 * read successfully we increment *crc_error and return 0. Otherwise we
176 * return the read error.
177 */
178 static int
179 dir_read_buf(
180 struct xfs_inode *ip,
181 xfs_dablk_t bno,
182 struct xfs_buf **bpp,
183 const struct xfs_buf_ops *ops,
184 int *crc_error)
185 {
186 int error;
187 int error2;
188
189 error = -libxfs_da_read_buf(NULL, ip, bno, 0, bpp, XFS_DATA_FORK, ops);
190
191 if (error != EFSBADCRC && error != EFSCORRUPTED)
192 return error;
193
194 error2 = -libxfs_da_read_buf(NULL, ip, bno, 0, bpp, XFS_DATA_FORK,
195 NULL);
196 if (error2)
197 return error2;
198
199 (*crc_error)++;
200 (*bpp)->b_ops = ops;
201 return 0;
202 }
203
204 /*
205 * Returns 0 if the name already exists (ie. a duplicate)
206 */
207 static int
208 dir_hash_add(
209 xfs_mount_t *mp,
210 dir_hash_tab_t *hashtab,
211 uint32_t addr,
212 xfs_ino_t inum,
213 int namelen,
214 unsigned char *name,
215 uint8_t ftype)
216 {
217 xfs_dahash_t hash = 0;
218 int byaddr;
219 int byhash = 0;
220 dir_hash_ent_t *p;
221 int dup;
222 short junk;
223 struct xfs_name xname;
224
225 ASSERT(!hashtab->names_duped);
226
227 xname.name = name;
228 xname.len = namelen;
229 xname.type = ftype;
230
231 junk = name[0] == '/';
232 byaddr = DIR_HASH_FUNC(hashtab, addr);
233 dup = 0;
234
235 if (!junk) {
236 hash = libxfs_dir2_hashname(mp, &xname);
237 byhash = DIR_HASH_FUNC(hashtab, hash);
238
239 /*
240 * search hash bucket for existing name.
241 */
242 for (p = hashtab->byhash[byhash]; p; p = p->nextbyhash) {
243 if (p->hashval == hash && p->name.len == namelen) {
244 if (memcmp(p->name.name, name, namelen) == 0) {
245 dup = 1;
246 junk = 1;
247 break;
248 }
249 }
250 }
251 }
252
253 if ((p = malloc(sizeof(*p))) == NULL)
254 do_error(_("malloc failed in dir_hash_add (%zu bytes)\n"),
255 sizeof(*p));
256
257 p->nextbyaddr = hashtab->byaddr[byaddr];
258 hashtab->byaddr[byaddr] = p;
259 if (hashtab->last)
260 hashtab->last->nextbyorder = p;
261 else
262 hashtab->first = p;
263 p->nextbyorder = NULL;
264 hashtab->last = p;
265
266 if (!(p->junkit = junk)) {
267 p->hashval = hash;
268 p->nextbyhash = hashtab->byhash[byhash];
269 hashtab->byhash[byhash] = p;
270 }
271 p->address = addr;
272 p->inum = inum;
273 p->seen = 0;
274 p->name = xname;
275
276 return !dup;
277 }
278
279 /*
280 * checks to see if any data entries are not in the leaf blocks
281 */
282 static int
283 dir_hash_unseen(
284 dir_hash_tab_t *hashtab)
285 {
286 int i;
287 dir_hash_ent_t *p;
288
289 for (i = 0; i < hashtab->size; i++) {
290 for (p = hashtab->byaddr[i]; p; p = p->nextbyaddr) {
291 if (p->seen == 0)
292 return 1;
293 }
294 }
295 return 0;
296 }
297
298 static int
299 dir_hash_check(
300 dir_hash_tab_t *hashtab,
301 xfs_inode_t *ip,
302 int seeval)
303 {
304 static char *seevalstr[DIR_HASH_CK_TOTAL];
305 static int done;
306
307 if (!done) {
308 seevalstr[DIR_HASH_CK_OK] = _("ok");
309 seevalstr[DIR_HASH_CK_DUPLEAF] = _("duplicate leaf");
310 seevalstr[DIR_HASH_CK_BADHASH] = _("hash value mismatch");
311 seevalstr[DIR_HASH_CK_NODATA] = _("no data entry");
312 seevalstr[DIR_HASH_CK_NOLEAF] = _("no leaf entry");
313 seevalstr[DIR_HASH_CK_BADSTALE] = _("bad stale count");
314 done = 1;
315 }
316
317 if (seeval == DIR_HASH_CK_OK && dir_hash_unseen(hashtab))
318 seeval = DIR_HASH_CK_NOLEAF;
319 if (seeval == DIR_HASH_CK_OK)
320 return 0;
321 do_warn(_("bad hash table for directory inode %" PRIu64 " (%s): "),
322 ip->i_ino, seevalstr[seeval]);
323 if (!no_modify)
324 do_warn(_("rebuilding\n"));
325 else
326 do_warn(_("would rebuild\n"));
327 return 1;
328 }
329
330 static void
331 dir_hash_done(
332 dir_hash_tab_t *hashtab)
333 {
334 int i;
335 dir_hash_ent_t *n;
336 dir_hash_ent_t *p;
337
338 for (i = 0; i < hashtab->size; i++) {
339 for (p = hashtab->byaddr[i]; p; p = n) {
340 n = p->nextbyaddr;
341 if (hashtab->names_duped)
342 free((void *)p->name.name);
343 free(p);
344 }
345 }
346 free(hashtab);
347 }
348
349 static dir_hash_tab_t *
350 dir_hash_init(
351 xfs_fsize_t size)
352 {
353 dir_hash_tab_t *hashtab;
354 int hsize;
355
356 hsize = size / (16 * 4);
357 if (hsize > 65536)
358 hsize = 63336;
359 else if (hsize < 16)
360 hsize = 16;
361 if ((hashtab = calloc(DIR_HASH_TAB_SIZE(hsize), 1)) == NULL)
362 do_error(_("calloc failed in dir_hash_init\n"));
363 hashtab->size = hsize;
364 hashtab->byhash = (dir_hash_ent_t**)((char *)hashtab +
365 sizeof(dir_hash_tab_t));
366 hashtab->byaddr = (dir_hash_ent_t**)((char *)hashtab +
367 sizeof(dir_hash_tab_t) + sizeof(dir_hash_ent_t*) * hsize);
368 return hashtab;
369 }
370
371 static int
372 dir_hash_see(
373 dir_hash_tab_t *hashtab,
374 xfs_dahash_t hash,
375 xfs_dir2_dataptr_t addr)
376 {
377 int i;
378 dir_hash_ent_t *p;
379
380 i = DIR_HASH_FUNC(hashtab, addr);
381 for (p = hashtab->byaddr[i]; p; p = p->nextbyaddr) {
382 if (p->address != addr)
383 continue;
384 if (p->seen)
385 return DIR_HASH_CK_DUPLEAF;
386 if (p->junkit == 0 && p->hashval != hash)
387 return DIR_HASH_CK_BADHASH;
388 p->seen = 1;
389 return DIR_HASH_CK_OK;
390 }
391 return DIR_HASH_CK_NODATA;
392 }
393
394 static void
395 dir_hash_update_ftype(
396 dir_hash_tab_t *hashtab,
397 xfs_dir2_dataptr_t addr,
398 uint8_t ftype)
399 {
400 int i;
401 dir_hash_ent_t *p;
402
403 i = DIR_HASH_FUNC(hashtab, addr);
404 for (p = hashtab->byaddr[i]; p; p = p->nextbyaddr) {
405 if (p->address != addr)
406 continue;
407 p->name.type = ftype;
408 }
409 }
410
411 /*
412 * checks to make sure leafs match a data entry, and that the stale
413 * count is valid.
414 */
415 static int
416 dir_hash_see_all(
417 dir_hash_tab_t *hashtab,
418 xfs_dir2_leaf_entry_t *ents,
419 int count,
420 int stale)
421 {
422 int i;
423 int j;
424 int rval;
425
426 for (i = j = 0; i < count; i++) {
427 if (be32_to_cpu(ents[i].address) == XFS_DIR2_NULL_DATAPTR) {
428 j++;
429 continue;
430 }
431 rval = dir_hash_see(hashtab, be32_to_cpu(ents[i].hashval),
432 be32_to_cpu(ents[i].address));
433 if (rval != DIR_HASH_CK_OK)
434 return rval;
435 }
436 return j == stale ? DIR_HASH_CK_OK : DIR_HASH_CK_BADSTALE;
437 }
438
439 /*
440 * Convert name pointers into locally allocated memory.
441 * This must only be done after all the entries have been added.
442 */
443 static void
444 dir_hash_dup_names(dir_hash_tab_t *hashtab)
445 {
446 unsigned char *name;
447 dir_hash_ent_t *p;
448
449 if (hashtab->names_duped)
450 return;
451
452 for (p = hashtab->first; p; p = p->nextbyorder) {
453 name = malloc(p->name.len);
454 memcpy(name, p->name.name, p->name.len);
455 p->name.name = name;
456 }
457 hashtab->names_duped = 1;
458 }
459
460 /*
461 * Given a block number in a fork, return the next valid block number
462 * (not a hole).
463 * If this is the last block number then NULLFILEOFF is returned.
464 *
465 * This was originally in the kernel, but only used in xfs_repair.
466 */
467 static int
468 bmap_next_offset(
469 xfs_trans_t *tp, /* transaction pointer */
470 xfs_inode_t *ip, /* incore inode */
471 xfs_fileoff_t *bnop, /* current block */
472 int whichfork) /* data or attr fork */
473 {
474 xfs_fileoff_t bno; /* current block */
475 int error; /* error return value */
476 xfs_bmbt_irec_t got; /* current extent value */
477 struct xfs_ifork *ifp; /* inode fork pointer */
478 struct xfs_iext_cursor icur;
479
480 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
481 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
482 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
483 return EIO;
484 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
485 *bnop = NULLFILEOFF;
486 return 0;
487 }
488 ifp = XFS_IFORK_PTR(ip, whichfork);
489 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
490 (error = -libxfs_iread_extents(tp, ip, whichfork)))
491 return error;
492 bno = *bnop + 1;
493 if (!libxfs_iext_lookup_extent(ip, ifp, bno, &icur, &got))
494 *bnop = NULLFILEOFF;
495 else
496 *bnop = got.br_startoff < bno ? bno : got.br_startoff;
497 return 0;
498 }
499
500
501 static void
502 res_failed(
503 int err)
504 {
505 if (err == ENOSPC) {
506 do_error(_("ran out of disk space!\n"));
507 } else
508 do_error(_("xfs_trans_reserve returned %d\n"), err);
509 }
510
511 static void
512 mk_rbmino(xfs_mount_t *mp)
513 {
514 xfs_trans_t *tp;
515 xfs_inode_t *ip;
516 xfs_bmbt_irec_t *ep;
517 int i;
518 int nmap;
519 int error;
520 xfs_fileoff_t bno;
521 xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
522 int times;
523 uint blocks;
524
525 /*
526 * first set up inode
527 */
528 i = -libxfs_trans_alloc_rollable(mp, 10, &tp);
529 if (i)
530 res_failed(i);
531
532 error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip,
533 &xfs_default_ifork_ops);
534 if (error) {
535 do_error(
536 _("couldn't iget realtime bitmap inode -- error - %d\n"),
537 error);
538 }
539
540 memset(&ip->i_d, 0, sizeof(ip->i_d));
541
542 VFS_I(ip)->i_mode = S_IFREG;
543 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
544 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
545
546 set_nlink(VFS_I(ip), 1); /* account for sb ptr */
547
548 times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
549 if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
550 VFS_I(ip)->i_version = 1;
551 ip->i_d.di_flags2 = 0;
552 times |= XFS_ICHGTIME_CREATE;
553 }
554 libxfs_trans_ichgtime(tp, ip, times);
555
556 /*
557 * now the ifork
558 */
559 ip->i_df.if_flags = XFS_IFEXTENTS;
560 ip->i_df.if_bytes = 0;
561 ip->i_df.if_u1.if_root = NULL;
562
563 ip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
564
565 /*
566 * commit changes
567 */
568 libxfs_trans_ijoin(tp, ip, 0);
569 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
570 error = -libxfs_trans_commit(tp);
571 if (error)
572 do_error(_("%s: commit failed, error %d\n"), __func__, error);
573
574 /*
575 * then allocate blocks for file and fill with zeroes (stolen
576 * from mkfs)
577 */
578 blocks = mp->m_sb.sb_rbmblocks +
579 XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
580 error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
581 if (error)
582 res_failed(error);
583
584 libxfs_trans_ijoin(tp, ip, 0);
585 bno = 0;
586 while (bno < mp->m_sb.sb_rbmblocks) {
587 nmap = XFS_BMAP_MAX_NMAP;
588 error = -libxfs_bmapi_write(tp, ip, bno,
589 (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno),
590 0, mp->m_sb.sb_rbmblocks, map, &nmap);
591 if (error) {
592 do_error(
593 _("couldn't allocate realtime bitmap, error = %d\n"),
594 error);
595 }
596 for (i = 0, ep = map; i < nmap; i++, ep++) {
597 libxfs_device_zero(mp->m_ddev_targp,
598 XFS_FSB_TO_DADDR(mp, ep->br_startblock),
599 XFS_FSB_TO_BB(mp, ep->br_blockcount));
600 bno += ep->br_blockcount;
601 }
602 }
603 error = -libxfs_trans_commit(tp);
604 if (error) {
605 do_error(
606 _("allocation of the realtime bitmap failed, error = %d\n"),
607 error);
608 }
609 libxfs_irele(ip);
610 }
611
612 static int
613 fill_rbmino(xfs_mount_t *mp)
614 {
615 xfs_buf_t *bp;
616 xfs_trans_t *tp;
617 xfs_inode_t *ip;
618 xfs_rtword_t *bmp;
619 int nmap;
620 int error;
621 xfs_fileoff_t bno;
622 xfs_bmbt_irec_t map;
623
624 bmp = btmcompute;
625 bno = 0;
626
627 error = -libxfs_trans_alloc_rollable(mp, 10, &tp);
628 if (error)
629 res_failed(error);
630
631 error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip,
632 &xfs_default_ifork_ops);
633 if (error) {
634 do_error(
635 _("couldn't iget realtime bitmap inode -- error - %d\n"),
636 error);
637 }
638
639 while (bno < mp->m_sb.sb_rbmblocks) {
640 /*
641 * fill the file one block at a time
642 */
643 nmap = 1;
644 error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap);
645 if (error || nmap != 1) {
646 do_error(
647 _("couldn't map realtime bitmap block %" PRIu64 ", error = %d\n"),
648 bno, error);
649 }
650
651 ASSERT(map.br_startblock != HOLESTARTBLOCK);
652
653 error = -libxfs_trans_read_buf(
654 mp, tp, mp->m_dev,
655 XFS_FSB_TO_DADDR(mp, map.br_startblock),
656 XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL);
657
658 if (error) {
659 do_warn(
660 _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime bitmap inode %" PRIu64 "\n"),
661 bno, map.br_startblock, mp->m_sb.sb_rbmino);
662 return(1);
663 }
664
665 memmove(bp->b_addr, bmp, mp->m_sb.sb_blocksize);
666
667 libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
668
669 bmp = (xfs_rtword_t *)((intptr_t) bmp + mp->m_sb.sb_blocksize);
670 bno++;
671 }
672
673 libxfs_trans_ijoin(tp, ip, 0);
674 error = -libxfs_trans_commit(tp);
675 if (error)
676 do_error(_("%s: commit failed, error %d\n"), __func__, error);
677 libxfs_irele(ip);
678 return(0);
679 }
680
681 static int
682 fill_rsumino(xfs_mount_t *mp)
683 {
684 xfs_buf_t *bp;
685 xfs_trans_t *tp;
686 xfs_inode_t *ip;
687 xfs_suminfo_t *smp;
688 int nmap;
689 int error;
690 xfs_fileoff_t bno;
691 xfs_fileoff_t end_bno;
692 xfs_bmbt_irec_t map;
693
694 smp = sumcompute;
695 bno = 0;
696 end_bno = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
697
698 error = -libxfs_trans_alloc_rollable(mp, 10, &tp);
699 if (error)
700 res_failed(error);
701
702 error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip,
703 &xfs_default_ifork_ops);
704 if (error) {
705 do_error(
706 _("couldn't iget realtime summary inode -- error - %d\n"),
707 error);
708 }
709
710 while (bno < end_bno) {
711 /*
712 * fill the file one block at a time
713 */
714 nmap = 1;
715 error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap);
716 if (error || nmap != 1) {
717 do_error(
718 _("couldn't map realtime summary inode block %" PRIu64 ", error = %d\n"),
719 bno, error);
720 }
721
722 ASSERT(map.br_startblock != HOLESTARTBLOCK);
723
724 error = -libxfs_trans_read_buf(
725 mp, tp, mp->m_dev,
726 XFS_FSB_TO_DADDR(mp, map.br_startblock),
727 XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL);
728
729 if (error) {
730 do_warn(
731 _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode %" PRIu64 "\n"),
732 bno, map.br_startblock, mp->m_sb.sb_rsumino);
733 libxfs_irele(ip);
734 return(1);
735 }
736
737 memmove(bp->b_addr, smp, mp->m_sb.sb_blocksize);
738
739 libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
740
741 smp = (xfs_suminfo_t *)((intptr_t)smp + mp->m_sb.sb_blocksize);
742 bno++;
743 }
744
745 libxfs_trans_ijoin(tp, ip, 0);
746 error = -libxfs_trans_commit(tp);
747 if (error)
748 do_error(_("%s: commit failed, error %d\n"), __func__, error);
749 libxfs_irele(ip);
750 return(0);
751 }
752
753 static void
754 mk_rsumino(xfs_mount_t *mp)
755 {
756 xfs_trans_t *tp;
757 xfs_inode_t *ip;
758 xfs_bmbt_irec_t *ep;
759 int i;
760 int nmap;
761 int error;
762 int nsumblocks;
763 xfs_fileoff_t bno;
764 xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
765 int times;
766 uint blocks;
767
768 /*
769 * first set up inode
770 */
771 i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp);
772 if (i)
773 res_failed(i);
774
775 error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip,
776 &xfs_default_ifork_ops);
777 if (error) {
778 do_error(
779 _("couldn't iget realtime summary inode -- error - %d\n"),
780 error);
781 }
782
783 memset(&ip->i_d, 0, sizeof(ip->i_d));
784
785 VFS_I(ip)->i_mode = S_IFREG;
786 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
787 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
788
789 set_nlink(VFS_I(ip), 1); /* account for sb ptr */
790
791 times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
792 if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
793 VFS_I(ip)->i_version = 1;
794 ip->i_d.di_flags2 = 0;
795 times |= XFS_ICHGTIME_CREATE;
796 }
797 libxfs_trans_ichgtime(tp, ip, times);
798
799 /*
800 * now the ifork
801 */
802 ip->i_df.if_flags = XFS_IFEXTENTS;
803 ip->i_df.if_bytes = 0;
804 ip->i_df.if_u1.if_root = NULL;
805
806 ip->i_d.di_size = mp->m_rsumsize;
807
808 /*
809 * commit changes
810 */
811 libxfs_trans_ijoin(tp, ip, 0);
812 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
813 error = -libxfs_trans_commit(tp);
814 if (error)
815 do_error(_("%s: commit failed, error %d\n"), __func__, error);
816
817 /*
818 * then allocate blocks for file and fill with zeroes (stolen
819 * from mkfs)
820 */
821 nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
822 blocks = nsumblocks + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
823 error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
824 if (error)
825 res_failed(error);
826
827 libxfs_trans_ijoin(tp, ip, 0);
828 bno = 0;
829 while (bno < nsumblocks) {
830 nmap = XFS_BMAP_MAX_NMAP;
831 error = -libxfs_bmapi_write(tp, ip, bno,
832 (xfs_extlen_t)(nsumblocks - bno),
833 0, nsumblocks, map, &nmap);
834 if (error) {
835 do_error(
836 _("couldn't allocate realtime summary inode, error = %d\n"),
837 error);
838 }
839 for (i = 0, ep = map; i < nmap; i++, ep++) {
840 libxfs_device_zero(mp->m_ddev_targp,
841 XFS_FSB_TO_DADDR(mp, ep->br_startblock),
842 XFS_FSB_TO_BB(mp, ep->br_blockcount));
843 bno += ep->br_blockcount;
844 }
845 }
846 error = -libxfs_trans_commit(tp);
847 if (error) {
848 do_error(
849 _("allocation of the realtime summary ino failed, error = %d\n"),
850 error);
851 }
852 libxfs_irele(ip);
853 }
854
855 /*
856 * makes a new root directory.
857 */
858 static void
859 mk_root_dir(xfs_mount_t *mp)
860 {
861 xfs_trans_t *tp;
862 xfs_inode_t *ip;
863 int i;
864 int error;
865 const mode_t mode = 0755;
866 ino_tree_node_t *irec;
867 int times;
868
869 ip = NULL;
870 i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp);
871 if (i)
872 res_failed(i);
873
874 error = -libxfs_iget(mp, tp, mp->m_sb.sb_rootino, 0, &ip,
875 &xfs_default_ifork_ops);
876 if (error) {
877 do_error(_("could not iget root inode -- error - %d\n"), error);
878 }
879
880 /*
881 * take care of the core -- initialization from xfs_ialloc()
882 */
883 memset(&ip->i_d, 0, sizeof(ip->i_d));
884
885 VFS_I(ip)->i_mode = mode|S_IFDIR;
886 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
887 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
888
889 set_nlink(VFS_I(ip), 2); /* account for . and .. */
890
891 times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
892 if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
893 VFS_I(ip)->i_version = 1;
894 ip->i_d.di_flags2 = 0;
895 times |= XFS_ICHGTIME_CREATE;
896 }
897 libxfs_trans_ichgtime(tp, ip, times);
898 libxfs_trans_ijoin(tp, ip, 0);
899 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
900
901 /*
902 * now the ifork
903 */
904 ip->i_df.if_flags = XFS_IFEXTENTS;
905 ip->i_df.if_bytes = 0;
906 ip->i_df.if_u1.if_root = NULL;
907
908 /*
909 * initialize the directory
910 */
911 libxfs_dir_init(tp, ip, ip);
912
913 error = -libxfs_trans_commit(tp);
914 if (error)
915 do_error(_("%s: commit failed, error %d\n"), __func__, error);
916
917 libxfs_irele(ip);
918
919 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
920 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino));
921 set_inode_isadir(irec, XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino) -
922 irec->ino_startnum);
923 }
924
925 /*
926 * orphanage name == lost+found
927 */
928 static xfs_ino_t
929 mk_orphanage(xfs_mount_t *mp)
930 {
931 xfs_ino_t ino;
932 xfs_trans_t *tp;
933 xfs_inode_t *ip;
934 xfs_inode_t *pip;
935 ino_tree_node_t *irec;
936 int ino_offset = 0;
937 int i;
938 int error;
939 const int mode = 0755;
940 int nres;
941 struct xfs_name xname;
942
943 /*
944 * check for an existing lost+found first, if it exists, return
945 * its inode. Otherwise, we can create it. Bad lost+found inodes
946 * would have been cleared in phase3 and phase4.
947 */
948
949 i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip,
950 &xfs_default_ifork_ops);
951 if (i)
952 do_error(_("%d - couldn't iget root inode to obtain %s\n"),
953 i, ORPHANAGE);
954
955 xname.name = (unsigned char *)ORPHANAGE;
956 xname.len = strlen(ORPHANAGE);
957 xname.type = XFS_DIR3_FT_DIR;
958
959 if (libxfs_dir_lookup(NULL, pip, &xname, &ino, NULL) == 0)
960 return ino;
961
962 /*
963 * could not be found, create it
964 */
965 nres = XFS_MKDIR_SPACE_RES(mp, xname.len);
966 i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir, nres, 0, 0, &tp);
967 if (i)
968 res_failed(i);
969
970 /*
971 * use iget/ijoin instead of trans_iget because the ialloc
972 * wrapper can commit the transaction and start a new one
973 */
974 /* i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip,
975 &xfs_default_ifork_ops);
976 if (i)
977 do_error(_("%d - couldn't iget root inode to make %s\n"),
978 i, ORPHANAGE);*/
979
980 error = -libxfs_inode_alloc(&tp, pip, mode|S_IFDIR,
981 1, 0, &zerocr, &zerofsx, &ip);
982 if (error) {
983 do_error(_("%s inode allocation failed %d\n"),
984 ORPHANAGE, error);
985 }
986 inc_nlink(VFS_I(ip)); /* account for . */
987 ino = ip->i_ino;
988
989 irec = find_inode_rec(mp,
990 XFS_INO_TO_AGNO(mp, ino),
991 XFS_INO_TO_AGINO(mp, ino));
992
993 if (irec == NULL) {
994 /*
995 * This inode is allocated from a newly created inode
996 * chunk and therefore did not exist when inode chunks
997 * were processed in phase3. Add this group of inodes to
998 * the entry avl tree as if they were discovered in phase3.
999 */
1000 irec = set_inode_free_alloc(mp, XFS_INO_TO_AGNO(mp, ino),
1001 XFS_INO_TO_AGINO(mp, ino));
1002 alloc_ex_data(irec);
1003
1004 for (i = 0; i < XFS_INODES_PER_CHUNK; i++)
1005 set_inode_free(irec, i);
1006 }
1007
1008 ino_offset = get_inode_offset(mp, ino, irec);
1009
1010 /*
1011 * Mark the inode allocated to lost+found as used in the AVL tree
1012 * so it is not skipped in phase 7
1013 */
1014 set_inode_used(irec, ino_offset);
1015 add_inode_ref(irec, ino_offset);
1016 add_inode_reached(irec, ino_offset);
1017
1018 /*
1019 * now that we know the transaction will stay around,
1020 * add the root inode to it
1021 */
1022 libxfs_trans_ijoin(tp, pip, 0);
1023
1024 /*
1025 * create the actual entry
1026 */
1027 error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, nres);
1028 if (error)
1029 do_error(
1030 _("can't make %s, createname error %d\n"),
1031 ORPHANAGE, error);
1032
1033 /*
1034 * bump up the link count in the root directory to account
1035 * for .. in the new directory, and update the irec copy of the
1036 * on-disk nlink so we don't fail the link count check later.
1037 */
1038 inc_nlink(VFS_I(pip));
1039 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
1040 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino));
1041 add_inode_ref(irec, 0);
1042 set_inode_disk_nlinks(irec, 0, get_inode_disk_nlinks(irec, 0) + 1);
1043
1044 libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
1045 libxfs_dir_init(tp, ip, pip);
1046 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1047 error = -libxfs_trans_commit(tp);
1048 if (error) {
1049 do_error(_("%s directory creation failed -- bmapf error %d\n"),
1050 ORPHANAGE, error);
1051 }
1052 libxfs_irele(ip);
1053 libxfs_irele(pip);
1054
1055 return(ino);
1056 }
1057
1058 /*
1059 * move a file to the orphange.
1060 */
1061 static void
1062 mv_orphanage(
1063 xfs_mount_t *mp,
1064 xfs_ino_t ino, /* inode # to be moved */
1065 int isa_dir) /* 1 if inode is a directory */
1066 {
1067 xfs_inode_t *orphanage_ip;
1068 xfs_ino_t entry_ino_num;
1069 xfs_inode_t *ino_p;
1070 xfs_trans_t *tp;
1071 int err;
1072 unsigned char fname[MAXPATHLEN + 1];
1073 int nres;
1074 int incr;
1075 ino_tree_node_t *irec;
1076 int ino_offset = 0;
1077 struct xfs_name xname;
1078
1079 xname.name = fname;
1080 xname.len = snprintf((char *)fname, sizeof(fname), "%llu",
1081 (unsigned long long)ino);
1082
1083 err = -libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip,
1084 &xfs_default_ifork_ops);
1085 if (err)
1086 do_error(_("%d - couldn't iget orphanage inode\n"), err);
1087 /*
1088 * Make sure the filename is unique in the lost+found
1089 */
1090 incr = 0;
1091 while (libxfs_dir_lookup(NULL, orphanage_ip, &xname, &entry_ino_num,
1092 NULL) == 0)
1093 xname.len = snprintf((char *)fname, sizeof(fname), "%llu.%d",
1094 (unsigned long long)ino, ++incr);
1095
1096 /* Orphans may not have a proper parent, so use custom ops here */
1097 err = -libxfs_iget(mp, NULL, ino, 0, &ino_p, &phase6_ifork_ops);
1098 if (err)
1099 do_error(_("%d - couldn't iget disconnected inode\n"), err);
1100
1101 xname.type = libxfs_mode_to_ftype(VFS_I(ino_p)->i_mode);
1102
1103 if (isa_dir) {
1104 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, orphanage_ino),
1105 XFS_INO_TO_AGINO(mp, orphanage_ino));
1106 if (irec)
1107 ino_offset = XFS_INO_TO_AGINO(mp, orphanage_ino) -
1108 irec->ino_startnum;
1109 nres = XFS_DIRENTER_SPACE_RES(mp, fnamelen) +
1110 XFS_DIRENTER_SPACE_RES(mp, 2);
1111 err = -libxfs_dir_lookup(NULL, ino_p, &xfs_name_dotdot,
1112 &entry_ino_num, NULL);
1113 if (err) {
1114 ASSERT(err == ENOENT);
1115
1116 err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_rename,
1117 nres, 0, 0, &tp);
1118 if (err)
1119 do_error(
1120 _("space reservation failed (%d), filesystem may be out of space\n"),
1121 err);
1122
1123 libxfs_trans_ijoin(tp, orphanage_ip, 0);
1124 libxfs_trans_ijoin(tp, ino_p, 0);
1125
1126 err = -libxfs_dir_createname(tp, orphanage_ip, &xname,
1127 ino, nres);
1128 if (err)
1129 do_error(
1130 _("name create failed in %s (%d), filesystem may be out of space\n"),
1131 ORPHANAGE, err);
1132
1133 if (irec)
1134 add_inode_ref(irec, ino_offset);
1135 else
1136 inc_nlink(VFS_I(orphanage_ip));
1137 libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE);
1138
1139 err = -libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot,
1140 orphanage_ino, nres);
1141 if (err)
1142 do_error(
1143 _("creation of .. entry failed (%d), filesystem may be out of space\n"),
1144 err);
1145
1146 inc_nlink(VFS_I(ino_p));
1147 libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
1148 err = -libxfs_trans_commit(tp);
1149 if (err)
1150 do_error(
1151 _("creation of .. entry failed (%d)\n"), err);
1152 } else {
1153 err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_rename,
1154 nres, 0, 0, &tp);
1155 if (err)
1156 do_error(
1157 _("space reservation failed (%d), filesystem may be out of space\n"),
1158 err);
1159
1160 libxfs_trans_ijoin(tp, orphanage_ip, 0);
1161 libxfs_trans_ijoin(tp, ino_p, 0);
1162
1163
1164 err = -libxfs_dir_createname(tp, orphanage_ip, &xname,
1165 ino, nres);
1166 if (err)
1167 do_error(
1168 _("name create failed in %s (%d), filesystem may be out of space\n"),
1169 ORPHANAGE, err);
1170
1171 if (irec)
1172 add_inode_ref(irec, ino_offset);
1173 else
1174 inc_nlink(VFS_I(orphanage_ip));
1175 libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE);
1176
1177 /*
1178 * don't replace .. value if it already points
1179 * to us. that'll pop a libxfs/kernel ASSERT.
1180 */
1181 if (entry_ino_num != orphanage_ino) {
1182 err = -libxfs_dir_replace(tp, ino_p,
1183 &xfs_name_dotdot, orphanage_ino,
1184 nres);
1185 if (err)
1186 do_error(
1187 _("name replace op failed (%d), filesystem may be out of space\n"),
1188 err);
1189 }
1190
1191 err = -libxfs_trans_commit(tp);
1192 if (err)
1193 do_error(
1194 _("orphanage name replace op failed (%d)\n"), err);
1195 }
1196
1197 } else {
1198 /*
1199 * use the remove log reservation as that's
1200 * more accurate. we're only creating the
1201 * links, we're not doing the inode allocation
1202 * also accounted for in the create
1203 */
1204 nres = XFS_DIRENTER_SPACE_RES(mp, xname.len);
1205 err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove,
1206 nres, 0, 0, &tp);
1207 if (err)
1208 do_error(
1209 _("space reservation failed (%d), filesystem may be out of space\n"),
1210 err);
1211
1212 libxfs_trans_ijoin(tp, orphanage_ip, 0);
1213 libxfs_trans_ijoin(tp, ino_p, 0);
1214
1215 err = -libxfs_dir_createname(tp, orphanage_ip, &xname, ino,
1216 nres);
1217 if (err)
1218 do_error(
1219 _("name create failed in %s (%d), filesystem may be out of space\n"),
1220 ORPHANAGE, err);
1221 ASSERT(err == 0);
1222
1223 set_nlink(VFS_I(ino_p), 1);
1224 libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
1225 err = -libxfs_trans_commit(tp);
1226 if (err)
1227 do_error(
1228 _("orphanage name create failed (%d)\n"), err);
1229 }
1230 libxfs_irele(ino_p);
1231 libxfs_irele(orphanage_ip);
1232 }
1233
1234 static int
1235 entry_junked(
1236 const char *msg,
1237 const char *iname,
1238 xfs_ino_t ino1,
1239 xfs_ino_t ino2)
1240 {
1241 do_warn(msg, iname, ino1, ino2);
1242 if (!no_modify) {
1243 if (verbose)
1244 do_warn(_(", marking entry to be junked\n"));
1245 else
1246 do_warn("\n");
1247 } else
1248 do_warn(_(", would junk entry\n"));
1249 return !no_modify;
1250 }
1251
1252 /* Find and invalidate all the directory's buffers. */
1253 static int
1254 dir_binval(
1255 struct xfs_trans *tp,
1256 struct xfs_inode *ip,
1257 int whichfork)
1258 {
1259 struct xfs_iext_cursor icur;
1260 struct xfs_bmbt_irec rec;
1261 struct xfs_ifork *ifp;
1262 struct xfs_da_geometry *geo;
1263 struct xfs_buf *bp;
1264 xfs_dablk_t dabno;
1265 int error = 0;
1266
1267 if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
1268 ip->i_d.di_format != XFS_DINODE_FMT_BTREE)
1269 return 0;
1270
1271 geo = tp->t_mountp->m_dir_geo;
1272 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1273 for_each_xfs_iext(ifp, &icur, &rec) {
1274 for (dabno = roundup(rec.br_startoff, geo->fsbcount);
1275 dabno < rec.br_startoff + rec.br_blockcount;
1276 dabno += geo->fsbcount) {
1277 bp = NULL;
1278 error = -libxfs_da_get_buf(tp, ip, dabno, &bp,
1279 whichfork);
1280 if (error)
1281 return error;
1282 if (!bp)
1283 continue;
1284 libxfs_trans_binval(tp, bp);
1285 libxfs_trans_brelse(tp, bp);
1286 }
1287 }
1288
1289 return error;
1290 }
1291
1292 /*
1293 * Unexpected failure during the rebuild will leave the entries in
1294 * lost+found on the next run
1295 */
1296
1297 static void
1298 longform_dir2_rebuild(
1299 xfs_mount_t *mp,
1300 xfs_ino_t ino,
1301 xfs_inode_t *ip,
1302 ino_tree_node_t *irec,
1303 int ino_offset,
1304 dir_hash_tab_t *hashtab)
1305 {
1306 int error;
1307 int nres;
1308 xfs_trans_t *tp;
1309 xfs_fileoff_t lastblock;
1310 xfs_inode_t pip;
1311 dir_hash_ent_t *p;
1312 int done = 0;
1313
1314 /*
1315 * trash directory completely and rebuild from scratch using the
1316 * name/inode pairs in the hash table
1317 */
1318
1319 do_warn(_("rebuilding directory inode %" PRIu64 "\n"), ino);
1320
1321 /*
1322 * first attempt to locate the parent inode, if it can't be
1323 * found, set it to the root inode and it'll be moved to the
1324 * orphanage later (the inode number here needs to be valid
1325 * for the libxfs_dir_init() call).
1326 */
1327 pip.i_ino = get_inode_parent(irec, ino_offset);
1328 if (pip.i_ino == NULLFSINO ||
1329 libxfs_dir_ino_validate(mp, pip.i_ino))
1330 pip.i_ino = mp->m_sb.sb_rootino;
1331
1332 nres = XFS_REMOVE_SPACE_RES(mp);
1333 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp);
1334 if (error)
1335 res_failed(error);
1336 libxfs_trans_ijoin(tp, ip, 0);
1337
1338 error = dir_binval(tp, ip, XFS_DATA_FORK);
1339 if (error)
1340 do_error(_("error %d invalidating directory %llu blocks\n"),
1341 error, (unsigned long long)ip->i_ino);
1342
1343 if ((error = -libxfs_bmap_last_offset(ip, &lastblock, XFS_DATA_FORK)))
1344 do_error(_("xfs_bmap_last_offset failed -- error - %d\n"),
1345 error);
1346
1347 /* free all data, leaf, node and freespace blocks */
1348 while (!done) {
1349 error = -libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA,
1350 0, &done);
1351 if (error) {
1352 do_warn(_("xfs_bunmapi failed -- error - %d\n"), error);
1353 goto out_bmap_cancel;
1354 }
1355 error = -libxfs_defer_finish(&tp);
1356 if (error) {
1357 do_warn(("defer_finish failed -- error - %d\n"), error);
1358 goto out_bmap_cancel;
1359 }
1360 /*
1361 * Close out trans and start the next one in the chain.
1362 */
1363 error = -libxfs_trans_roll_inode(&tp, ip);
1364 if (error)
1365 goto out_bmap_cancel;
1366 }
1367
1368 error = -libxfs_dir_init(tp, ip, &pip);
1369 if (error) {
1370 do_warn(_("xfs_dir_init failed -- error - %d\n"), error);
1371 goto out_bmap_cancel;
1372 }
1373
1374 error = -libxfs_trans_commit(tp);
1375 if (error)
1376 do_error(
1377 _("dir init failed (%d)\n"), error);
1378
1379 if (ino == mp->m_sb.sb_rootino)
1380 need_root_dotdot = 0;
1381
1382 /* go through the hash list and re-add the inodes */
1383
1384 for (p = hashtab->first; p; p = p->nextbyorder) {
1385
1386 if (p->name.name[0] == '/' || (p->name.name[0] == '.' &&
1387 (p->name.len == 1 || (p->name.len == 2 &&
1388 p->name.name[1] == '.'))))
1389 continue;
1390
1391 nres = XFS_CREATE_SPACE_RES(mp, p->name.len);
1392 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_create,
1393 nres, 0, 0, &tp);
1394 if (error)
1395 res_failed(error);
1396
1397 libxfs_trans_ijoin(tp, ip, 0);
1398
1399 error = -libxfs_dir_createname(tp, ip, &p->name, p->inum,
1400 nres);
1401 if (error) {
1402 do_warn(
1403 _("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"),
1404 ino, error);
1405 goto out_bmap_cancel;
1406 }
1407
1408 error = -libxfs_trans_commit(tp);
1409 if (error)
1410 do_error(
1411 _("name create failed (%d) during rebuild\n"), error);
1412 }
1413
1414 return;
1415
1416 out_bmap_cancel:
1417 libxfs_trans_cancel(tp);
1418 return;
1419 }
1420
1421
1422 /*
1423 * Kill a block in a version 2 inode.
1424 * Makes its own transaction.
1425 */
1426 static void
1427 dir2_kill_block(
1428 xfs_mount_t *mp,
1429 xfs_inode_t *ip,
1430 xfs_dablk_t da_bno,
1431 struct xfs_buf *bp)
1432 {
1433 xfs_da_args_t args;
1434 int error;
1435 int nres;
1436 xfs_trans_t *tp;
1437
1438 nres = XFS_REMOVE_SPACE_RES(mp);
1439 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp);
1440 if (error)
1441 res_failed(error);
1442 libxfs_trans_ijoin(tp, ip, 0);
1443 libxfs_trans_bjoin(tp, bp);
1444 memset(&args, 0, sizeof(args));
1445 args.dp = ip;
1446 args.trans = tp;
1447 args.whichfork = XFS_DATA_FORK;
1448 args.geo = mp->m_dir_geo;
1449 if (da_bno >= mp->m_dir_geo->leafblk && da_bno < mp->m_dir_geo->freeblk)
1450 error = -libxfs_da_shrink_inode(&args, da_bno, bp);
1451 else
1452 error = -libxfs_dir2_shrink_inode(&args,
1453 xfs_dir2_da_to_db(mp->m_dir_geo, da_bno), bp);
1454 if (error)
1455 do_error(_("shrink_inode failed inode %" PRIu64 " block %u\n"),
1456 ip->i_ino, da_bno);
1457 error = -libxfs_trans_commit(tp);
1458 if (error)
1459 do_error(
1460 _("directory shrink failed (%d)\n"), error);
1461 }
1462
1463 /*
1464 * process a data block, also checks for .. entry
1465 * and corrects it to match what we think .. should be
1466 */
1467 static void
1468 longform_dir2_entry_check_data(
1469 xfs_mount_t *mp,
1470 xfs_inode_t *ip,
1471 int *num_illegal,
1472 int *need_dot,
1473 ino_tree_node_t *current_irec,
1474 int current_ino_offset,
1475 struct xfs_buf **bpp,
1476 dir_hash_tab_t *hashtab,
1477 freetab_t **freetabp,
1478 xfs_dablk_t da_bno,
1479 int isblock)
1480 {
1481 xfs_dir2_dataptr_t addr;
1482 xfs_dir2_leaf_entry_t *blp;
1483 struct xfs_buf *bp;
1484 xfs_dir2_block_tail_t *btp;
1485 struct xfs_dir2_data_hdr *d;
1486 xfs_dir2_db_t db;
1487 xfs_dir2_data_entry_t *dep;
1488 xfs_dir2_data_unused_t *dup;
1489 struct xfs_dir2_data_free *bf;
1490 char *endptr;
1491 int error;
1492 char fname[MAXNAMELEN + 1];
1493 freetab_t *freetab;
1494 int i;
1495 int ino_offset;
1496 xfs_ino_t inum;
1497 ino_tree_node_t *irec;
1498 int junkit;
1499 int lastfree;
1500 int len;
1501 int nbad;
1502 int needlog;
1503 int needscan;
1504 xfs_ino_t parent;
1505 char *ptr;
1506 xfs_trans_t *tp;
1507 int wantmagic;
1508 struct xfs_da_args da = {
1509 .dp = ip,
1510 .geo = mp->m_dir_geo,
1511 };
1512
1513
1514 bp = *bpp;
1515 d = bp->b_addr;
1516 ptr = (char *)d + mp->m_dir_geo->data_entry_offset;
1517 nbad = 0;
1518 needscan = needlog = 0;
1519 junkit = 0;
1520 freetab = *freetabp;
1521 if (isblock) {
1522 btp = xfs_dir2_block_tail_p(mp->m_dir_geo, d);
1523 blp = xfs_dir2_block_leaf_p(btp);
1524 endptr = (char *)blp;
1525 if (endptr > (char *)btp)
1526 endptr = (char *)btp;
1527 if (xfs_sb_version_hascrc(&mp->m_sb))
1528 wantmagic = XFS_DIR3_BLOCK_MAGIC;
1529 else
1530 wantmagic = XFS_DIR2_BLOCK_MAGIC;
1531 } else {
1532 endptr = (char *)d + mp->m_dir_geo->blksize;
1533 if (xfs_sb_version_hascrc(&mp->m_sb))
1534 wantmagic = XFS_DIR3_DATA_MAGIC;
1535 else
1536 wantmagic = XFS_DIR2_DATA_MAGIC;
1537 }
1538 db = xfs_dir2_da_to_db(mp->m_dir_geo, da_bno);
1539
1540 /* check for data block beyond expected end */
1541 if (freetab->naents <= db) {
1542 struct freetab_ent e;
1543
1544 *freetabp = freetab = realloc(freetab, FREETAB_SIZE(db + 1));
1545 if (!freetab) {
1546 do_error(_("realloc failed in %s (%zu bytes)\n"),
1547 __func__, FREETAB_SIZE(db + 1));
1548 }
1549 e.v = NULLDATAOFF;
1550 e.s = 0;
1551 for (i = freetab->naents; i < db; i++)
1552 freetab->ents[i] = e;
1553 freetab->naents = db + 1;
1554 }
1555
1556 /* check the data block */
1557 while (ptr < endptr) {
1558
1559 /* check for freespace */
1560 dup = (xfs_dir2_data_unused_t *)ptr;
1561 if (XFS_DIR2_DATA_FREE_TAG == be16_to_cpu(dup->freetag)) {
1562
1563 /* check for invalid freespace length */
1564 if (ptr + be16_to_cpu(dup->length) > endptr ||
1565 be16_to_cpu(dup->length) == 0 ||
1566 (be16_to_cpu(dup->length) &
1567 (XFS_DIR2_DATA_ALIGN - 1)))
1568 break;
1569
1570 /* check for invalid tag */
1571 if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
1572 (char *)dup - (char *)d)
1573 break;
1574
1575 /* check for block with no data entries */
1576 if ((ptr == (char *)d + mp->m_dir_geo->data_entry_offset) &&
1577 (ptr + be16_to_cpu(dup->length) >= endptr)) {
1578 junkit = 1;
1579 *num_illegal += 1;
1580 break;
1581 }
1582
1583 /* continue at the end of the freespace */
1584 ptr += be16_to_cpu(dup->length);
1585 if (ptr >= endptr)
1586 break;
1587 }
1588
1589 /* validate data entry size */
1590 dep = (xfs_dir2_data_entry_t *)ptr;
1591 if (ptr + libxfs_dir2_data_entsize(mp, dep->namelen) > endptr)
1592 break;
1593 if (be16_to_cpu(*libxfs_dir2_data_entry_tag_p(mp, dep)) !=
1594 (char *)dep - (char *)d)
1595 break;
1596 ptr += libxfs_dir2_data_entsize(mp, dep->namelen);
1597 }
1598
1599 /* did we find an empty or corrupt block? */
1600 if (ptr != endptr) {
1601 if (junkit) {
1602 do_warn(
1603 _("empty data block %u in directory inode %" PRIu64 ": "),
1604 da_bno, ip->i_ino);
1605 } else {
1606 do_warn(_
1607 ("corrupt block %u in directory inode %" PRIu64 ": "),
1608 da_bno, ip->i_ino);
1609 }
1610 if (!no_modify) {
1611 do_warn(_("junking block\n"));
1612 dir2_kill_block(mp, ip, da_bno, bp);
1613 } else {
1614 do_warn(_("would junk block\n"));
1615 libxfs_buf_relse(bp);
1616 }
1617 freetab->ents[db].v = NULLDATAOFF;
1618 *bpp = NULL;
1619 return;
1620 }
1621
1622 /* update number of data blocks processed */
1623 if (freetab->nents < db + 1)
1624 freetab->nents = db + 1;
1625
1626 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, 0, 0, 0, &tp);
1627 if (error)
1628 res_failed(error);
1629 da.trans = tp;
1630 libxfs_trans_ijoin(tp, ip, 0);
1631 libxfs_trans_bjoin(tp, bp);
1632 libxfs_trans_bhold(tp, bp);
1633 if (be32_to_cpu(d->magic) != wantmagic) {
1634 do_warn(
1635 _("bad directory block magic # %#x for directory inode %" PRIu64 " block %d: "),
1636 be32_to_cpu(d->magic), ip->i_ino, da_bno);
1637 if (!no_modify) {
1638 do_warn(_("fixing magic # to %#x\n"), wantmagic);
1639 d->magic = cpu_to_be32(wantmagic);
1640 needlog = 1;
1641 } else
1642 do_warn(_("would fix magic # to %#x\n"), wantmagic);
1643 }
1644 lastfree = 0;
1645 ptr = (char *)d + mp->m_dir_geo->data_entry_offset;
1646 /*
1647 * look at each entry. reference inode pointed to by each
1648 * entry in the incore inode tree.
1649 * if not a directory, set reached flag, increment link count
1650 * if a directory and reached, mark entry as to be deleted.
1651 * if a directory, check to see if recorded parent
1652 * matches current inode #,
1653 * if so, then set reached flag, increment link count
1654 * of current and child dir inodes, push the child
1655 * directory inode onto the directory stack.
1656 * if current inode != parent, then mark entry to be deleted.
1657 */
1658 while (ptr < endptr) {
1659 dup = (xfs_dir2_data_unused_t *)ptr;
1660 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
1661 if (lastfree) {
1662 do_warn(
1663 _("directory inode %" PRIu64 " block %u has consecutive free entries: "),
1664 ip->i_ino, da_bno);
1665 if (!no_modify) {
1666
1667 do_warn(_("joining together\n"));
1668 len = be16_to_cpu(dup->length);
1669 libxfs_dir2_data_use_free(&da, bp, dup,
1670 ptr - (char *)d, len, &needlog,
1671 &needscan);
1672 libxfs_dir2_data_make_free(&da, bp,
1673 ptr - (char *)d, len, &needlog,
1674 &needscan);
1675 } else
1676 do_warn(_("would join together\n"));
1677 }
1678 ptr += be16_to_cpu(dup->length);
1679 lastfree = 1;
1680 continue;
1681 }
1682 addr = xfs_dir2_db_off_to_dataptr(mp->m_dir_geo, db,
1683 ptr - (char *)d);
1684 dep = (xfs_dir2_data_entry_t *)ptr;
1685 ptr += libxfs_dir2_data_entsize(mp, dep->namelen);
1686 inum = be64_to_cpu(dep->inumber);
1687 lastfree = 0;
1688 /*
1689 * skip bogus entries (leading '/'). they'll be deleted
1690 * later. must still log it, else we leak references to
1691 * buffers.
1692 */
1693 if (dep->name[0] == '/') {
1694 nbad++;
1695 if (!no_modify)
1696 libxfs_dir2_data_log_entry(&da, bp, dep);
1697 continue;
1698 }
1699
1700 memmove(fname, dep->name, dep->namelen);
1701 fname[dep->namelen] = '\0';
1702 ASSERT(inum != NULLFSINO);
1703
1704 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, inum),
1705 XFS_INO_TO_AGINO(mp, inum));
1706 if (irec == NULL) {
1707 nbad++;
1708 if (entry_junked(
1709 _("entry \"%s\" in directory inode %" PRIu64 " points to non-existent inode %" PRIu64 ""),
1710 fname, ip->i_ino, inum)) {
1711 dep->name[0] = '/';
1712 libxfs_dir2_data_log_entry(&da, bp, dep);
1713 }
1714 continue;
1715 }
1716 ino_offset = XFS_INO_TO_AGINO(mp, inum) - irec->ino_startnum;
1717
1718 /*
1719 * if it's a free inode, blow out the entry.
1720 * by now, any inode that we think is free
1721 * really is free.
1722 */
1723 if (is_inode_free(irec, ino_offset)) {
1724 nbad++;
1725 if (entry_junked(
1726 _("entry \"%s\" in directory inode %" PRIu64 " points to free inode %" PRIu64),
1727 fname, ip->i_ino, inum)) {
1728 dep->name[0] = '/';
1729 libxfs_dir2_data_log_entry(&da, bp, dep);
1730 }
1731 continue;
1732 }
1733
1734 /*
1735 * check if this inode is lost+found dir in the root
1736 */
1737 if (inum == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) {
1738 /*
1739 * if it's not a directory, trash it
1740 */
1741 if (!inode_isadir(irec, ino_offset)) {
1742 nbad++;
1743 if (entry_junked(
1744 _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"),
1745 ORPHANAGE, inum, ip->i_ino)) {
1746 dep->name[0] = '/';
1747 libxfs_dir2_data_log_entry(&da, bp, dep);
1748 }
1749 continue;
1750 }
1751 /*
1752 * if this is a dup, it will be picked up below,
1753 * otherwise, mark it as the orphanage for later.
1754 */
1755 if (!orphanage_ino)
1756 orphanage_ino = inum;
1757 }
1758
1759 /*
1760 * check for duplicate names in directory.
1761 */
1762 if (!dir_hash_add(mp, hashtab, addr, inum, dep->namelen,
1763 dep->name, libxfs_dir2_data_get_ftype(mp, dep))) {
1764 nbad++;
1765 if (entry_junked(
1766 _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"),
1767 fname, inum, ip->i_ino)) {
1768 dep->name[0] = '/';
1769 libxfs_dir2_data_log_entry(&da, bp, dep);
1770 }
1771 if (inum == orphanage_ino)
1772 orphanage_ino = 0;
1773 continue;
1774 }
1775
1776 /*
1777 * if just scanning to rebuild a directory due to a ".."
1778 * update, just continue
1779 */
1780 if (dotdot_update)
1781 continue;
1782
1783 /*
1784 * skip the '..' entry since it's checked when the
1785 * directory is reached by something else. if it never
1786 * gets reached, it'll be moved to the orphanage and we'll
1787 * take care of it then. If it doesn't exist at all, the
1788 * directory needs to be rebuilt first before being added
1789 * to the orphanage.
1790 */
1791 if (dep->namelen == 2 && dep->name[0] == '.' &&
1792 dep->name[1] == '.') {
1793 if (da_bno != 0) {
1794 /* ".." should be in the first block */
1795 nbad++;
1796 if (entry_junked(
1797 _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is not in the the first block"), fname,
1798 inum, ip->i_ino)) {
1799 dep->name[0] = '/';
1800 libxfs_dir2_data_log_entry(&da, bp, dep);
1801 }
1802 }
1803 continue;
1804 }
1805 ASSERT(no_modify || libxfs_verify_dir_ino(mp, inum));
1806 /*
1807 * special case the . entry. we know there's only one
1808 * '.' and only '.' points to itself because bogus entries
1809 * got trashed in phase 3 if there were > 1.
1810 * bump up link count for '.' but don't set reached
1811 * until we're actually reached by another directory
1812 * '..' is already accounted for or will be taken care
1813 * of when directory is moved to orphanage.
1814 */
1815 if (ip->i_ino == inum) {
1816 ASSERT(no_modify ||
1817 (dep->name[0] == '.' && dep->namelen == 1));
1818 add_inode_ref(current_irec, current_ino_offset);
1819 if (da_bno != 0 ||
1820 dep != (void *)d + mp->m_dir_geo->data_entry_offset) {
1821 /* "." should be the first entry */
1822 nbad++;
1823 if (entry_junked(
1824 _("entry \"%s\" in dir %" PRIu64 " is not the first entry"),
1825 fname, inum, ip->i_ino)) {
1826 dep->name[0] = '/';
1827 libxfs_dir2_data_log_entry(&da, bp, dep);
1828 }
1829 }
1830 *need_dot = 0;
1831 continue;
1832 }
1833 /*
1834 * skip entries with bogus inumbers if we're in no modify mode
1835 */
1836 if (no_modify && !libxfs_verify_dir_ino(mp, inum))
1837 continue;
1838
1839 /* validate ftype field if supported */
1840 if (xfs_sb_version_hasftype(&mp->m_sb)) {
1841 uint8_t dir_ftype;
1842 uint8_t ino_ftype;
1843
1844 dir_ftype = libxfs_dir2_data_get_ftype(mp, dep);
1845 ino_ftype = get_inode_ftype(irec, ino_offset);
1846
1847 if (dir_ftype != ino_ftype) {
1848 if (no_modify) {
1849 do_warn(
1850 _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
1851 dir_ftype, ino_ftype,
1852 ip->i_ino, inum);
1853 } else {
1854 do_warn(
1855 _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
1856 dir_ftype, ino_ftype,
1857 ip->i_ino, inum);
1858 libxfs_dir2_data_put_ftype(mp, dep, ino_ftype);
1859 libxfs_dir2_data_log_entry(&da, bp, dep);
1860 dir_hash_update_ftype(hashtab, addr,
1861 ino_ftype);
1862 }
1863 }
1864 }
1865
1866 /*
1867 * check easy case first, regular inode, just bump
1868 * the link count and continue
1869 */
1870 if (!inode_isadir(irec, ino_offset)) {
1871 add_inode_reached(irec, ino_offset);
1872 continue;
1873 }
1874 parent = get_inode_parent(irec, ino_offset);
1875 ASSERT(parent != 0);
1876 junkit = 0;
1877 /*
1878 * bump up the link counts in parent and child
1879 * directory but if the link doesn't agree with
1880 * the .. in the child, blow out the entry.
1881 * if the directory has already been reached,
1882 * blow away the entry also.
1883 */
1884 if (is_inode_reached(irec, ino_offset)) {
1885 junkit = 1;
1886 do_warn(
1887 _("entry \"%s\" in dir %" PRIu64" points to an already connected directory inode %" PRIu64 "\n"),
1888 fname, ip->i_ino, inum);
1889 } else if (parent == ip->i_ino) {
1890 add_inode_reached(irec, ino_offset);
1891 add_inode_ref(current_irec, current_ino_offset);
1892 } else if (parent == NULLFSINO) {
1893 /* ".." was missing, but this entry refers to it,
1894 so, set it as the parent and mark for rebuild */
1895 do_warn(
1896 _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"),
1897 fname, ip->i_ino, inum);
1898 set_inode_parent(irec, ino_offset, ip->i_ino);
1899 add_inode_reached(irec, ino_offset);
1900 add_inode_ref(current_irec, current_ino_offset);
1901 add_dotdot_update(XFS_INO_TO_AGNO(mp, inum), irec,
1902 ino_offset);
1903 } else {
1904 junkit = 1;
1905 do_warn(
1906 _("entry \"%s\" in dir inode %" PRIu64 " inconsistent with .. value (%" PRIu64 ") in ino %" PRIu64 "\n"),
1907 fname, ip->i_ino, parent, inum);
1908 }
1909 if (junkit) {
1910 if (inum == orphanage_ino)
1911 orphanage_ino = 0;
1912 nbad++;
1913 if (!no_modify) {
1914 dep->name[0] = '/';
1915 libxfs_dir2_data_log_entry(&da, bp, dep);
1916 if (verbose)
1917 do_warn(
1918 _("\twill clear entry \"%s\"\n"),
1919 fname);
1920 } else {
1921 do_warn(_("\twould clear entry \"%s\"\n"),
1922 fname);
1923 }
1924 }
1925 }
1926 *num_illegal += nbad;
1927 if (needscan)
1928 libxfs_dir2_data_freescan(mp, d, &i);
1929 if (needlog)
1930 libxfs_dir2_data_log_header(&da, bp);
1931 error = -libxfs_trans_commit(tp);
1932 if (error)
1933 do_error(
1934 _("directory block fixing failed (%d)\n"), error);
1935
1936 /* record the largest free space in the freetab for later checking */
1937 bf = libxfs_dir2_data_bestfree_p(mp, d);
1938 freetab->ents[db].v = be16_to_cpu(bf[0].length);
1939 freetab->ents[db].s = 0;
1940 }
1941
1942 /* check v5 metadata */
1943 static int
1944 __check_dir3_header(
1945 struct xfs_mount *mp,
1946 struct xfs_buf *bp,
1947 xfs_ino_t ino,
1948 __be64 owner,
1949 __be64 blkno,
1950 uuid_t *uuid)
1951 {
1952
1953 /* verify owner */
1954 if (be64_to_cpu(owner) != ino) {
1955 do_warn(
1956 _("expected owner inode %" PRIu64 ", got %llu, directory block %" PRIu64 "\n"),
1957 ino, (unsigned long long)be64_to_cpu(owner), bp->b_bn);
1958 return 1;
1959 }
1960 /* verify block number */
1961 if (be64_to_cpu(blkno) != bp->b_bn) {
1962 do_warn(
1963 _("expected block %" PRIu64 ", got %llu, directory inode %" PRIu64 "\n"),
1964 bp->b_bn, (unsigned long long)be64_to_cpu(blkno), ino);
1965 return 1;
1966 }
1967 /* verify uuid */
1968 if (platform_uuid_compare(uuid, &mp->m_sb.sb_meta_uuid) != 0) {
1969 do_warn(
1970 _("wrong FS UUID, directory inode %" PRIu64 " block %" PRIu64 "\n"),
1971 ino, bp->b_bn);
1972 return 1;
1973 }
1974
1975 return 0;
1976 }
1977
1978 static int
1979 check_da3_header(
1980 struct xfs_mount *mp,
1981 struct xfs_buf *bp,
1982 xfs_ino_t ino)
1983 {
1984 struct xfs_da3_blkinfo *info = bp->b_addr;
1985
1986 return __check_dir3_header(mp, bp, ino, info->owner, info->blkno,
1987 &info->uuid);
1988 }
1989
1990 static int
1991 check_dir3_header(
1992 struct xfs_mount *mp,
1993 struct xfs_buf *bp,
1994 xfs_ino_t ino)
1995 {
1996 struct xfs_dir3_blk_hdr *info = bp->b_addr;
1997
1998 return __check_dir3_header(mp, bp, ino, info->owner, info->blkno,
1999 &info->uuid);
2000 }
2001
2002 /*
2003 * Check contents of leaf-form block.
2004 */
2005 static int
2006 longform_dir2_check_leaf(
2007 xfs_mount_t *mp,
2008 xfs_inode_t *ip,
2009 dir_hash_tab_t *hashtab,
2010 freetab_t *freetab)
2011 {
2012 int badtail;
2013 __be16 *bestsp;
2014 struct xfs_buf *bp;
2015 xfs_dablk_t da_bno;
2016 int i;
2017 xfs_dir2_leaf_t *leaf;
2018 xfs_dir2_leaf_tail_t *ltp;
2019 int seeval;
2020 struct xfs_dir2_leaf_entry *ents;
2021 struct xfs_dir3_icleaf_hdr leafhdr;
2022 int error;
2023 int fixit = 0;
2024
2025 da_bno = mp->m_dir_geo->leafblk;
2026 error = dir_read_buf(ip, da_bno, &bp, &xfs_dir3_leaf1_buf_ops, &fixit);
2027 if (error == EFSBADCRC || error == EFSCORRUPTED || fixit) {
2028 do_warn(
2029 _("leaf block %u for directory inode %" PRIu64 " bad CRC\n"),
2030 da_bno, ip->i_ino);
2031 return 1;
2032 } else if (error) {
2033 do_error(
2034 _("can't read block %u for directory inode %" PRIu64 ", error %d\n"),
2035 da_bno, ip->i_ino, error);
2036 /* NOTREACHED */
2037 }
2038
2039 leaf = bp->b_addr;
2040 libxfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
2041 ents = leafhdr.ents;
2042 ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
2043 bestsp = xfs_dir2_leaf_bests_p(ltp);
2044 if (!(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
2045 leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) ||
2046 leafhdr.forw || leafhdr.back ||
2047 leafhdr.count < leafhdr.stale ||
2048 leafhdr.count > mp->m_dir_geo->leaf_max_ents ||
2049 (char *)&ents[leafhdr.count] > (char *)bestsp) {
2050 do_warn(
2051 _("leaf block %u for directory inode %" PRIu64 " bad header\n"),
2052 da_bno, ip->i_ino);
2053 libxfs_buf_relse(bp);
2054 return 1;
2055 }
2056
2057 if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) {
2058 error = check_da3_header(mp, bp, ip->i_ino);
2059 if (error) {
2060 libxfs_buf_relse(bp);
2061 return error;
2062 }
2063 }
2064
2065 seeval = dir_hash_see_all(hashtab, ents, leafhdr.count, leafhdr.stale);
2066 if (dir_hash_check(hashtab, ip, seeval)) {
2067 libxfs_buf_relse(bp);
2068 return 1;
2069 }
2070 badtail = freetab->nents != be32_to_cpu(ltp->bestcount);
2071 for (i = 0; !badtail && i < be32_to_cpu(ltp->bestcount); i++) {
2072 freetab->ents[i].s = 1;
2073 badtail = freetab->ents[i].v != be16_to_cpu(bestsp[i]);
2074 }
2075 if (badtail) {
2076 do_warn(
2077 _("leaf block %u for directory inode %" PRIu64 " bad tail\n"),
2078 da_bno, ip->i_ino);
2079 libxfs_buf_relse(bp);
2080 return 1;
2081 }
2082 libxfs_buf_relse(bp);
2083 return fixit;
2084 }
2085
2086 /*
2087 * Check contents of the node blocks (leaves)
2088 * Looks for matching hash values for the data entries.
2089 */
2090 static int
2091 longform_dir2_check_node(
2092 xfs_mount_t *mp,
2093 xfs_inode_t *ip,
2094 dir_hash_tab_t *hashtab,
2095 freetab_t *freetab)
2096 {
2097 struct xfs_buf *bp;
2098 xfs_dablk_t da_bno;
2099 xfs_dir2_db_t fdb;
2100 xfs_dir2_free_t *free;
2101 int i;
2102 xfs_dir2_leaf_t *leaf;
2103 xfs_fileoff_t next_da_bno;
2104 int seeval = 0;
2105 int used;
2106 struct xfs_dir2_leaf_entry *ents;
2107 struct xfs_dir3_icleaf_hdr leafhdr;
2108 struct xfs_dir3_icfree_hdr freehdr;
2109 __be16 *bests;
2110 int error;
2111 int fixit = 0;
2112
2113 for (da_bno = mp->m_dir_geo->leafblk, next_da_bno = 0;
2114 next_da_bno != NULLFILEOFF && da_bno < mp->m_dir_geo->freeblk;
2115 da_bno = (xfs_dablk_t)next_da_bno) {
2116 next_da_bno = da_bno + mp->m_dir_geo->fsbcount - 1;
2117 if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
2118 break;
2119
2120 /*
2121 * we need to use the da3 node verifier here as it handles the
2122 * fact that reading the leaf hash tree blocks can return either
2123 * leaf or node blocks and calls the correct verifier. If we get
2124 * a node block, then we'll skip it below based on a magic
2125 * number check.
2126 */
2127 error = dir_read_buf(ip, da_bno, &bp, &xfs_da3_node_buf_ops,
2128 &fixit);
2129 if (error) {
2130 do_warn(
2131 _("can't read leaf block %u for directory inode %" PRIu64 ", error %d\n"),
2132 da_bno, ip->i_ino, error);
2133 return 1;
2134 }
2135 leaf = bp->b_addr;
2136 libxfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
2137 ents = leafhdr.ents;
2138 if (!(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
2139 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
2140 leafhdr.magic == XFS_DA_NODE_MAGIC ||
2141 leafhdr.magic == XFS_DA3_NODE_MAGIC)) {
2142 do_warn(
2143 _("unknown magic number %#x for block %u in directory inode %" PRIu64 "\n"),
2144 leafhdr.magic, da_bno, ip->i_ino);
2145 libxfs_buf_relse(bp);
2146 return 1;
2147 }
2148
2149 /* check v5 metadata */
2150 if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
2151 leafhdr.magic == XFS_DA3_NODE_MAGIC) {
2152 error = check_da3_header(mp, bp, ip->i_ino);
2153 if (error) {
2154 libxfs_buf_relse(bp);
2155 return error;
2156 }
2157 }
2158
2159 /* ignore nodes */
2160 if (leafhdr.magic == XFS_DA_NODE_MAGIC ||
2161 leafhdr.magic == XFS_DA3_NODE_MAGIC) {
2162 libxfs_buf_relse(bp);
2163 continue;
2164 }
2165
2166 /*
2167 * If there's a validator error, we need to ensure that we got
2168 * the right ops on the buffer for when we write it back out.
2169 */
2170 bp->b_ops = &xfs_dir3_leafn_buf_ops;
2171 if (leafhdr.count > mp->m_dir_geo->leaf_max_ents ||
2172 leafhdr.count < leafhdr.stale) {
2173 do_warn(
2174 _("leaf block %u for directory inode %" PRIu64 " bad header\n"),
2175 da_bno, ip->i_ino);
2176 libxfs_buf_relse(bp);
2177 return 1;
2178 }
2179 seeval = dir_hash_see_all(hashtab, ents,
2180 leafhdr.count, leafhdr.stale);
2181 libxfs_buf_relse(bp);
2182 if (seeval != DIR_HASH_CK_OK)
2183 return 1;
2184 }
2185 if (dir_hash_check(hashtab, ip, seeval))
2186 return 1;
2187
2188 for (da_bno = mp->m_dir_geo->freeblk, next_da_bno = 0;
2189 next_da_bno != NULLFILEOFF;
2190 da_bno = (xfs_dablk_t)next_da_bno) {
2191 next_da_bno = da_bno + mp->m_dir_geo->fsbcount - 1;
2192 if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
2193 break;
2194
2195 error = dir_read_buf(ip, da_bno, &bp, &xfs_dir3_free_buf_ops,
2196 &fixit);
2197 if (error) {
2198 do_warn(
2199 _("can't read freespace block %u for directory inode %" PRIu64 ", error %d\n"),
2200 da_bno, ip->i_ino, error);
2201 return 1;
2202 }
2203 free = bp->b_addr;
2204 libxfs_dir2_free_hdr_from_disk(mp, &freehdr, free);
2205 bests = freehdr.bests;
2206 fdb = xfs_dir2_da_to_db(mp->m_dir_geo, da_bno);
2207 if (!(freehdr.magic == XFS_DIR2_FREE_MAGIC ||
2208 freehdr.magic == XFS_DIR3_FREE_MAGIC) ||
2209 freehdr.firstdb !=
2210 (fdb - xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) *
2211 mp->m_dir_geo->free_max_bests ||
2212 freehdr.nvalid < freehdr.nused) {
2213 do_warn(
2214 _("free block %u for directory inode %" PRIu64 " bad header\n"),
2215 da_bno, ip->i_ino);
2216 libxfs_buf_relse(bp);
2217 return 1;
2218 }
2219
2220 if (freehdr.magic == XFS_DIR3_FREE_MAGIC) {
2221 error = check_dir3_header(mp, bp, ip->i_ino);
2222 if (error) {
2223 libxfs_buf_relse(bp);
2224 return error;
2225 }
2226 }
2227 for (i = used = 0; i < freehdr.nvalid; i++) {
2228 if (i + freehdr.firstdb >= freetab->nents ||
2229 freetab->ents[i + freehdr.firstdb].v !=
2230 be16_to_cpu(bests[i])) {
2231 do_warn(
2232 _("free block %u entry %i for directory ino %" PRIu64 " bad\n"),
2233 da_bno, i, ip->i_ino);
2234 libxfs_buf_relse(bp);
2235 return 1;
2236 }
2237 used += be16_to_cpu(bests[i]) != NULLDATAOFF;
2238 freetab->ents[i + freehdr.firstdb].s = 1;
2239 }
2240 if (used != freehdr.nused) {
2241 do_warn(
2242 _("free block %u for directory inode %" PRIu64 " bad nused\n"),
2243 da_bno, ip->i_ino);
2244 libxfs_buf_relse(bp);
2245 return 1;
2246 }
2247 libxfs_buf_relse(bp);
2248 }
2249 for (i = 0; i < freetab->nents; i++) {
2250 if ((freetab->ents[i].s == 0) &&
2251 (freetab->ents[i].v != NULLDATAOFF)) {
2252 do_warn(
2253 _("missing freetab entry %u for directory inode %" PRIu64 "\n"),
2254 i, ip->i_ino);
2255 return 1;
2256 }
2257 }
2258 return fixit;
2259 }
2260
2261 /*
2262 * If a directory is corrupt, we need to read in as many entries as possible,
2263 * destroy the entry and create a new one with recovered name/inode pairs.
2264 * (ie. get libxfs to do all the grunt work)
2265 */
2266 static void
2267 longform_dir2_entry_check(xfs_mount_t *mp,
2268 xfs_ino_t ino,
2269 xfs_inode_t *ip,
2270 int *num_illegal,
2271 int *need_dot,
2272 ino_tree_node_t *irec,
2273 int ino_offset,
2274 dir_hash_tab_t *hashtab)
2275 {
2276 struct xfs_buf **bplist;
2277 xfs_dablk_t da_bno;
2278 freetab_t *freetab;
2279 int num_bps;
2280 int i;
2281 int isblock;
2282 int isleaf;
2283 xfs_fileoff_t next_da_bno;
2284 int seeval;
2285 int fixit = 0;
2286 xfs_dir2_db_t db;
2287 struct xfs_da_args args;
2288
2289 *need_dot = 1;
2290 freetab = malloc(FREETAB_SIZE(ip->i_d.di_size / mp->m_dir_geo->blksize));
2291 if (!freetab) {
2292 do_error(_("malloc failed in %s (%" PRId64 " bytes)\n"),
2293 __func__,
2294 FREETAB_SIZE(ip->i_d.di_size / mp->m_dir_geo->blksize));
2295 exit(1);
2296 }
2297 freetab->naents = ip->i_d.di_size / mp->m_dir_geo->blksize;
2298 freetab->nents = 0;
2299 for (i = 0; i < freetab->naents; i++) {
2300 freetab->ents[i].v = NULLDATAOFF;
2301 freetab->ents[i].s = 0;
2302 }
2303 num_bps = freetab->naents;
2304 bplist = calloc(num_bps, sizeof(struct xfs_buf*));
2305 if (!bplist)
2306 do_error(_("calloc failed in %s (%zu bytes)\n"),
2307 __func__, num_bps * sizeof(struct xfs_buf*));
2308
2309 /* is this a block, leaf, or node directory? */
2310 args.dp = ip;
2311 args.geo = mp->m_dir_geo;
2312 libxfs_dir2_isblock(&args, &isblock);
2313 libxfs_dir2_isleaf(&args, &isleaf);
2314
2315 /* check directory "data" blocks (ie. name/inode pairs) */
2316 for (da_bno = 0, next_da_bno = 0;
2317 next_da_bno != NULLFILEOFF && da_bno < mp->m_dir_geo->leafblk;
2318 da_bno = (xfs_dablk_t)next_da_bno) {
2319 const struct xfs_buf_ops *ops;
2320 int error;
2321 struct xfs_dir2_data_hdr *d;
2322
2323 next_da_bno = da_bno + mp->m_dir_geo->fsbcount - 1;
2324 if (bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK)) {
2325 /*
2326 * if this is the first block, there isn't anything we
2327 * can recover so we just trash it.
2328 */
2329 if (da_bno == 0) {
2330 fixit++;
2331 goto out_fix;
2332 }
2333 break;
2334 }
2335
2336 db = xfs_dir2_da_to_db(mp->m_dir_geo, da_bno);
2337 if (db >= num_bps) {
2338 int last_size = num_bps;
2339
2340 /* more data blocks than expected */
2341 num_bps = db + 1;
2342 bplist = realloc(bplist, num_bps * sizeof(struct xfs_buf*));
2343 if (!bplist)
2344 do_error(_("realloc failed in %s (%zu bytes)\n"),
2345 __func__,
2346 num_bps * sizeof(struct xfs_buf*));
2347 /* Initialize the new elements */
2348 for (i = last_size; i < num_bps; i++)
2349 bplist[i] = NULL;
2350 }
2351
2352 if (isblock)
2353 ops = &xfs_dir3_block_buf_ops;
2354 else
2355 ops = &xfs_dir3_data_buf_ops;
2356
2357 error = dir_read_buf(ip, da_bno, &bplist[db], ops, &fixit);
2358 if (error) {
2359 do_warn(
2360 _("can't read data block %u for directory inode %" PRIu64 " error %d\n"),
2361 da_bno, ino, error);
2362 *num_illegal += 1;
2363
2364 /*
2365 * we try to read all "data" blocks, but if we are in
2366 * block form and we fail, there isn't anything else to
2367 * read, and nothing we can do but trash it.
2368 */
2369 if (isblock) {
2370 fixit++;
2371 goto out_fix;
2372 }
2373 continue;
2374 }
2375
2376 /* check v5 metadata */
2377 d = bplist[db]->b_addr;
2378 if (be32_to_cpu(d->magic) == XFS_DIR3_BLOCK_MAGIC ||
2379 be32_to_cpu(d->magic) == XFS_DIR3_DATA_MAGIC) {
2380 struct xfs_buf *bp = bplist[db];
2381
2382 error = check_dir3_header(mp, bp, ino);
2383 if (error) {
2384 fixit++;
2385 continue;
2386 }
2387 }
2388
2389 longform_dir2_entry_check_data(mp, ip, num_illegal, need_dot,
2390 irec, ino_offset, &bplist[db], hashtab,
2391 &freetab, da_bno, isblock);
2392 }
2393 fixit |= (*num_illegal != 0) || dir2_is_badino(ino) || *need_dot;
2394
2395 if (!dotdot_update) {
2396 /* check btree and freespace */
2397 if (isblock) {
2398 struct xfs_dir2_data_hdr *block;
2399 xfs_dir2_block_tail_t *btp;
2400 xfs_dir2_leaf_entry_t *blp;
2401
2402 block = bplist[0]->b_addr;
2403 btp = xfs_dir2_block_tail_p(mp->m_dir_geo, block);
2404 blp = xfs_dir2_block_leaf_p(btp);
2405 seeval = dir_hash_see_all(hashtab, blp,
2406 be32_to_cpu(btp->count),
2407 be32_to_cpu(btp->stale));
2408 if (dir_hash_check(hashtab, ip, seeval))
2409 fixit |= 1;
2410 } else if (isleaf) {
2411 fixit |= longform_dir2_check_leaf(mp, ip, hashtab,
2412 freetab);
2413 } else {
2414 fixit |= longform_dir2_check_node(mp, ip, hashtab,
2415 freetab);
2416 }
2417 }
2418 out_fix:
2419 if (!no_modify && (fixit || dotdot_update)) {
2420 dir_hash_dup_names(hashtab);
2421 for (i = 0; i < num_bps; i++)
2422 if (bplist[i])
2423 libxfs_buf_relse(bplist[i]);
2424 longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab);
2425 *num_illegal = 0;
2426 *need_dot = 0;
2427 } else {
2428 if (fixit || dotdot_update)
2429 do_warn(
2430 _("would rebuild directory inode %" PRIu64 "\n"), ino);
2431 for (i = 0; i < num_bps; i++)
2432 if (bplist[i])
2433 libxfs_buf_relse(bplist[i]);
2434 }
2435
2436 free(bplist);
2437 free(freetab);
2438 }
2439
2440 /*
2441 * shortform directory v2 processing routines -- entry verification and
2442 * bad entry deletion (pruning).
2443 */
2444 static struct xfs_dir2_sf_entry *
2445 shortform_dir2_junk(
2446 struct xfs_mount *mp,
2447 struct xfs_dir2_sf_hdr *sfp,
2448 struct xfs_dir2_sf_entry *sfep,
2449 xfs_ino_t lino,
2450 int *max_size,
2451 int *index,
2452 int *bytes_deleted,
2453 int *ino_dirty)
2454 {
2455 struct xfs_dir2_sf_entry *next_sfep;
2456 int next_len;
2457 int next_elen;
2458
2459 if (lino == orphanage_ino)
2460 orphanage_ino = 0;
2461
2462 next_elen = libxfs_dir2_sf_entsize(mp, sfp, sfep->namelen);
2463 next_sfep = libxfs_dir2_sf_nextentry(mp, sfp, sfep);
2464
2465 /*
2466 * if we are just checking, simply return the pointer to the next entry
2467 * here so that the checking loop can continue.
2468 */
2469 if (no_modify) {
2470 do_warn(_("would junk entry\n"));
2471 return next_sfep;
2472 }
2473
2474 /*
2475 * now move all the remaining entries down over the junked entry and
2476 * clear the newly unused bytes at the tail of the directory region.
2477 */
2478 next_len = *max_size - ((intptr_t)next_sfep - (intptr_t)sfp);
2479 *max_size -= next_elen;
2480 *bytes_deleted += next_elen;
2481
2482 memmove(sfep, next_sfep, next_len);
2483 memset((void *)((intptr_t)sfep + next_len), 0, next_elen);
2484 sfp->count -= 1;
2485 *ino_dirty = 1;
2486
2487 /*
2488 * WARNING: drop the index i by one so it matches the decremented count
2489 * for accurate comparisons in the loop test
2490 */
2491 (*index)--;
2492
2493 if (verbose)
2494 do_warn(_("junking entry\n"));
2495 else
2496 do_warn("\n");
2497 return sfep;
2498 }
2499
2500 static void
2501 shortform_dir2_entry_check(xfs_mount_t *mp,
2502 xfs_ino_t ino,
2503 xfs_inode_t *ip,
2504 int *ino_dirty,
2505 ino_tree_node_t *current_irec,
2506 int current_ino_offset,
2507 dir_hash_tab_t *hashtab)
2508 {
2509 xfs_ino_t lino;
2510 xfs_ino_t parent;
2511 struct xfs_dir2_sf_hdr *sfp;
2512 struct xfs_dir2_sf_entry *sfep;
2513 struct xfs_dir2_sf_entry *next_sfep;
2514 struct xfs_ifork *ifp;
2515 struct ino_tree_node *irec;
2516 int max_size;
2517 int ino_offset;
2518 int i;
2519 int bad_sfnamelen;
2520 int namelen;
2521 int bytes_deleted;
2522 char fname[MAXNAMELEN + 1];
2523 int i8;
2524
2525 ifp = &ip->i_df;
2526 sfp = (struct xfs_dir2_sf_hdr *) ifp->if_u1.if_data;
2527 *ino_dirty = 0;
2528 bytes_deleted = 0;
2529
2530 max_size = ifp->if_bytes;
2531 ASSERT(ip->i_d.di_size <= ifp->if_bytes);
2532
2533 /*
2534 * if just rebuild a directory due to a "..", update and return
2535 */
2536 if (dotdot_update) {
2537 parent = get_inode_parent(current_irec, current_ino_offset);
2538 if (no_modify) {
2539 do_warn(
2540 _("would set .. in sf dir inode %" PRIu64 " to %" PRIu64 "\n"),
2541 ino, parent);
2542 } else {
2543 do_warn(
2544 _("setting .. in sf dir inode %" PRIu64 " to %" PRIu64 "\n"),
2545 ino, parent);
2546 libxfs_dir2_sf_put_parent_ino(sfp, parent);
2547 *ino_dirty = 1;
2548 }
2549 return;
2550 }
2551
2552 /*
2553 * no '.' entry in shortform dirs, just bump up ref count by 1
2554 * '..' was already (or will be) accounted for and checked when
2555 * the directory is reached or will be taken care of when the
2556 * directory is moved to orphanage.
2557 */
2558 add_inode_ref(current_irec, current_ino_offset);
2559
2560 /*
2561 * Initialise i8 counter -- the parent inode number counts as well.
2562 */
2563 i8 = libxfs_dir2_sf_get_parent_ino(sfp) > XFS_DIR2_MAX_SHORT_INUM;
2564
2565 /*
2566 * now run through entries, stop at first bad entry, don't need
2567 * to skip over '..' since that's encoded in its own field and
2568 * no need to worry about '.' since it doesn't exist.
2569 */
2570 sfep = next_sfep = xfs_dir2_sf_firstentry(sfp);
2571
2572 for (i = 0; i < sfp->count && max_size >
2573 (intptr_t)next_sfep - (intptr_t)sfp;
2574 sfep = next_sfep, i++) {
2575 bad_sfnamelen = 0;
2576
2577 lino = libxfs_dir2_sf_get_ino(mp, sfp, sfep);
2578
2579 namelen = sfep->namelen;
2580
2581 ASSERT(no_modify || namelen > 0);
2582
2583 if (no_modify && namelen == 0) {
2584 /*
2585 * if we're really lucky, this is
2586 * the last entry in which case we
2587 * can use the dir size to set the
2588 * namelen value. otherwise, forget
2589 * it because we're not going to be
2590 * able to find the next entry.
2591 */
2592 bad_sfnamelen = 1;
2593
2594 if (i == sfp->count - 1) {
2595 namelen = ip->i_d.di_size -
2596 ((intptr_t) &sfep->name[0] -
2597 (intptr_t) sfp);
2598 } else {
2599 /*
2600 * don't process the rest of the directory,
2601 * break out of processing loop
2602 */
2603 break;
2604 }
2605 } else if (no_modify && (intptr_t) sfep - (intptr_t) sfp +
2606 + libxfs_dir2_sf_entsize(mp, sfp, sfep->namelen)
2607 > ip->i_d.di_size) {
2608 bad_sfnamelen = 1;
2609
2610 if (i == sfp->count - 1) {
2611 namelen = ip->i_d.di_size -
2612 ((intptr_t) &sfep->name[0] -
2613 (intptr_t) sfp);
2614 } else {
2615 /*
2616 * don't process the rest of the directory,
2617 * break out of processing loop
2618 */
2619 break;
2620 }
2621 }
2622
2623 memmove(fname, sfep->name, sfep->namelen);
2624 fname[sfep->namelen] = '\0';
2625
2626 ASSERT(no_modify || (lino != NULLFSINO && lino != 0));
2627 ASSERT(no_modify || libxfs_verify_dir_ino(mp, lino));
2628
2629 /*
2630 * Also skip entries with bogus inode numbers if we're
2631 * in no modify mode.
2632 */
2633
2634 if (no_modify && !libxfs_verify_dir_ino(mp, lino)) {
2635 next_sfep = libxfs_dir2_sf_nextentry(mp, sfp, sfep);
2636 continue;
2637 }
2638
2639 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino),
2640 XFS_INO_TO_AGINO(mp, lino));
2641
2642 if (irec == NULL) {
2643 do_warn(
2644 _("entry \"%s\" in shortform directory %" PRIu64 " references non-existent inode %" PRIu64 "\n"),
2645 fname, ino, lino);
2646 next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino,
2647 &max_size, &i, &bytes_deleted,
2648 ino_dirty);
2649 continue;
2650 }
2651
2652 ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum;
2653
2654 /*
2655 * if it's a free inode, blow out the entry.
2656 * by now, any inode that we think is free
2657 * really is free.
2658 */
2659 if (is_inode_free(irec, ino_offset)) {
2660 do_warn(
2661 _("entry \"%s\" in shortform directory inode %" PRIu64 " points to free inode %" PRIu64 "\n"),
2662 fname, ino, lino);
2663 next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino,
2664 &max_size, &i, &bytes_deleted,
2665 ino_dirty);
2666 continue;
2667 }
2668 /*
2669 * check if this inode is lost+found dir in the root
2670 */
2671 if (ino == mp->m_sb.sb_rootino && strcmp(fname, ORPHANAGE) == 0) {
2672 /*
2673 * if it's not a directory, trash it
2674 */
2675 if (!inode_isadir(irec, ino_offset)) {
2676 do_warn(
2677 _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"),
2678 ORPHANAGE, lino, ino);
2679 next_sfep = shortform_dir2_junk(mp, sfp, sfep,
2680 lino, &max_size, &i,
2681 &bytes_deleted, ino_dirty);
2682 continue;
2683 }
2684 /*
2685 * if this is a dup, it will be picked up below,
2686 * otherwise, mark it as the orphanage for later.
2687 */
2688 if (!orphanage_ino)
2689 orphanage_ino = lino;
2690 }
2691 /*
2692 * check for duplicate names in directory.
2693 */
2694 if (!dir_hash_add(mp, hashtab, (xfs_dir2_dataptr_t)
2695 (sfep - xfs_dir2_sf_firstentry(sfp)),
2696 lino, sfep->namelen, sfep->name,
2697 libxfs_dir2_sf_get_ftype(mp, sfep))) {
2698 do_warn(
2699 _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"),
2700 fname, lino, ino);
2701 next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino,
2702 &max_size, &i, &bytes_deleted,
2703 ino_dirty);
2704 continue;
2705 }
2706
2707 if (!inode_isadir(irec, ino_offset)) {
2708 /*
2709 * check easy case first, regular inode, just bump
2710 * the link count
2711 */
2712 add_inode_reached(irec, ino_offset);
2713 } else {
2714 parent = get_inode_parent(irec, ino_offset);
2715
2716 /*
2717 * bump up the link counts in parent and child.
2718 * directory but if the link doesn't agree with
2719 * the .. in the child, blow out the entry
2720 */
2721 if (is_inode_reached(irec, ino_offset)) {
2722 do_warn(
2723 _("entry \"%s\" in directory inode %" PRIu64
2724 " references already connected inode %" PRIu64 ".\n"),
2725 fname, ino, lino);
2726 next_sfep = shortform_dir2_junk(mp, sfp, sfep,
2727 lino, &max_size, &i,
2728 &bytes_deleted, ino_dirty);
2729 continue;
2730 } else if (parent == ino) {
2731 add_inode_reached(irec, ino_offset);
2732 add_inode_ref(current_irec, current_ino_offset);
2733 } else if (parent == NULLFSINO) {
2734 /* ".." was missing, but this entry refers to it,
2735 so, set it as the parent and mark for rebuild */
2736 do_warn(
2737 _("entry \"%s\" in dir ino %" PRIu64 " doesn't have a .. entry, will set it in ino %" PRIu64 ".\n"),
2738 fname, ino, lino);
2739 set_inode_parent(irec, ino_offset, ino);
2740 add_inode_reached(irec, ino_offset);
2741 add_inode_ref(current_irec, current_ino_offset);
2742 add_dotdot_update(XFS_INO_TO_AGNO(mp, lino),
2743 irec, ino_offset);
2744 } else {
2745 do_warn(
2746 _("entry \"%s\" in directory inode %" PRIu64
2747 " not consistent with .. value (%" PRIu64
2748 ") in inode %" PRIu64 ",\n"),
2749 fname, ino, parent, lino);
2750 next_sfep = shortform_dir2_junk(mp, sfp, sfep,
2751 lino, &max_size, &i,
2752 &bytes_deleted, ino_dirty);
2753 continue;
2754 }
2755 }
2756
2757 /* validate ftype field if supported */
2758 if (xfs_sb_version_hasftype(&mp->m_sb)) {
2759 uint8_t dir_ftype;
2760 uint8_t ino_ftype;
2761
2762 dir_ftype = libxfs_dir2_sf_get_ftype(mp, sfep);
2763 ino_ftype = get_inode_ftype(irec, ino_offset);
2764
2765 if (dir_ftype != ino_ftype) {
2766 if (no_modify) {
2767 do_warn(
2768 _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
2769 dir_ftype, ino_ftype,
2770 ino, lino);
2771 } else {
2772 do_warn(
2773 _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
2774 dir_ftype, ino_ftype,
2775 ino, lino);
2776 libxfs_dir2_sf_put_ftype(mp, sfep,
2777 ino_ftype);
2778 dir_hash_update_ftype(hashtab,
2779 (xfs_dir2_dataptr_t)(sfep - xfs_dir2_sf_firstentry(sfp)),
2780 ino_ftype);
2781 *ino_dirty = 1;
2782 }
2783 }
2784 }
2785
2786 if (lino > XFS_DIR2_MAX_SHORT_INUM)
2787 i8++;
2788
2789 /*
2790 * go onto next entry - we have to take entries with bad namelen
2791 * into account in no modify mode since we calculate size based
2792 * on next_sfep.
2793 */
2794 ASSERT(no_modify || bad_sfnamelen == 0);
2795 next_sfep = (struct xfs_dir2_sf_entry *)((intptr_t)sfep +
2796 (bad_sfnamelen
2797 ? libxfs_dir2_sf_entsize(mp, sfp, namelen)
2798 : libxfs_dir2_sf_entsize(mp, sfp, sfep->namelen)));
2799 }
2800
2801 if (sfp->i8count != i8) {
2802 if (no_modify) {
2803 do_warn(_("would fix i8count in inode %" PRIu64 "\n"),
2804 ino);
2805 } else {
2806 if (i8 == 0) {
2807 struct xfs_dir2_sf_entry *tmp_sfep;
2808
2809 tmp_sfep = next_sfep;
2810 process_sf_dir2_fixi8(mp, sfp, &tmp_sfep);
2811 bytes_deleted +=
2812 (intptr_t)next_sfep -
2813 (intptr_t)tmp_sfep;
2814 next_sfep = tmp_sfep;
2815 } else
2816 sfp->i8count = i8;
2817 *ino_dirty = 1;
2818 do_warn(_("fixing i8count in inode %" PRIu64 "\n"),
2819 ino);
2820 }
2821 }
2822
2823 /*
2824 * sync up sizes if required
2825 */
2826 if (*ino_dirty && bytes_deleted > 0) {
2827 ASSERT(!no_modify);
2828 libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK);
2829 ip->i_d.di_size -= bytes_deleted;
2830 }
2831
2832 if (ip->i_d.di_size != ip->i_df.if_bytes) {
2833 ASSERT(ip->i_df.if_bytes == (xfs_fsize_t)
2834 ((intptr_t) next_sfep - (intptr_t) sfp));
2835 ip->i_d.di_size = (xfs_fsize_t)
2836 ((intptr_t) next_sfep - (intptr_t) sfp);
2837 do_warn(
2838 _("setting size to %" PRId64 " bytes to reflect junked entries\n"),
2839 ip->i_d.di_size);
2840 *ino_dirty = 1;
2841 }
2842 }
2843
2844 /*
2845 * processes all reachable inodes in directories
2846 */
2847 static void
2848 process_dir_inode(
2849 xfs_mount_t *mp,
2850 xfs_agnumber_t agno,
2851 ino_tree_node_t *irec,
2852 int ino_offset)
2853 {
2854 xfs_ino_t ino;
2855 xfs_inode_t *ip;
2856 xfs_trans_t *tp;
2857 dir_hash_tab_t *hashtab;
2858 int need_dot;
2859 int dirty, num_illegal, error, nres;
2860
2861 ino = XFS_AGINO_TO_INO(mp, agno, irec->ino_startnum + ino_offset);
2862
2863 /*
2864 * open up directory inode, check all entries,
2865 * then call prune_dir_entries to remove all
2866 * remaining illegal directory entries.
2867 */
2868
2869 ASSERT(!is_inode_refchecked(irec, ino_offset) || dotdot_update);
2870
2871 error = -libxfs_iget(mp, NULL, ino, 0, &ip, &phase6_ifork_ops);
2872 if (error) {
2873 if (!no_modify)
2874 do_error(
2875 _("couldn't map inode %" PRIu64 ", err = %d\n"),
2876 ino, error);
2877 else {
2878 do_warn(
2879 _("couldn't map inode %" PRIu64 ", err = %d\n"),
2880 ino, error);
2881 /*
2882 * see below for what we're doing if this
2883 * is root. Why do we need to do this here?
2884 * to ensure that the root doesn't show up
2885 * as being disconnected in the no_modify case.
2886 */
2887 if (mp->m_sb.sb_rootino == ino) {
2888 add_inode_reached(irec, 0);
2889 add_inode_ref(irec, 0);
2890 }
2891 }
2892
2893 add_inode_refchecked(irec, 0);
2894 return;
2895 }
2896
2897 need_dot = dirty = num_illegal = 0;
2898
2899 if (mp->m_sb.sb_rootino == ino) {
2900 /*
2901 * mark root inode reached and bump up
2902 * link count for root inode to account
2903 * for '..' entry since the root inode is
2904 * never reached by a parent. we know
2905 * that root's '..' is always good --
2906 * guaranteed by phase 3 and/or below.
2907 */
2908 add_inode_reached(irec, ino_offset);
2909 }
2910
2911 add_inode_refchecked(irec, ino_offset);
2912
2913 hashtab = dir_hash_init(ip->i_d.di_size);
2914
2915 /*
2916 * look for bogus entries
2917 */
2918 switch (ip->i_d.di_format) {
2919 case XFS_DINODE_FMT_EXTENTS:
2920 case XFS_DINODE_FMT_BTREE:
2921 /*
2922 * also check for missing '.' in longform dirs.
2923 * missing .. entries are added if required when
2924 * the directory is connected to lost+found. but
2925 * we need to create '.' entries here.
2926 */
2927 longform_dir2_entry_check(mp, ino, ip,
2928 &num_illegal, &need_dot,
2929 irec, ino_offset,
2930 hashtab);
2931 break;
2932
2933 case XFS_DINODE_FMT_LOCAL:
2934 /*
2935 * using the remove reservation is overkill
2936 * since at most we'll only need to log the
2937 * inode but it's easier than wedging a
2938 * new define in ourselves.
2939 */
2940 nres = no_modify ? 0 : XFS_REMOVE_SPACE_RES(mp);
2941 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove,
2942 nres, 0, 0, &tp);
2943 if (error)
2944 res_failed(error);
2945
2946 libxfs_trans_ijoin(tp, ip, 0);
2947
2948 shortform_dir2_entry_check(mp, ino, ip, &dirty,
2949 irec, ino_offset,
2950 hashtab);
2951
2952 ASSERT(dirty == 0 || (dirty && !no_modify));
2953 if (dirty) {
2954 libxfs_trans_log_inode(tp, ip,
2955 XFS_ILOG_CORE | XFS_ILOG_DDATA);
2956 error = -libxfs_trans_commit(tp);
2957 if (error)
2958 do_error(
2959 _("error %d fixing shortform directory %llu\n"),
2960 error,
2961 (unsigned long long)ip->i_ino);
2962 } else {
2963 libxfs_trans_cancel(tp);
2964 }
2965 break;
2966
2967 default:
2968 break;
2969 }
2970 dir_hash_done(hashtab);
2971
2972 /*
2973 * if we have to create a .. for /, do it now *before*
2974 * we delete the bogus entries, otherwise the directory
2975 * could transform into a shortform dir which would
2976 * probably cause the simulation to choke. Even
2977 * if the illegal entries get shifted around, it's ok
2978 * because the entries are structurally intact and in
2979 * in hash-value order so the simulation won't get confused
2980 * if it has to move them around.
2981 */
2982 if (!no_modify && need_root_dotdot && ino == mp->m_sb.sb_rootino) {
2983 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_LOCAL);
2984
2985 do_warn(_("recreating root directory .. entry\n"));
2986
2987 nres = XFS_MKDIR_SPACE_RES(mp, 2);
2988 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir,
2989 nres, 0, 0, &tp);
2990 if (error)
2991 res_failed(error);
2992
2993 libxfs_trans_ijoin(tp, ip, 0);
2994
2995 error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot,
2996 ip->i_ino, nres);
2997 if (error)
2998 do_error(
2999 _("can't make \"..\" entry in root inode %" PRIu64 ", createname error %d\n"), ino, error);
3000
3001 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
3002 error = -libxfs_trans_commit(tp);
3003 if (error)
3004 do_error(
3005 _("root inode \"..\" entry recreation failed (%d)\n"), error);
3006
3007 need_root_dotdot = 0;
3008 } else if (need_root_dotdot && ino == mp->m_sb.sb_rootino) {
3009 do_warn(_("would recreate root directory .. entry\n"));
3010 }
3011
3012 /*
3013 * if we need to create the '.' entry, do so only if
3014 * the directory is a longform dir. if it's been
3015 * turned into a shortform dir, then the inode is ok
3016 * since shortform dirs have no '.' entry and the inode
3017 * has already been committed by prune_lf_dir_entry().
3018 */
3019 if (need_dot) {
3020 /*
3021 * bump up our link count but don't
3022 * bump up the inode link count. chances
3023 * are good that even though we lost '.'
3024 * the inode link counts reflect '.' so
3025 * leave the inode link count alone and if
3026 * it turns out to be wrong, we'll catch
3027 * that in phase 7.
3028 */
3029 add_inode_ref(irec, ino_offset);
3030
3031 if (no_modify) {
3032 do_warn(
3033 _("would create missing \".\" entry in dir ino %" PRIu64 "\n"),
3034 ino);
3035 } else if (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) {
3036 /*
3037 * need to create . entry in longform dir.
3038 */
3039 do_warn(
3040 _("creating missing \".\" entry in dir ino %" PRIu64 "\n"), ino);
3041
3042 nres = XFS_MKDIR_SPACE_RES(mp, 1);
3043 error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir,
3044 nres, 0, 0, &tp);
3045 if (error)
3046 res_failed(error);
3047
3048 libxfs_trans_ijoin(tp, ip, 0);
3049
3050 error = -libxfs_dir_createname(tp, ip, &xfs_name_dot,
3051 ip->i_ino, nres);
3052 if (error)
3053 do_error(
3054 _("can't make \".\" entry in dir ino %" PRIu64 ", createname error %d\n"),
3055 ino, error);
3056
3057 libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
3058 error = -libxfs_trans_commit(tp);
3059 if (error)
3060 do_error(
3061 _("root inode \".\" entry recreation failed (%d)\n"), error);
3062 }
3063 }
3064 libxfs_irele(ip);
3065 }
3066
3067 /*
3068 * mark realtime bitmap and summary inodes as reached.
3069 * quota inode will be marked here as well
3070 */
3071 static void
3072 mark_standalone_inodes(xfs_mount_t *mp)
3073 {
3074 ino_tree_node_t *irec;
3075 int offset;
3076
3077 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rbmino),
3078 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino));
3079
3080 offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino) -
3081 irec->ino_startnum;
3082
3083 add_inode_reached(irec, offset);
3084
3085 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rsumino),
3086 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino));
3087
3088 offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino) -
3089 irec->ino_startnum;
3090
3091 add_inode_reached(irec, offset);
3092
3093 if (fs_quotas) {
3094 if (mp->m_sb.sb_uquotino
3095 && mp->m_sb.sb_uquotino != NULLFSINO) {
3096 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp,
3097 mp->m_sb.sb_uquotino),
3098 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino));
3099 offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino)
3100 - irec->ino_startnum;
3101 add_inode_reached(irec, offset);
3102 }
3103 if (mp->m_sb.sb_gquotino
3104 && mp->m_sb.sb_gquotino != NULLFSINO) {
3105 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp,
3106 mp->m_sb.sb_gquotino),
3107 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino));
3108 offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino)
3109 - irec->ino_startnum;
3110 add_inode_reached(irec, offset);
3111 }
3112 if (mp->m_sb.sb_pquotino
3113 && mp->m_sb.sb_pquotino != NULLFSINO) {
3114 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp,
3115 mp->m_sb.sb_pquotino),
3116 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino));
3117 offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino)
3118 - irec->ino_startnum;
3119 add_inode_reached(irec, offset);
3120 }
3121 }
3122 }
3123
3124 static void
3125 check_for_orphaned_inodes(
3126 xfs_mount_t *mp,
3127 xfs_agnumber_t agno,
3128 ino_tree_node_t *irec)
3129 {
3130 int i;
3131 xfs_ino_t ino;
3132
3133 for (i = 0; i < XFS_INODES_PER_CHUNK; i++) {
3134 ASSERT(is_inode_confirmed(irec, i));
3135 if (is_inode_free(irec, i))
3136 continue;
3137
3138 if (is_inode_reached(irec, i))
3139 continue;
3140
3141 ASSERT(inode_isadir(irec, i) ||
3142 num_inode_references(irec, i) == 0);
3143
3144 ino = XFS_AGINO_TO_INO(mp, agno, i + irec->ino_startnum);
3145 if (inode_isadir(irec, i))
3146 do_warn(_("disconnected dir inode %" PRIu64 ", "), ino);
3147 else
3148 do_warn(_("disconnected inode %" PRIu64 ", "), ino);
3149 if (!no_modify) {
3150 if (!orphanage_ino)
3151 orphanage_ino = mk_orphanage(mp);
3152 do_warn(_("moving to %s\n"), ORPHANAGE);
3153 mv_orphanage(mp, ino, inode_isadir(irec, i));
3154 } else {
3155 do_warn(_("would move to %s\n"), ORPHANAGE);
3156 }
3157 /*
3158 * for read-only case, even though the inode isn't
3159 * really reachable, set the flag (and bump our link
3160 * count) anyway to fool phase 7
3161 */
3162 add_inode_reached(irec, i);
3163 }
3164 }
3165
3166 static void
3167 traverse_function(
3168 struct workqueue *wq,
3169 xfs_agnumber_t agno,
3170 void *arg)
3171 {
3172 ino_tree_node_t *irec;
3173 int i;
3174 prefetch_args_t *pf_args = arg;
3175
3176 wait_for_inode_prefetch(pf_args);
3177
3178 if (verbose)
3179 do_log(_(" - agno = %d\n"), agno);
3180
3181 for (irec = findfirst_inode_rec(agno); irec; irec = next_ino_rec(irec)) {
3182 if (irec->ino_isa_dir == 0)
3183 continue;
3184
3185 if (pf_args) {
3186 sem_post(&pf_args->ra_count);
3187 #ifdef XR_PF_TRACE
3188 sem_getvalue(&pf_args->ra_count, &i);
3189 pftrace(
3190 "processing inode chunk %p in AG %d (sem count = %d)",
3191 irec, agno, i);
3192 #endif
3193 }
3194
3195 for (i = 0; i < XFS_INODES_PER_CHUNK; i++) {
3196 if (inode_isadir(irec, i))
3197 process_dir_inode(wq->wq_ctx, agno, irec, i);
3198 }
3199 }
3200 cleanup_inode_prefetch(pf_args);
3201 }
3202
3203 static void
3204 update_missing_dotdot_entries(
3205 xfs_mount_t *mp)
3206 {
3207 dotdot_update_t *dir;
3208
3209 /*
3210 * these entries parents were updated, rebuild them again
3211 * set dotdot_update flag so processing routines do not count links
3212 */
3213 dotdot_update = 1;
3214 while (!list_empty(&dotdot_update_list)) {
3215 dir = list_entry(dotdot_update_list.prev, struct dotdot_update,
3216 list);
3217 list_del(&dir->list);
3218 process_dir_inode(mp, dir->agno, dir->irec, dir->ino_offset);
3219 free(dir);
3220 }
3221 }
3222
3223 static void
3224 traverse_ags(
3225 struct xfs_mount *mp)
3226 {
3227 do_inode_prefetch(mp, 0, traverse_function, false, true);
3228 }
3229
3230 void
3231 phase6(xfs_mount_t *mp)
3232 {
3233 ino_tree_node_t *irec;
3234 int i;
3235
3236 memset(&zerocr, 0, sizeof(struct cred));
3237 memset(&zerofsx, 0, sizeof(struct fsxattr));
3238 orphanage_ino = 0;
3239
3240 do_log(_("Phase 6 - check inode connectivity...\n"));
3241
3242 incore_ext_teardown(mp);
3243
3244 add_ino_ex_data(mp);
3245
3246 /*
3247 * verify existence of root directory - if we have to
3248 * make one, it's ok for the incore data structs not to
3249 * know about it since everything about it (and the other
3250 * inodes in its chunk if a new chunk was created) are ok
3251 */
3252 if (need_root_inode) {
3253 if (!no_modify) {
3254 do_warn(_("reinitializing root directory\n"));
3255 mk_root_dir(mp);
3256 need_root_inode = 0;
3257 need_root_dotdot = 0;
3258 } else {
3259 do_warn(_("would reinitialize root directory\n"));
3260 }
3261 }
3262
3263 if (need_rbmino) {
3264 if (!no_modify) {
3265 do_warn(_("reinitializing realtime bitmap inode\n"));
3266 mk_rbmino(mp);
3267 need_rbmino = 0;
3268 } else {
3269 do_warn(_("would reinitialize realtime bitmap inode\n"));
3270 }
3271 }
3272
3273 if (need_rsumino) {
3274 if (!no_modify) {
3275 do_warn(_("reinitializing realtime summary inode\n"));
3276 mk_rsumino(mp);
3277 need_rsumino = 0;
3278 } else {
3279 do_warn(_("would reinitialize realtime summary inode\n"));
3280 }
3281 }
3282
3283 if (!no_modify) {
3284 do_log(
3285 _(" - resetting contents of realtime bitmap and summary inodes\n"));
3286 if (fill_rbmino(mp)) {
3287 do_warn(
3288 _("Warning: realtime bitmap may be inconsistent\n"));
3289 }
3290
3291 if (fill_rsumino(mp)) {
3292 do_warn(
3293 _("Warning: realtime bitmap may be inconsistent\n"));
3294 }
3295 }
3296
3297 mark_standalone_inodes(mp);
3298
3299 do_log(_(" - traversing filesystem ...\n"));
3300
3301 irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
3302 XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino));
3303
3304 /*
3305 * we always have a root inode, even if it's free...
3306 * if the root is free, forget it, lost+found is already gone
3307 */
3308 if (is_inode_free(irec, 0) || !inode_isadir(irec, 0)) {
3309 need_root_inode = 1;
3310 }
3311
3312 /*
3313 * then process all inodes by walking incore inode tree
3314 */
3315 traverse_ags(mp);
3316
3317 /*
3318 * any directories that had updated ".." entries, rebuild them now
3319 */
3320 update_missing_dotdot_entries(mp);
3321
3322 do_log(_(" - traversal finished ...\n"));
3323 do_log(_(" - moving disconnected inodes to %s ...\n"),
3324 ORPHANAGE);
3325
3326 /*
3327 * move all disconnected inodes to the orphanage
3328 */
3329 for (i = 0; i < glob_agcount; i++) {
3330 irec = findfirst_inode_rec(i);
3331 while (irec != NULL) {
3332 check_for_orphaned_inodes(mp, i, irec);
3333 irec = next_ino_rec(irec);
3334 }
3335 }
3336 }