All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.