]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - repair/dino_chunks.c
Refactor process_dinode_int()
[thirdparty/xfsprogs-dev.git] / repair / dino_chunks.c
1 /*
2 * Copyright (c) 2000-2002,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 "protos.h"
25 #include "err_protos.h"
26 #include "dir.h"
27 #include "dinode.h"
28 #include "versions.h"
29 #include "prefetch.h"
30 #include "progress.h"
31
32 /*
33 * validates inode block or chunk, returns # of good inodes
34 * the dinodes are verified using verify_uncertain_dinode() which
35 * means only the basic inode info is checked, no fork checks.
36 */
37
38 int
39 check_aginode_block(xfs_mount_t *mp,
40 xfs_agnumber_t agno,
41 xfs_agblock_t agbno)
42 {
43
44 xfs_dinode_t *dino_p;
45 int i;
46 int cnt = 0;
47 xfs_buf_t *bp;
48
49 /*
50 * it's ok to read these possible inode blocks in one at
51 * a time because they don't belong to known inodes (if
52 * they did, we'd know about them courtesy of the incore inode
53 * tree and we wouldn't be here and we stale the buffers out
54 * so no one else will overlap them.
55 */
56 bp = libxfs_readbuf(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno),
57 XFS_FSB_TO_BB(mp, 1), 0);
58 if (!bp) {
59 do_warn(_("cannot read agbno (%u/%u), disk block %lld\n"), agno,
60 agbno, (xfs_daddr_t)XFS_AGB_TO_DADDR(mp, agno, agbno));
61 return(0);
62 }
63
64 for (i = 0; i < mp->m_sb.sb_inopblock; i++) {
65 dino_p = XFS_MAKE_IPTR(mp, bp, i);
66 if (!verify_uncertain_dinode(mp, dino_p, agno,
67 XFS_OFFBNO_TO_AGINO(mp, agbno, i)))
68 cnt++;
69 }
70
71 libxfs_putbuf(bp);
72 return(cnt);
73 }
74
75 int
76 check_inode_block(xfs_mount_t *mp,
77 xfs_ino_t ino)
78 {
79 return(check_aginode_block(mp, XFS_INO_TO_AGNO(mp, ino),
80 XFS_INO_TO_AGBNO(mp, ino)));
81 }
82
83 /*
84 * tries to establish if the inode really exists in a valid
85 * inode chunk. returns number of new inodes if things are good
86 * and 0 if bad. start is the start of the discovered inode chunk.
87 * routine assumes that ino is a legal inode number
88 * (verified by verify_inum()). If the inode chunk turns out
89 * to be good, this routine will put the inode chunk into
90 * the good inode chunk tree if required.
91 *
92 * the verify_(ag)inode* family of routines are utility
93 * routines called by check_uncertain_aginodes() and
94 * process_uncertain_aginodes().
95 */
96 int
97 verify_inode_chunk(xfs_mount_t *mp,
98 xfs_ino_t ino,
99 xfs_ino_t *start_ino)
100 {
101 xfs_agnumber_t agno;
102 xfs_agino_t agino;
103 xfs_agino_t start_agino;
104 xfs_agblock_t agbno;
105 xfs_agblock_t start_agbno = 0;
106 xfs_agblock_t end_agbno;
107 xfs_agblock_t max_agbno;
108 xfs_agblock_t cur_agbno;
109 xfs_agblock_t chunk_start_agbno;
110 xfs_agblock_t chunk_stop_agbno;
111 ino_tree_node_t *irec_before_p = NULL;
112 ino_tree_node_t *irec_after_p = NULL;
113 ino_tree_node_t *irec_p;
114 ino_tree_node_t *irec_next_p;
115 int irec_cnt;
116 int ino_cnt = 0;
117 int num_blks;
118 int i;
119 int j;
120 int state;
121
122 agno = XFS_INO_TO_AGNO(mp, ino);
123 agino = XFS_INO_TO_AGINO(mp, ino);
124 agbno = XFS_INO_TO_AGBNO(mp, ino);
125 *start_ino = NULLFSINO;
126
127 ASSERT(XFS_IALLOC_BLOCKS(mp) > 0);
128
129 if (agno == mp->m_sb.sb_agcount - 1)
130 max_agbno = mp->m_sb.sb_dblocks -
131 (xfs_drfsbno_t) mp->m_sb.sb_agblocks * agno;
132 else
133 max_agbno = mp->m_sb.sb_agblocks;
134
135 /*
136 * is the inode beyond the end of the AG?
137 */
138 if (agbno >= max_agbno)
139 return(0);
140
141 /*
142 * check for the easy case, inodes per block >= XFS_INODES_PER_CHUNK
143 * (multiple chunks per block)
144 */
145 if (XFS_IALLOC_BLOCKS(mp) == 1) {
146 if (agbno > max_agbno)
147 return(0);
148
149 if (check_inode_block(mp, ino) == 0)
150 return(0);
151
152 pthread_mutex_lock(&ag_locks[agno]);
153
154 switch (state = get_agbno_state(mp, agno, agbno)) {
155 case XR_E_INO:
156 do_warn(
157 _("uncertain inode block %d/%d already known\n"),
158 agno, agbno);
159 break;
160 case XR_E_UNKNOWN:
161 case XR_E_FREE1:
162 case XR_E_FREE:
163 set_agbno_state(mp, agno, agbno, XR_E_INO);
164 break;
165 case XR_E_MULT:
166 case XR_E_INUSE:
167 case XR_E_INUSE_FS:
168 case XR_E_FS_MAP:
169 /*
170 * if block is already claimed, forget it.
171 */
172 do_warn(
173 _("inode block %d/%d multiply claimed, (state %d)\n"),
174 agno, agbno, state);
175 set_agbno_state(mp, agno, agbno, XR_E_MULT);
176 pthread_mutex_unlock(&ag_locks[agno]);
177 return(0);
178 default:
179 do_warn(
180 _("inode block %d/%d bad state, (state %d)\n"),
181 agno, agbno, state);
182 set_agbno_state(mp, agno, agbno, XR_E_INO);
183 break;
184 }
185
186 pthread_mutex_unlock(&ag_locks[agno]);
187
188 start_agino = XFS_OFFBNO_TO_AGINO(mp, agbno, 0);
189 *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino);
190
191 /*
192 * put new inode record(s) into inode tree
193 */
194 for (j = 0; j < chunks_pblock; j++) {
195 if ((irec_p = find_inode_rec(agno, start_agino))
196 == NULL) {
197 irec_p = set_inode_free_alloc(agno,
198 start_agino);
199 for (i = 1; i < XFS_INODES_PER_CHUNK; i++)
200 set_inode_free(irec_p, i);
201 }
202 if (start_agino <= agino && agino <
203 start_agino + XFS_INODES_PER_CHUNK)
204 set_inode_used(irec_p, agino - start_agino);
205
206 start_agino += XFS_INODES_PER_CHUNK;
207 ino_cnt += XFS_INODES_PER_CHUNK;
208 }
209
210 return(ino_cnt);
211 } else if (fs_aligned_inodes) {
212 /*
213 * next easy case -- aligned inode filesystem.
214 * just check out the chunk
215 */
216 start_agbno = rounddown(XFS_INO_TO_AGBNO(mp, ino),
217 fs_ino_alignment);
218 end_agbno = start_agbno + XFS_IALLOC_BLOCKS(mp);
219
220 /*
221 * if this fs has aligned inodes but the end of the
222 * chunk is beyond the end of the ag, this is a bad
223 * chunk
224 */
225 if (end_agbno > max_agbno)
226 return(0);
227
228 /*
229 * check out all blocks in chunk
230 */
231 ino_cnt = 0;
232 for (cur_agbno = start_agbno; cur_agbno < end_agbno;
233 cur_agbno++) {
234 ino_cnt += check_aginode_block(mp, agno, cur_agbno);
235 }
236
237 /*
238 * if we lose either 2 blocks worth of inodes or >25% of
239 * the chunk, just forget it.
240 */
241 if (ino_cnt < XFS_INODES_PER_CHUNK - 2 * mp->m_sb.sb_inopblock
242 || ino_cnt < XFS_INODES_PER_CHUNK - 16)
243 return(0);
244
245 /*
246 * ok, put the record into the tree, if no conflict.
247 */
248 if (find_uncertain_inode_rec(agno,
249 XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0)))
250 return(0);
251
252 start_agino = XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0);
253 *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino);
254
255 irec_p = set_inode_free_alloc(agno,
256 XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0));
257
258 for (i = 1; i < XFS_INODES_PER_CHUNK; i++)
259 set_inode_free(irec_p, i);
260
261 ASSERT(start_agino <= agino &&
262 start_agino + XFS_INODES_PER_CHUNK > agino);
263
264 set_inode_used(irec_p, agino - start_agino);
265
266 return(XFS_INODES_PER_CHUNK);
267 }
268
269 /*
270 * hard case -- pre-6.3 filesystem.
271 * set default start/end agbnos and ensure agbnos are legal.
272 * we're setting a range [start_agbno, end_agbno) such that
273 * a discovered inode chunk completely within that range
274 * would include the inode passed into us.
275 */
276 if (XFS_IALLOC_BLOCKS(mp) > 1) {
277 if (agino > XFS_IALLOC_INODES(mp))
278 start_agbno = agbno - XFS_IALLOC_BLOCKS(mp) + 1;
279 else
280 start_agbno = 1;
281 }
282
283 end_agbno = agbno + XFS_IALLOC_BLOCKS(mp);
284
285 if (end_agbno > max_agbno)
286 end_agbno = max_agbno;
287
288 /*
289 * search tree for known inodes within +/- 1 inode chunk range
290 */
291 irec_before_p = irec_after_p = NULL;
292
293 find_inode_rec_range(agno, XFS_OFFBNO_TO_AGINO(mp, start_agbno, 0),
294 XFS_OFFBNO_TO_AGINO(mp, end_agbno, mp->m_sb.sb_inopblock - 1),
295 &irec_before_p, &irec_after_p);
296
297 /*
298 * if we have known inode chunks in our search range, establish
299 * their start and end-points to tighten our search range. range
300 * is [start, end) -- e.g. max/end agbno is one beyond the
301 * last block to be examined. the avl routines work this way.
302 */
303 if (irec_before_p) {
304 /*
305 * only one inode record in the range, move one boundary in
306 */
307 if (irec_before_p == irec_after_p) {
308 if (irec_before_p->ino_startnum < agino)
309 start_agbno = XFS_AGINO_TO_AGBNO(mp,
310 irec_before_p->ino_startnum +
311 XFS_INODES_PER_CHUNK);
312 else
313 end_agbno = XFS_AGINO_TO_AGBNO(mp,
314 irec_before_p->ino_startnum);
315 }
316
317 /*
318 * find the start of the gap in the search range (which
319 * should contain our unknown inode). if the only irec
320 * within +/- 1 chunks starts after the inode we're
321 * looking for, skip this stuff since the end_agbno
322 * of the range has already been trimmed in to not
323 * include that irec.
324 */
325 if (irec_before_p->ino_startnum < agino) {
326 irec_p = irec_before_p;
327 irec_next_p = next_ino_rec(irec_p);
328
329 while(irec_next_p != NULL &&
330 irec_p->ino_startnum + XFS_INODES_PER_CHUNK ==
331 irec_next_p->ino_startnum) {
332 irec_p = irec_next_p;
333 irec_next_p = next_ino_rec(irec_next_p);
334 }
335
336 start_agbno = XFS_AGINO_TO_AGBNO(mp,
337 irec_p->ino_startnum) +
338 XFS_IALLOC_BLOCKS(mp);
339
340 /*
341 * we know that the inode we're trying to verify isn't
342 * in an inode chunk so the next ino_rec marks the end
343 * of the gap -- is it within the search range?
344 */
345 if (irec_next_p != NULL &&
346 agino + XFS_IALLOC_INODES(mp) >=
347 irec_next_p->ino_startnum)
348 end_agbno = XFS_AGINO_TO_AGBNO(mp,
349 irec_next_p->ino_startnum);
350 }
351
352 ASSERT(start_agbno < end_agbno);
353 }
354
355 /*
356 * if the gap is too small to contain a chunk, we lose.
357 * this means that inode chunks known to be good surround
358 * the inode in question and that the space between them
359 * is too small for a legal inode chunk
360 */
361 if (end_agbno - start_agbno < XFS_IALLOC_BLOCKS(mp))
362 return(0);
363
364 /*
365 * now grunge around the disk, start at the inode block and
366 * go in each direction until you hit a non-inode block or
367 * run into a range boundary. A non-inode block is block
368 * with *no* good inodes in it. Unfortunately, we can't
369 * co-opt bad blocks into inode chunks (which might take
370 * care of disk blocks that turn into zeroes) because the
371 * filesystem could very well allocate two inode chunks
372 * with a one block file in between and we'd zap the file.
373 * We're better off just losing the rest of the
374 * inode chunk instead.
375 */
376 for (cur_agbno = agbno; cur_agbno >= start_agbno; cur_agbno--) {
377 /*
378 * if the block has no inodes, it's a bad block so
379 * break out now without decrementing cur_agbno so
380 * chunk start blockno will be set to the last good block
381 */
382 if (!(irec_cnt = check_aginode_block(mp, agno, cur_agbno)))
383 break;
384 ino_cnt += irec_cnt;
385 }
386
387 chunk_start_agbno = cur_agbno + 1;
388
389 for (cur_agbno = agbno + 1; cur_agbno < end_agbno; cur_agbno++) {
390 /*
391 * if the block has no inodes, it's a bad block so
392 * break out now without incrementing cur_agbno so
393 * chunk start blockno will be set to the block
394 * immediately after the last good block.
395 */
396 if (!(irec_cnt = check_aginode_block(mp, agno, cur_agbno)))
397 break;
398 ino_cnt += irec_cnt;
399 }
400
401 chunk_stop_agbno = cur_agbno;
402
403 num_blks = chunk_stop_agbno - chunk_start_agbno;
404
405 if (num_blks < XFS_IALLOC_BLOCKS(mp) || ino_cnt == 0)
406 return(0);
407
408 /*
409 * XXX - later - if the entire range is selected and they're all
410 * good inodes, keep searching in either direction.
411 * until you the range of inodes end, then split into chunks
412 * for now, just take one chunk's worth starting at the lowest
413 * possible point and hopefully we'll pick the rest up later.
414 *
415 * XXX - if we were going to fix up an inode chunk for
416 * any good inodes in the chunk, this is where we would
417 * do it. For now, keep it simple and lose the rest of
418 * the chunk
419 */
420
421 if (num_blks % XFS_IALLOC_BLOCKS(mp) != 0) {
422 num_blks = rounddown(num_blks, XFS_IALLOC_BLOCKS(mp));
423 chunk_stop_agbno = chunk_start_agbno + num_blks;
424 }
425
426 /*
427 * ok, we've got a candidate inode chunk. now we have to
428 * verify that we aren't trying to use blocks that are already
429 * in use. If so, mark them as multiply claimed since odds
430 * are very low that we found this chunk by stumbling across
431 * user data -- we're probably here as a result of a directory
432 * entry or an iunlinked pointer
433 */
434 pthread_mutex_lock(&ag_locks[agno]);
435 for (j = 0, cur_agbno = chunk_start_agbno;
436 cur_agbno < chunk_stop_agbno; cur_agbno++) {
437 switch (state = get_agbno_state(mp, agno, cur_agbno)) {
438 case XR_E_MULT:
439 case XR_E_INUSE:
440 case XR_E_INUSE_FS:
441 case XR_E_FS_MAP:
442 do_warn(
443 _("inode block %d/%d multiply claimed, (state %d)\n"),
444 agno, cur_agbno, state);
445 set_agbno_state(mp, agno, cur_agbno, XR_E_MULT);
446 j = 1;
447 break;
448 case XR_E_INO:
449 do_error(
450 _("uncertain inode block overlap, agbno = %d, ino = %llu\n"),
451 agbno, ino);
452 break;
453 default:
454 break;
455 }
456
457 if (j) {
458 pthread_mutex_unlock(&ag_locks[agno]);
459 return(0);
460 }
461 }
462 pthread_mutex_unlock(&ag_locks[agno]);
463
464 /*
465 * ok, chunk is good. put the record into the tree if required,
466 * and fill in the bitmap. All inodes will be marked as "free"
467 * except for the one that led us to discover the chunk. That's
468 * ok because we'll override the free setting later if the
469 * contents of the inode indicate it's in use.
470 */
471 start_agino = XFS_OFFBNO_TO_AGINO(mp, chunk_start_agbno, 0);
472 *start_ino = XFS_AGINO_TO_INO(mp, agno, start_agino);
473
474 ASSERT(find_inode_rec(agno, start_agino) == NULL);
475
476 irec_p = set_inode_free_alloc(agno, start_agino);
477 for (i = 1; i < XFS_INODES_PER_CHUNK; i++)
478 set_inode_free(irec_p, i);
479
480 ASSERT(start_agino <= agino &&
481 start_agino + XFS_INODES_PER_CHUNK > agino);
482
483 set_inode_used(irec_p, agino - start_agino);
484
485 pthread_mutex_lock(&ag_locks[agno]);
486
487 for (cur_agbno = chunk_start_agbno;
488 cur_agbno < chunk_stop_agbno; cur_agbno++) {
489 switch (state = get_agbno_state(mp, agno, cur_agbno)) {
490 case XR_E_INO:
491 do_error(
492 _("uncertain inode block %llu already known\n"),
493 XFS_AGB_TO_FSB(mp, agno, cur_agbno));
494 break;
495 case XR_E_UNKNOWN:
496 case XR_E_FREE1:
497 case XR_E_FREE:
498 set_agbno_state(mp, agno, cur_agbno, XR_E_INO);
499 break;
500 case XR_E_MULT:
501 case XR_E_INUSE:
502 case XR_E_INUSE_FS:
503 case XR_E_FS_MAP:
504 do_error(
505 _("inode block %d/%d multiply claimed, (state %d)\n"),
506 agno, cur_agbno, state);
507 break;
508 default:
509 do_warn(
510 _("inode block %d/%d bad state, (state %d)\n"),
511 agno, cur_agbno, state);
512 set_agbno_state(mp, agno, cur_agbno, XR_E_INO);
513 break;
514 }
515 }
516 pthread_mutex_unlock(&ag_locks[agno]);
517
518 return(ino_cnt);
519 }
520
521 /*
522 * same as above only for ag inode chunks
523 */
524 int
525 verify_aginode_chunk(xfs_mount_t *mp,
526 xfs_agnumber_t agno,
527 xfs_agino_t agino,
528 xfs_agino_t *agino_start)
529 {
530 xfs_ino_t ino;
531 int res;
532
533 res = verify_inode_chunk(mp, XFS_AGINO_TO_INO(mp, agno, agino), &ino);
534
535 if (res)
536 *agino_start = XFS_INO_TO_AGINO(mp, ino);
537 else
538 *agino_start = NULLAGINO;
539
540 return(res);
541 }
542
543 /*
544 * this does the same as the two above only it returns a pointer
545 * to the inode record in the good inode tree
546 */
547 ino_tree_node_t *
548 verify_aginode_chunk_irec(xfs_mount_t *mp,
549 xfs_agnumber_t agno,
550 xfs_agino_t agino)
551 {
552 xfs_agino_t start_agino;
553 ino_tree_node_t *irec = NULL;
554
555 if (verify_aginode_chunk(mp, agno, agino, &start_agino))
556 irec = find_inode_rec(agno, start_agino);
557
558 return(irec);
559 }
560
561
562
563 /*
564 * processes an inode allocation chunk/block, returns 1 on I/O errors,
565 * 0 otherwise
566 *
567 * *bogus is set to 1 if the entire set of inodes is bad.
568 */
569
570 /* ARGSUSED */
571 static int
572 process_inode_chunk(
573 xfs_mount_t *mp,
574 xfs_agnumber_t agno,
575 int num_inos,
576 ino_tree_node_t *first_irec,
577 int ino_discovery,
578 int check_dups,
579 int extra_attr_check,
580 int *bogus)
581 {
582 xfs_ino_t parent;
583 ino_tree_node_t *ino_rec;
584 xfs_buf_t **bplist;
585 xfs_dinode_t *dino;
586 int icnt;
587 int status;
588 int is_used;
589 int state;
590 int ino_dirty;
591 int irec_offset;
592 int ibuf_offset;
593 xfs_agino_t agino;
594 xfs_agblock_t agbno;
595 int dirty = 0;
596 int isa_dir = 0;
597 int blks_per_cluster;
598 int cluster_count;
599 int bp_index;
600 int cluster_offset;
601
602 ASSERT(first_irec != NULL);
603 ASSERT(XFS_AGINO_TO_OFFSET(mp, first_irec->ino_startnum) == 0);
604
605 *bogus = 0;
606 ASSERT(XFS_IALLOC_BLOCKS(mp) > 0);
607
608 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
609 if (blks_per_cluster == 0)
610 blks_per_cluster = 1;
611 cluster_count = XFS_INODES_PER_CHUNK / inodes_per_cluster;
612 ASSERT(cluster_count > 0);
613
614 /*
615 * get all blocks required to read in this chunk (may wind up
616 * having to process more chunks in a multi-chunk per block fs)
617 */
618 agbno = XFS_AGINO_TO_AGBNO(mp, first_irec->ino_startnum);
619
620 /*
621 * set up first irec
622 */
623 ino_rec = first_irec;
624
625 bplist = malloc(cluster_count * sizeof(xfs_buf_t *));
626 if (bplist == NULL)
627 do_error(_("failed to allocate %d bytes of memory\n"),
628 cluster_count * sizeof(xfs_buf_t*));
629
630 for (bp_index = 0; bp_index < cluster_count; bp_index++) {
631 #ifdef XR_PF_TRACE
632 pftrace("about to read off %llu in AG %d",
633 (long long)XFS_AGB_TO_DADDR(mp, agno, agbno), agno);
634 #endif
635 bplist[bp_index] = libxfs_readbuf(mp->m_dev,
636 XFS_AGB_TO_DADDR(mp, agno, agbno),
637 XFS_FSB_TO_BB(mp, blks_per_cluster), 0);
638 if (!bplist[bp_index]) {
639 do_warn(_("cannot read inode %llu, disk block %lld, cnt %d\n"),
640 XFS_AGINO_TO_INO(mp, agno, first_irec->ino_startnum),
641 XFS_AGB_TO_DADDR(mp, agno, agbno),
642 (int)XFS_FSB_TO_BB(mp, blks_per_cluster));
643 while (bp_index > 0) {
644 bp_index--;
645 libxfs_putbuf(bplist[bp_index]);
646 }
647 free(bplist);
648 return(1);
649 }
650 agbno += blks_per_cluster;
651
652 #ifdef XR_PF_TRACE
653 pftrace("readbuf %p (%llu, %d) in AG %d", bplist[bp_index],
654 (long long)XFS_BUF_ADDR(bplist[bp_index]),
655 XFS_BUF_COUNT(bplist[bp_index]), agno);
656 #endif
657 }
658 agbno = XFS_AGINO_TO_AGBNO(mp, first_irec->ino_startnum);
659
660 /*
661 * initialize counters
662 */
663 irec_offset = 0;
664 ibuf_offset = 0;
665 cluster_offset = 0;
666 icnt = 0;
667 status = 0;
668 bp_index = 0;
669
670 /*
671 * verify inode chunk if necessary
672 */
673 if (ino_discovery) {
674 for (;;) {
675 /*
676 * make inode pointer
677 */
678 dino = XFS_MAKE_IPTR(mp, bplist[bp_index], cluster_offset);
679 agino = irec_offset + ino_rec->ino_startnum;
680
681 /*
682 * we always think that the root and realtime
683 * inodes are verified even though we may have
684 * to reset them later to keep from losing the
685 * chunk that they're in
686 */
687 if (verify_dinode(mp, dino, agno, agino) == 0 ||
688 (agno == 0 &&
689 (mp->m_sb.sb_rootino == agino ||
690 mp->m_sb.sb_rsumino == agino ||
691 mp->m_sb.sb_rbmino == agino)))
692 status++;
693
694 irec_offset++;
695 icnt++;
696 cluster_offset++;
697
698 if (icnt == XFS_IALLOC_INODES(mp) &&
699 irec_offset == XFS_INODES_PER_CHUNK) {
700 /*
701 * done! - finished up irec and block
702 * simultaneously
703 */
704 break;
705 } else if (irec_offset == XFS_INODES_PER_CHUNK) {
706 /*
707 * get new irec (multiple chunks per block fs)
708 */
709 ino_rec = next_ino_rec(ino_rec);
710 ASSERT(ino_rec->ino_startnum == agino + 1);
711 irec_offset = 0;
712 }
713 if (cluster_offset == inodes_per_cluster) {
714 bp_index++;
715 cluster_offset = 0;
716 }
717 }
718
719 /*
720 * if chunk/block is bad, blow it off. the inode records
721 * will be deleted by the caller if appropriate.
722 */
723 if (!status) {
724 *bogus = 1;
725 for (bp_index = 0; bp_index < cluster_count; bp_index++)
726 libxfs_putbuf(bplist[bp_index]);
727 free(bplist);
728 return(0);
729 }
730
731 /*
732 * reset irec and counters
733 */
734 ino_rec = first_irec;
735
736 irec_offset = 0;
737 cluster_offset = 0;
738 bp_index = 0;
739 icnt = 0;
740 status = 0;
741 }
742
743 /*
744 * mark block as an inode block in the incore bitmap
745 */
746 pthread_mutex_lock(&ag_locks[agno]);
747 switch (state = get_agbno_state(mp, agno, agbno)) {
748 case XR_E_INO: /* already marked */
749 break;
750 case XR_E_UNKNOWN:
751 case XR_E_FREE:
752 case XR_E_FREE1:
753 set_agbno_state(mp, agno, agbno, XR_E_INO);
754 break;
755 case XR_E_BAD_STATE:
756 do_error(_("bad state in block map %d\n"), state);
757 break;
758 default:
759 set_agbno_state(mp, agno, agbno, XR_E_MULT);
760 do_warn(_("inode block %llu multiply claimed, state was %d\n"),
761 XFS_AGB_TO_FSB(mp, agno, agbno), state);
762 break;
763 }
764 pthread_mutex_unlock(&ag_locks[agno]);
765
766 for (;;) {
767 /*
768 * make inode pointer
769 */
770 dino = XFS_MAKE_IPTR(mp, bplist[bp_index], cluster_offset);
771 agino = irec_offset + ino_rec->ino_startnum;
772
773 is_used = 3;
774 ino_dirty = 0;
775 parent = 0;
776
777 status = process_dinode(mp, dino, agno, agino,
778 is_inode_free(ino_rec, irec_offset),
779 &ino_dirty, &is_used,ino_discovery, check_dups,
780 extra_attr_check, &isa_dir, &parent);
781
782 ASSERT(is_used != 3);
783 if (ino_dirty)
784 dirty = 1;
785 /*
786 * XXX - if we want to try and keep
787 * track of whether we need to bang on
788 * the inode maps (instead of just
789 * blindly reconstructing them like
790 * we do now, this is where to start.
791 */
792 if (is_used) {
793 if (is_inode_free(ino_rec, irec_offset)) {
794 if (verbose || no_modify) {
795 do_warn(_("imap claims in-use inode "
796 "%llu is free, "),
797 XFS_AGINO_TO_INO(mp, agno,
798 agino));
799 }
800
801 if (verbose || !no_modify)
802 do_warn(_("correcting imap\n"));
803 else
804 do_warn(_("would correct imap\n"));
805 }
806 set_inode_used(ino_rec, irec_offset);
807
808 /*
809 * store on-disk nlink count for comparing in phase 7
810 */
811 set_inode_disk_nlinks(ino_rec, irec_offset,
812 dino->di_core.di_version > XFS_DINODE_VERSION_1
813 ? be32_to_cpu(dino->di_core.di_nlink)
814 : be16_to_cpu(dino->di_core.di_onlink));
815
816 } else {
817 set_inode_free(ino_rec, irec_offset);
818 }
819
820 /*
821 * if we lose the root inode, or it turns into
822 * a non-directory, that allows us to double-check
823 * later whether or not we need to reinitialize it.
824 */
825 if (isa_dir) {
826 set_inode_isadir(ino_rec, irec_offset);
827 /*
828 * we always set the parent but
829 * we may as well wait until
830 * phase 4 (no inode discovery)
831 * because the parent info will
832 * be solid then.
833 */
834 if (!ino_discovery) {
835 ASSERT(parent != 0);
836 set_inode_parent(ino_rec, irec_offset, parent);
837 ASSERT(parent ==
838 get_inode_parent(ino_rec, irec_offset));
839 }
840 } else {
841 clear_inode_isadir(ino_rec, irec_offset);
842 }
843
844 if (status) {
845 if (mp->m_sb.sb_rootino ==
846 XFS_AGINO_TO_INO(mp, agno, agino)) {
847 need_root_inode = 1;
848
849 if (!no_modify) {
850 do_warn(_("cleared root inode %llu\n"),
851 XFS_AGINO_TO_INO(mp, agno,
852 agino));
853 } else {
854 do_warn(_("would clear root inode %llu\n"),
855 XFS_AGINO_TO_INO(mp, agno,
856 agino));
857 }
858 } else if (mp->m_sb.sb_rbmino ==
859 XFS_AGINO_TO_INO(mp, agno, agino)) {
860 need_rbmino = 1;
861
862 if (!no_modify) {
863 do_warn(_("cleared realtime bitmap "
864 "inode %llu\n"),
865 XFS_AGINO_TO_INO(mp, agno,
866 agino));
867 } else {
868 do_warn(_("would clear realtime bitmap "
869 "inode %llu\n"),
870 XFS_AGINO_TO_INO(mp, agno,
871 agino));
872 }
873 } else if (mp->m_sb.sb_rsumino ==
874 XFS_AGINO_TO_INO(mp, agno, agino)) {
875 need_rsumino = 1;
876
877 if (!no_modify) {
878 do_warn(_("cleared realtime summary "
879 "inode %llu\n"),
880 XFS_AGINO_TO_INO(mp, agno,
881 agino));
882 } else {
883 do_warn(_("would clear realtime summary"
884 " inode %llu\n"),
885 XFS_AGINO_TO_INO(mp, agno,
886 agino));
887 }
888 } else if (!no_modify) {
889 do_warn(_("cleared inode %llu\n"),
890 XFS_AGINO_TO_INO(mp, agno, agino));
891 } else {
892 do_warn(_("would have cleared inode %llu\n"),
893 XFS_AGINO_TO_INO(mp, agno, agino));
894 }
895 }
896
897 irec_offset++;
898 ibuf_offset++;
899 icnt++;
900 cluster_offset++;
901
902 if (icnt == XFS_IALLOC_INODES(mp) &&
903 irec_offset == XFS_INODES_PER_CHUNK) {
904 /*
905 * done! - finished up irec and block simultaneously
906 */
907 for (bp_index = 0; bp_index < cluster_count; bp_index++) {
908 #ifdef XR_PF_TRACE
909 pftrace("put/writebuf %p (%llu) in AG %d", bplist[bp_index],
910 (long long)XFS_BUF_ADDR(bplist[bp_index]), agno);
911 #endif
912 if (dirty && !no_modify)
913 libxfs_writebuf(bplist[bp_index], 0);
914 else
915 libxfs_putbuf(bplist[bp_index]);
916 }
917 free(bplist);
918 break;
919 } else if (ibuf_offset == mp->m_sb.sb_inopblock) {
920 /*
921 * mark block as an inode block in the incore bitmap
922 * and reset inode buffer offset counter
923 */
924 ibuf_offset = 0;
925 agbno++;
926
927 pthread_mutex_lock(&ag_locks[agno]);
928 switch (state = get_agbno_state(mp, agno, agbno)) {
929 case XR_E_INO: /* already marked */
930 break;
931 case XR_E_UNKNOWN:
932 case XR_E_FREE:
933 case XR_E_FREE1:
934 set_agbno_state(mp, agno, agbno, XR_E_INO);
935 break;
936 case XR_E_BAD_STATE:
937 do_error(_("bad state in block map %d\n"),
938 state);
939 break;
940 default:
941 set_agbno_state(mp, agno, agbno, XR_E_MULT);
942 do_warn(_("inode block %llu multiply claimed, "
943 "state was %d\n"),
944 XFS_AGB_TO_FSB(mp, agno, agbno), state);
945 break;
946 }
947 pthread_mutex_unlock(&ag_locks[agno]);
948
949 } else if (irec_offset == XFS_INODES_PER_CHUNK) {
950 /*
951 * get new irec (multiple chunks per block fs)
952 */
953 ino_rec = next_ino_rec(ino_rec);
954 ASSERT(ino_rec->ino_startnum == agino + 1);
955 irec_offset = 0;
956 }
957 if (cluster_offset == inodes_per_cluster) {
958 bp_index++;
959 cluster_offset = 0;
960 }
961 }
962 return(0);
963 }
964
965 /*
966 * check all inodes mentioned in the ag's incore inode maps.
967 * the map may be incomplete. If so, we'll catch the missing
968 * inodes (hopefully) when we traverse the directory tree.
969 * check_dirs is set to 1 if directory inodes should be
970 * processed for internal consistency, parent setting and
971 * discovery of unknown inodes. this only happens
972 * in phase 3. check_dups is set to 1 if we're looking for
973 * inodes that reference duplicate blocks so we can trash
974 * the inode right then and there. this is set only in
975 * phase 4 after we've run through and set the bitmap once.
976 */
977 void
978 process_aginodes(
979 xfs_mount_t *mp,
980 prefetch_args_t *pf_args,
981 xfs_agnumber_t agno,
982 int ino_discovery,
983 int check_dups,
984 int extra_attr_check)
985 {
986 int num_inos, bogus;
987 ino_tree_node_t *ino_rec, *first_ino_rec, *prev_ino_rec;
988 #ifdef XR_PF_TRACE
989 int count;
990 #endif
991 first_ino_rec = ino_rec = findfirst_inode_rec(agno);
992
993 while (ino_rec != NULL) {
994 /*
995 * paranoia - step through inode records until we step
996 * through a full allocation of inodes. this could
997 * be an issue in big-block filesystems where a block
998 * can hold more than one inode chunk. make sure to
999 * grab the record corresponding to the beginning of
1000 * the next block before we call the processing routines.
1001 */
1002 num_inos = XFS_INODES_PER_CHUNK;
1003 while (num_inos < XFS_IALLOC_INODES(mp) && ino_rec != NULL) {
1004 /*
1005 * inodes chunks will always be aligned and sized
1006 * correctly
1007 */
1008 if ((ino_rec = next_ino_rec(ino_rec)) != NULL)
1009 num_inos += XFS_INODES_PER_CHUNK;
1010 }
1011
1012 ASSERT(num_inos == XFS_IALLOC_INODES(mp));
1013
1014 if (pf_args) {
1015 sem_post(&pf_args->ra_count);
1016 #ifdef XR_PF_TRACE
1017 sem_getvalue(&pf_args->ra_count, &count);
1018 pftrace("processing inode chunk %p in AG %d (sem count = %d)",
1019 first_ino_rec, agno, count);
1020 #endif
1021 }
1022
1023 if (process_inode_chunk(mp, agno, num_inos, first_ino_rec,
1024 ino_discovery, check_dups, extra_attr_check,
1025 &bogus)) {
1026 /* XXX - i/o error, we've got a problem */
1027 abort();
1028 }
1029
1030 if (!bogus)
1031 first_ino_rec = ino_rec = next_ino_rec(ino_rec);
1032 else {
1033 /*
1034 * inodes pointed to by this record are
1035 * completely bogus, blow the records for
1036 * this chunk out.
1037 * the inode block(s) will get reclaimed
1038 * in phase 4 when the block map is
1039 * reconstructed after inodes claiming
1040 * duplicate blocks are deleted.
1041 */
1042 num_inos = 0;
1043 ino_rec = first_ino_rec;
1044 while (num_inos < XFS_IALLOC_INODES(mp) &&
1045 ino_rec != NULL) {
1046 prev_ino_rec = ino_rec;
1047
1048 if ((ino_rec = next_ino_rec(ino_rec)) != NULL)
1049 num_inos += XFS_INODES_PER_CHUNK;
1050
1051 get_inode_rec(agno, prev_ino_rec);
1052 free_inode_rec(agno, prev_ino_rec);
1053 }
1054
1055 first_ino_rec = ino_rec;
1056 }
1057 PROG_RPT_INC(prog_rpt_done[agno], num_inos);
1058 }
1059 }
1060
1061 /*
1062 * verify the uncertain inode list for an ag.
1063 * Good inodes get moved into the good inode tree.
1064 * returns 0 if there are no uncertain inode records to
1065 * be processed, 1 otherwise. This routine destroys the
1066 * the entire uncertain inode tree for the ag as a side-effect.
1067 */
1068 void
1069 check_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno)
1070 {
1071 ino_tree_node_t *irec;
1072 ino_tree_node_t *nrec;
1073 xfs_agino_t start;
1074 xfs_agino_t i;
1075 xfs_agino_t agino;
1076 int got_some;
1077
1078 nrec = NULL;
1079 got_some = 0;
1080
1081 clear_uncertain_ino_cache(agno);
1082
1083 if ((irec = findfirst_uncertain_inode_rec(agno)) == NULL)
1084 return;
1085
1086 /*
1087 * the trick here is to find a contiguous range
1088 * of inodes, make sure that it doesn't overlap
1089 * with a known to exist chunk, and then make
1090 * sure it is a number of entire chunks.
1091 * we check on-disk once we have an idea of what's
1092 * going on just to double-check.
1093 *
1094 * process the uncertain inode record list and look
1095 * on disk to see if the referenced inodes are good
1096 */
1097
1098 do_warn(_("found inodes not in the inode allocation tree\n"));
1099
1100 do {
1101 /*
1102 * check every confirmed (which in this case means
1103 * inode that we really suspect to be an inode) inode
1104 */
1105 for (i = 0; i < XFS_INODES_PER_CHUNK; i++) {
1106 if (!is_inode_confirmed(irec, i))
1107 continue;
1108
1109 agino = i + irec->ino_startnum;
1110
1111 if (verify_aginum(mp, agno, agino))
1112 continue;
1113
1114 if (nrec != NULL && nrec->ino_startnum <= agino &&
1115 agino < nrec->ino_startnum +
1116 XFS_INODES_PER_CHUNK)
1117 continue;
1118
1119 if ((nrec = find_inode_rec(agno, agino)) == NULL)
1120 if (!verify_aginum(mp, agno, agino))
1121 if (verify_aginode_chunk(mp, agno,
1122 agino, &start))
1123 got_some = 1;
1124 }
1125
1126 get_uncertain_inode_rec(agno, irec);
1127 free_inode_rec(agno, irec);
1128
1129 irec = findfirst_uncertain_inode_rec(agno);
1130 } while (irec != NULL);
1131
1132 if (got_some)
1133 do_warn(_("found inodes not in the inode allocation tree\n"));
1134
1135 return;
1136 }
1137
1138 /*
1139 * verify and process the uncertain inodes for an ag.
1140 * this is different from check_ in that we can't just
1141 * move the good inodes into the good inode tree and let
1142 * process_aginodes() deal with them because this gets called
1143 * after process_aginodes() has been run on the ag inode tree.
1144 * So we have to process the inodes as well as verify since
1145 * we don't want to rerun process_aginodes() on a tree that has
1146 * mostly been processed.
1147 *
1148 * Note that if this routine does process some inodes, it can
1149 * add uncertain inodes to any ag which would require that
1150 * the routine be called again to process those newly-added
1151 * uncertain inodes.
1152 *
1153 * returns 0 if no inodes were processed and 1 if inodes
1154 * were processed (and it is possible that new uncertain
1155 * inodes were discovered).
1156 *
1157 * as a side-effect, this routine tears down the uncertain
1158 * inode tree for the ag.
1159 */
1160 int
1161 process_uncertain_aginodes(xfs_mount_t *mp, xfs_agnumber_t agno)
1162 {
1163 ino_tree_node_t *irec;
1164 ino_tree_node_t *nrec;
1165 xfs_agino_t agino;
1166 int i;
1167 int bogus;
1168 int cnt;
1169 int got_some;
1170
1171 #ifdef XR_INODE_TRACE
1172 fprintf(stderr, "in process_uncertain_aginodes, agno = %d\n", agno);
1173 #endif
1174
1175 got_some = 0;
1176
1177 clear_uncertain_ino_cache(agno);
1178
1179 if ((irec = findfirst_uncertain_inode_rec(agno)) == NULL)
1180 return(0);
1181
1182 nrec = NULL;
1183
1184 do {
1185 /*
1186 * check every confirmed inode
1187 */
1188 for (cnt = i = 0; i < XFS_INODES_PER_CHUNK; i++) {
1189 if (!is_inode_confirmed(irec, i))
1190 continue;
1191 cnt++;
1192 agino = i + irec->ino_startnum;
1193 #ifdef XR_INODE_TRACE
1194 fprintf(stderr, "ag inode = %d (0x%x)\n", agino, agino);
1195 #endif
1196 /*
1197 * skip over inodes already processed (in the
1198 * good tree), bad inode numbers, and inode numbers
1199 * pointing to bogus inodes
1200 */
1201 if (verify_aginum(mp, agno, agino))
1202 continue;
1203
1204 if (nrec != NULL && nrec->ino_startnum <= agino &&
1205 agino < nrec->ino_startnum +
1206 XFS_INODES_PER_CHUNK)
1207 continue;
1208
1209 if ((nrec = find_inode_rec(agno, agino)) != NULL)
1210 continue;
1211
1212 /*
1213 * verify the chunk. if good, it will be
1214 * added to the good inode tree.
1215 */
1216 if ((nrec = verify_aginode_chunk_irec(mp,
1217 agno, agino)) == NULL)
1218 continue;
1219
1220 got_some = 1;
1221
1222 /*
1223 * process the inode record we just added
1224 * to the good inode tree. The inode
1225 * processing may add more records to the
1226 * uncertain inode lists.
1227 */
1228 if (process_inode_chunk(mp, agno, XFS_IALLOC_INODES(mp),
1229 nrec, 1, 0, 0, &bogus)) {
1230 /* XXX - i/o error, we've got a problem */
1231 abort();
1232 }
1233 }
1234
1235 ASSERT(cnt != 0);
1236 /*
1237 * now return the uncertain inode record to the free pool
1238 * and pull another one off the list for processing
1239 */
1240 get_uncertain_inode_rec(agno, irec);
1241 free_inode_rec(agno, irec);
1242
1243 irec = findfirst_uncertain_inode_rec(agno);
1244 } while (irec != NULL);
1245
1246 if (got_some)
1247 do_warn(_("found inodes not in the inode allocation tree\n"));
1248
1249 return(1);
1250 }