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