* [djwong-xfs:vectorized-scrub 535/556] fs/xfs/scrub/rtrefcount.c:38:8: warning: Local variable 'error' shadows outer variable [shadowVariable]
@ 2022-12-18 18:52 kernel test robot
0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2022-12-18 18:52 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: oe-kbuild-all
tree: https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git vectorized-scrub
head: 957abd6304af2759b5e5564977f40272364cf712
commit: a96f43457988aa2c72488775bcc3bd690cecb9fb [535/556] xfs: online repair of the realtime refcount btree
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (cppcheck warning):
# apt-get install cppcheck
git checkout a96f43457988aa2c72488775bcc3bd690cecb9fb
cppcheck --quiet --enable=style,performance,portability --template=gcc FILE
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
cppcheck warnings: (new ones prefixed by >>)
>> fs/xfs/scrub/rtrefcount.c:38:8: warning: Local variable 'error' shadows outer variable [shadowVariable]
int error;
^
fs/xfs/scrub/rtrefcount.c:32:8: note: Shadowed declaration
int error = 0;
^
fs/xfs/scrub/rtrefcount.c:38:8: note: Shadow variable
int error;
^
cppcheck possible warnings: (new ones prefixed by >>, may not real problems)
>> fs/xfs/scrub/rtrefcount.c:216:13: warning: Uninitialized variable: frag->rm [uninitvar]
if (frag->rm.rm_startblock < bno)
^
fs/xfs/scrub/rtrefcount.c:199:16: note: Assuming condition is false
if (target_nr == 0)
^
fs/xfs/scrub/rtrefcount.c:216:13: note: Uninitialized variable: frag->rm
if (frag->rm.rm_startblock < bno)
^
vim +/error +38 fs/xfs/scrub/rtrefcount.c
25
26 /* Set us up with the realtime refcount metadata locked. */
27 int
28 xchk_setup_rtrefcountbt(
29 struct xfs_scrub *sc)
30 {
31 struct xfs_rtgroup *rtg;
32 int error = 0;
33
34 if (xchk_need_fshook_drain(sc))
35 xchk_fshooks_enable(sc, XCHK_FSHOOKS_DRAIN);
36
37 if (xchk_could_repair(sc)) {
> 38 int error;
39
40 error = xrep_setup_rtrefcountbt(sc);
41 if (error)
42 return error;
43 }
44
45 rtg = xfs_rtgroup_get(sc->mp, sc->sm->sm_agno);
46 if (!rtg)
47 return -ENOENT;
48
49 error = xchk_setup_rt(sc);
50 if (error)
51 goto out_rtg;
52
53 error = xchk_install_live_inode(sc, rtg->rtg_refcountip);
54 if (error)
55 goto out_rtg;
56
57 error = xchk_ino_dqattach(sc);
58 if (error)
59 goto out_rtg;
60
61 error = xchk_rtgroup_init(sc, rtg->rtg_rgno, &sc->sr, XCHK_RTGLOCK_ALL);
62 out_rtg:
63 xfs_rtgroup_put(rtg);
64 return error;
65 }
66
67 /* Realtime Reference count btree scrubber. */
68
69 /*
70 * Confirming Reference Counts via Reverse Mappings
71 *
72 * We want to count the reverse mappings overlapping a refcount record
73 * (bno, len, refcount), allowing for the possibility that some of the
74 * overlap may come from smaller adjoining reverse mappings, while some
75 * comes from single extents which overlap the range entirely. The
76 * outer loop is as follows:
77 *
78 * 1. For all reverse mappings overlapping the refcount extent,
79 * a. If a given rmap completely overlaps, mark it as seen.
80 * b. Otherwise, record the fragment (in agbno order) for later
81 * processing.
82 *
83 * Once we've seen all the rmaps, we know that for all blocks in the
84 * refcount record we want to find $refcount owners and we've already
85 * visited $seen extents that overlap all the blocks. Therefore, we
86 * need to find ($refcount - $seen) owners for every block in the
87 * extent; call that quantity $target_nr. Proceed as follows:
88 *
89 * 2. Pull the first $target_nr fragments from the list; all of them
90 * should start at or before the start of the extent.
91 * Call this subset of fragments the working set.
92 * 3. Until there are no more unprocessed fragments,
93 * a. Find the shortest fragments in the set and remove them.
94 * b. Note the block number of the end of these fragments.
95 * c. Pull the same number of fragments from the list. All of these
96 * fragments should start at the block number recorded in the
97 * previous step.
98 * d. Put those fragments in the set.
99 * 4. Check that there are $target_nr fragments remaining in the list,
100 * and that they all end at or beyond the end of the refcount extent.
101 *
102 * If the refcount is correct, all the check conditions in the algorithm
103 * should always hold true. If not, the refcount is incorrect.
104 */
105 struct xchk_rtrefcnt_frag {
106 struct list_head list;
107 struct xfs_rmap_irec rm;
108 };
109
110 struct xchk_rtrefcnt_check {
111 struct xfs_scrub *sc;
112 struct list_head fragments;
113
114 /* refcount extent we're examining */
115 xfs_rgblock_t bno;
116 xfs_extlen_t len;
117 xfs_nlink_t refcount;
118
119 /* number of owners seen */
120 xfs_nlink_t seen;
121 };
122
123 /*
124 * Decide if the given rmap is large enough that we can redeem it
125 * towards refcount verification now, or if it's a fragment, in
126 * which case we'll hang onto it in the hopes that we'll later
127 * discover that we've collected exactly the correct number of
128 * fragments as the rtrefcountbt says we should have.
129 */
130 STATIC int
131 xchk_rtrefcountbt_rmap_check(
132 struct xfs_btree_cur *cur,
133 const struct xfs_rmap_irec *rec,
134 void *priv)
135 {
136 struct xchk_rtrefcnt_check *refchk = priv;
137 struct xchk_rtrefcnt_frag *frag;
138 xfs_rgblock_t rm_last;
139 xfs_rgblock_t rc_last;
140 int error = 0;
141
142 if (xchk_should_terminate(refchk->sc, &error))
143 return error;
144
145 rm_last = rec->rm_startblock + rec->rm_blockcount - 1;
146 rc_last = refchk->bno + refchk->len - 1;
147
148 /* Confirm that a single-owner refc extent is a CoW stage. */
149 if (refchk->refcount == 1 && rec->rm_owner != XFS_RMAP_OWN_COW) {
150 xchk_btree_xref_set_corrupt(refchk->sc, cur, 0);
151 return 0;
152 }
153
154 if (rec->rm_startblock <= refchk->bno && rm_last >= rc_last) {
155 /*
156 * The rmap overlaps the refcount record, so we can confirm
157 * one refcount owner seen.
158 */
159 refchk->seen++;
160 } else {
161 /*
162 * This rmap covers only part of the refcount record, so
163 * save the fragment for later processing. If the rmapbt
164 * is healthy each rmap_irec we see will be in agbno order
165 * so we don't need insertion sort here.
166 */
167 frag = kmalloc(sizeof(struct xchk_rtrefcnt_frag),
168 XCHK_GFP_FLAGS);
169 if (!frag)
170 return -ENOMEM;
171 memcpy(&frag->rm, rec, sizeof(frag->rm));
172 list_add_tail(&frag->list, &refchk->fragments);
173 }
174
175 return 0;
176 }
177
178 /*
179 * Given a bunch of rmap fragments, iterate through them, keeping
180 * a running tally of the refcount. If this ever deviates from
181 * what we expect (which is the rtrefcountbt's refcount minus the
182 * number of extents that totally covered the rtrefcountbt extent),
183 * we have a rtrefcountbt error.
184 */
185 STATIC void
186 xchk_rtrefcountbt_process_rmap_fragments(
187 struct xchk_rtrefcnt_check *refchk)
188 {
189 struct list_head worklist;
190 struct xchk_rtrefcnt_frag *frag;
191 struct xchk_rtrefcnt_frag *n;
192 xfs_rgblock_t bno;
193 xfs_rgblock_t rbno;
194 xfs_rgblock_t next_rbno;
195 xfs_nlink_t nr;
196 xfs_nlink_t target_nr;
197
198 target_nr = refchk->refcount - refchk->seen;
199 if (target_nr == 0)
200 return;
201
202 /*
203 * There are (refchk->rc.rc_refcount - refchk->nr refcount)
204 * references we haven't found yet. Pull that many off the
205 * fragment list and figure out where the smallest rmap ends
206 * (and therefore the next rmap should start). All the rmaps
207 * we pull off should start at or before the beginning of the
208 * refcount record's range.
209 */
210 INIT_LIST_HEAD(&worklist);
211 rbno = NULLRGBLOCK;
212
213 /* Make sure the fragments actually /are/ in bno order. */
214 bno = 0;
215 list_for_each_entry(frag, &refchk->fragments, list) {
> 216 if (frag->rm.rm_startblock < bno)
217 goto done;
218 bno = frag->rm.rm_startblock;
219 }
220
221 /*
222 * Find all the rmaps that start at or before the refc extent,
223 * and put them on the worklist.
224 */
225 nr = 0;
226 list_for_each_entry_safe(frag, n, &refchk->fragments, list) {
227 if (frag->rm.rm_startblock > refchk->bno || nr > target_nr)
228 break;
229 bno = frag->rm.rm_startblock + frag->rm.rm_blockcount;
230 if (bno < rbno)
231 rbno = bno;
232 list_move_tail(&frag->list, &worklist);
233 nr++;
234 }
235
236 /*
237 * We should have found exactly $target_nr rmap fragments starting
238 * at or before the refcount extent.
239 */
240 if (nr != target_nr)
241 goto done;
242
243 while (!list_empty(&refchk->fragments)) {
244 /* Discard any fragments ending at rbno from the worklist. */
245 nr = 0;
246 next_rbno = NULLRGBLOCK;
247 list_for_each_entry_safe(frag, n, &worklist, list) {
248 bno = frag->rm.rm_startblock + frag->rm.rm_blockcount;
249 if (bno != rbno) {
250 if (bno < next_rbno)
251 next_rbno = bno;
252 continue;
253 }
254 list_del(&frag->list);
255 kfree(frag);
256 nr++;
257 }
258
259 /* Try to add nr rmaps starting at rbno to the worklist. */
260 list_for_each_entry_safe(frag, n, &refchk->fragments, list) {
261 bno = frag->rm.rm_startblock + frag->rm.rm_blockcount;
262 if (frag->rm.rm_startblock != rbno)
263 goto done;
264 list_move_tail(&frag->list, &worklist);
265 if (next_rbno > bno)
266 next_rbno = bno;
267 nr--;
268 if (nr == 0)
269 break;
270 }
271
272 /*
273 * If we get here and nr > 0, this means that we added fewer
274 * items to the worklist than we discarded because the fragment
275 * list ran out of items. Therefore, we cannot maintain the
276 * required refcount. Something is wrong, so we're done.
277 */
278 if (nr)
279 goto done;
280
281 rbno = next_rbno;
282 }
283
284 /*
285 * Make sure the last extent we processed ends at or beyond
286 * the end of the refcount extent.
287 */
288 if (rbno < refchk->bno + refchk->len)
289 goto done;
290
291 /* Actually record us having seen the remaining refcount. */
292 refchk->seen = refchk->refcount;
293 done:
294 /* Delete fragments and work list. */
295 list_for_each_entry_safe(frag, n, &worklist, list) {
296 list_del(&frag->list);
297 kfree(frag);
298 }
299 list_for_each_entry_safe(frag, n, &refchk->fragments, list) {
300 list_del(&frag->list);
301 kfree(frag);
302 }
303 }
304
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-12-18 18:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-18 18:52 [djwong-xfs:vectorized-scrub 535/556] fs/xfs/scrub/rtrefcount.c:38:8: warning: Local variable 'error' shadows outer variable [shadowVariable] kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.