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