All of lore.kernel.org
 help / color / mirror / Atom feed
From: kernel test robot <lkp@intel.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: oe-kbuild-all@lists.linux.dev
Subject: [djwong-xfs:vectorized-scrub 535/556] fs/xfs/scrub/rtrefcount.c:38:8: warning: Local variable 'error' shadows outer variable [shadowVariable]
Date: Mon, 19 Dec 2022 02:52:29 +0800	[thread overview]
Message-ID: <202212190237.R5o3MHGr-lkp@intel.com> (raw)

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

                 reply	other threads:[~2022-12-18 18:53 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202212190237.R5o3MHGr-lkp@intel.com \
    --to=lkp@intel.com \
    --cc=darrick.wong@oracle.com \
    --cc=oe-kbuild-all@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.