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