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