Re: [PATCH 18/30] xfs: scrub inode btrees

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Oct 16, 2017 at 01:55:59PM +1100, Dave Chinner wrote:
> On Wed, Oct 11, 2017 at 06:42:41PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> > 
> > Check the records of the inode btrees to make sure that the values
> > make sense given the inode records themselves.
> 
> .....
> 
> I think maybe I missed this first time around...
> 
> > +/* Check a particular inode with ir_free. */
> > +STATIC int
> > +xfs_scrub_iallocbt_check_cluster_freemask(
> > +	struct xfs_scrub_btree		*bs,
> > +	xfs_ino_t			fsino,
> > +	xfs_agino_t			chunkino,
> > +	xfs_agino_t			clusterino,
> > +	struct xfs_inobt_rec_incore	*irec,
> > +	struct xfs_buf			*bp)
> > +{
> > +	struct xfs_dinode		*dip;
> > +	struct xfs_mount		*mp = bs->cur->bc_mp;
> > +	bool				freemask_ok;
> > +	bool				inuse;
> > +	int				error;
> > +
> > +	dip = xfs_buf_offset(bp, clusterino * mp->m_sb.sb_inodesize);
> > +	if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC ||
> > +	    (dip->di_version >= 3 &&
> > +	     be64_to_cpu(dip->di_ino) != fsino + clusterino)) {
> > +		xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0);
> > +		goto out;
> > +	}
> > +
> > +	freemask_ok = (irec->ir_free & XFS_INOBT_MASK(chunkino + clusterino));
> 
> Ok, so if the inode if free, the corresponding bit in the mask
> will be set....
> 
> > +	error = xfs_icache_inode_is_allocated(mp, bs->cur->bc_tp,
> > +			fsino + clusterino, &inuse);
> > +	if (error == -ENODATA) {
> > +		/* Not cached, just read the disk buffer */
> > +		freemask_ok ^= !!(dip->di_mode);
> 
> And this uses the lowest bit of the mask? How does that work?
> 
> /me spends 10 minutes trying to work out this function before he
> realises that freemask_ok is a boolean, so the initial freemask
> bit is collapsed down to a single bit.
> 
> Ok, that's definitely unexpected and not obvious from the code or
> comments. The name "freemask_ok" is misleading the way it's used.
> The first time it is set is means "inode is free", then after this
> operation it means "inode matches free mask"....

Ugh, sorry.  Thank you for complaining about this!

> 
> > +		if (!bs->sc->try_harder && !freemask_ok)
> > +			return -EDEADLOCK;
> > +	} else if (error < 0) {
> > +		/*
> > +		 * Inode is only half assembled, or there was an IO error,
> > +		 * or the verifier failed, so don't bother trying to check.
> > +		 * The inode scrubber can deal with this.
> > +		 */
> > +		freemask_ok = true;
> 
> And here it means "we didn't check the free mask"
> 
> > +	} else {
> > +		/* Inode is all there. */
> > +		freemask_ok ^= inuse;
> 
> And here is means "inode matches free mask" again....
> 
> > +	}
> > +	if (!freemask_ok)
> > +		xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0);
> > +out:
> > +	return 0;
> 
> Can we rewrite this to be a little more obvious?
> 
> 	bool		inode_is_free = false;
> 	bool		freemask_ok;
> ....
> 	if (irec->ir_free & XFS_INOBT_MASK(chunkino + clusterino))
> 		inode_is_free = true;
> ....
> 	if (error == -ENODATA) {
> 		freemask_ok = inode_is_free ^ !!(dip->di_mode);
> ....
> 	else if (error < 0) {
> 		/*
> 		 * Inode is only half assembled, .....
> 		 */
> 		goto out;
> 	} else {
> 		freemask_ok = inode_is_free ^ inuse;
> 	}
> 
> That's a lot more obvious what the code is checking...

Done.

> 
> > +/* Scrub an inobt/finobt record. */
> > +STATIC int
> > +xfs_scrub_iallocbt_helper(
> 
> s/helper/rec/

Done.

--D

> 
> -Dave.
> -- 
> Dave Chinner
> david@xxxxxxxxxxxxx
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux