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