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