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