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