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