]>
Commit | Line | Data |
---|---|---|
959ef981 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2bd0ea18 | 2 | /* |
da23017d NS |
3 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. | |
2bd0ea18 NS |
5 | */ |
6 | ||
6b803e5a | 7 | #include "libxfs.h" |
1164bde5 DC |
8 | #include "threads.h" |
9 | #include "prefetch.h" | |
2bd0ea18 NS |
10 | #include "avl.h" |
11 | #include "globals.h" | |
12 | #include "agheader.h" | |
13 | #include "incore.h" | |
14 | #include "protos.h" | |
15 | #include "err_protos.h" | |
16 | #include "dinode.h" | |
06fbdda9 | 17 | #include "progress.h" |
bd758142 | 18 | #include "bmap.h" |
8100dd79 | 19 | #include "threads.h" |
2bd0ea18 | 20 | |
62b00e63 CH |
21 | static void |
22 | process_agi_unlinked( | |
23 | struct xfs_mount *mp, | |
24 | xfs_agnumber_t agno) | |
2bd0ea18 | 25 | { |
62b00e63 CH |
26 | struct xfs_buf *bp; |
27 | struct xfs_agi *agip; | |
28 | xfs_agnumber_t i; | |
29 | int agi_dirty = 0; | |
31079e67 | 30 | int error; |
2bd0ea18 | 31 | |
31079e67 | 32 | error = -libxfs_buf_read(mp->m_dev, |
9440d84d | 33 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), |
31079e67 DW |
34 | mp->m_sb.sb_sectsize / BBSIZE, LIBXFS_READBUF_SALVAGE, |
35 | &bp, &xfs_agi_buf_ops); | |
36 | if (error) | |
5d1b7f0f | 37 | do_error(_("cannot read agi block %" PRId64 " for ag %u\n"), |
9440d84d | 38 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), agno); |
2bd0ea18 | 39 | |
c99cea5c | 40 | agip = bp->b_addr; |
2bd0ea18 | 41 | |
62b00e63 | 42 | ASSERT(be32_to_cpu(agip->agi_seqno) == agno); |
2bd0ea18 NS |
43 | |
44 | for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { | |
62b00e63 CH |
45 | if (agip->agi_unlinked[i] != cpu_to_be32(NULLAGINO)) { |
46 | agip->agi_unlinked[i] = cpu_to_be32(NULLAGINO); | |
47 | agi_dirty = 1; | |
2bd0ea18 NS |
48 | } |
49 | } | |
50 | ||
18b4f688 | 51 | if (agi_dirty) { |
f524ae04 | 52 | libxfs_buf_mark_dirty(bp); |
18b4f688 DW |
53 | libxfs_buf_relse(bp); |
54 | } | |
2bd0ea18 | 55 | else |
e02ba985 | 56 | libxfs_buf_relse(bp); |
2bd0ea18 NS |
57 | } |
58 | ||
2556c98b BN |
59 | static void |
60 | process_ag_func( | |
62843f36 | 61 | struct workqueue *wq, |
2556c98b BN |
62 | xfs_agnumber_t agno, |
63 | void *arg) | |
3b6ac903 MV |
64 | { |
65 | /* | |
66 | * turn on directory processing (inode discovery) and | |
67 | * attribute processing (extra_attr_check) | |
68 | */ | |
2556c98b | 69 | wait_for_inode_prefetch(arg); |
3b6ac903 | 70 | do_log(_(" - agno = %d\n"), agno); |
62843f36 | 71 | process_aginodes(wq->wq_ctx, arg, agno, 1, 0, 1); |
bd758142 | 72 | blkmap_free_final(); |
2556c98b BN |
73 | cleanup_inode_prefetch(arg); |
74 | } | |
75 | ||
76 | static void | |
77 | process_ags( | |
78 | xfs_mount_t *mp) | |
79 | { | |
1164bde5 | 80 | do_inode_prefetch(mp, ag_stride, process_ag_func, false, false); |
3b6ac903 MV |
81 | } |
82 | ||
8100dd79 DC |
83 | static void |
84 | do_uncertain_aginodes( | |
62843f36 DW |
85 | struct workqueue *wq, |
86 | xfs_agnumber_t agno, | |
87 | void *arg) | |
8100dd79 | 88 | { |
62843f36 | 89 | int *count = arg; |
8100dd79 | 90 | |
62843f36 | 91 | *count = process_uncertain_aginodes(wq->wq_ctx, agno); |
8100dd79 DC |
92 | |
93 | #ifdef XR_INODE_TRACE | |
94 | fprintf(stderr, | |
95 | "\t\t phase 3 - ag %d process_uncertain_inodes returns %d\n", | |
96 | *count, j); | |
97 | #endif | |
98 | ||
99 | PROG_RPT_INC(prog_rpt_done[agno], 1); | |
100 | } | |
101 | ||
2bd0ea18 | 102 | void |
8100dd79 DC |
103 | phase3( |
104 | struct xfs_mount *mp, | |
105 | int scan_threads) | |
2bd0ea18 | 106 | { |
8100dd79 DC |
107 | int i, j; |
108 | int *counts; | |
62843f36 | 109 | struct workqueue wq; |
2bd0ea18 | 110 | |
507f4e33 | 111 | do_log(_("Phase 3 - for each AG...\n")); |
2bd0ea18 | 112 | if (!no_modify) |
507f4e33 | 113 | do_log(_(" - scan and clear agi unlinked lists...\n")); |
2bd0ea18 | 114 | else |
507f4e33 | 115 | do_log(_(" - scan (but don't clear) agi unlinked lists...\n")); |
2bd0ea18 | 116 | |
14f8b681 | 117 | set_progress_msg(PROG_FMT_AGI_UNLINKED, (uint64_t) glob_agcount); |
06fbdda9 | 118 | |
62b00e63 CH |
119 | /* first clear the agi unlinked AGI list */ |
120 | if (!no_modify) { | |
121 | for (i = 0; i < mp->m_sb.sb_agcount; i++) | |
122 | process_agi_unlinked(mp, i); | |
123 | } | |
124 | ||
125 | /* now look at possibly bogus inodes */ | |
2bd0ea18 | 126 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { |
2bd0ea18 | 127 | check_uncertain_aginodes(mp, i); |
06fbdda9 | 128 | PROG_RPT_INC(prog_rpt_done[i], 1); |
2bd0ea18 | 129 | } |
06fbdda9 | 130 | print_final_rpt(); |
2bd0ea18 NS |
131 | |
132 | /* ok, now that the tree's ok, let's take a good look */ | |
133 | ||
507f4e33 NS |
134 | do_log(_( |
135 | " - process known inodes and perform inode discovery...\n")); | |
2bd0ea18 | 136 | |
14f8b681 | 137 | set_progress_msg(PROG_FMT_PROCESS_INO, (uint64_t) mp->m_sb.sb_icount); |
2556c98b BN |
138 | |
139 | process_ags(mp); | |
140 | ||
06fbdda9 | 141 | print_final_rpt(); |
2bd0ea18 NS |
142 | |
143 | /* | |
144 | * process newly discovered inode chunks | |
145 | */ | |
507f4e33 | 146 | do_log(_(" - process newly discovered inodes...\n")); |
14f8b681 | 147 | set_progress_msg(PROG_FMT_NEW_INODES, (uint64_t) glob_agcount); |
8100dd79 DC |
148 | |
149 | counts = calloc(sizeof(*counts), mp->m_sb.sb_agcount); | |
150 | if (!counts) { | |
151 | do_abort(_("no memory for uncertain inode counts\n")); | |
152 | return; | |
153 | } | |
154 | ||
2bd0ea18 NS |
155 | do { |
156 | /* | |
157 | * have to loop until no ag has any uncertain | |
158 | * inodes | |
159 | */ | |
160 | j = 0; | |
8100dd79 DC |
161 | memset(counts, 0, mp->m_sb.sb_agcount * sizeof(*counts)); |
162 | ||
163 | create_work_queue(&wq, mp, scan_threads); | |
164 | ||
165 | for (i = 0; i < mp->m_sb.sb_agcount; i++) | |
166 | queue_work(&wq, do_uncertain_aginodes, i, &counts[i]); | |
167 | ||
168 | destroy_work_queue(&wq); | |
169 | ||
170 | /* tally up the counts */ | |
171 | for (i = 0; i < mp->m_sb.sb_agcount; i++) | |
172 | j += counts[i]; | |
173 | ||
2bd0ea18 | 174 | } while (j != 0); |
8100dd79 DC |
175 | |
176 | free(counts); | |
177 | ||
06fbdda9 | 178 | print_final_rpt(); |
2bd0ea18 | 179 | } |