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