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