Re: xfs_repair deleting realtime files.

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

 




On Tue, 2 Oct 2012, Dave Chinner wrote:

> On Sat, Sep 29, 2012 at 04:49:03PM -0600, Anand Tiwari wrote:
> > Subject: [PATCH] xfs_repair: detect realtime extent shared by multiple
> >  records in extent map
> >
> > XFS currently can have records in extent map, which starts from unaligned start block w.r.t rextsize.
> > xfs_repair considers this as a bug (multiple claims for a real-time extent) and deletes the file.
> > This patch addresses the issue, by comparing current and previous records and make sure they are
> > contiguous and not overlapped.
> >
> > Signed-off-by: Anand Tiwari <anand.tiwari@xxxxxxxxx>
> > ---
> >  repair/dinode.c |   37 ++++++++++++++++++++++++++++++++++---
> >  1 file changed, 34 insertions(+), 3 deletions(-)
> >
> > diff --git a/repair/dinode.c b/repair/dinode.c
> > index 5a2da39..5537f1c 100644
> > --- a/repair/dinode.c
> > +++ b/repair/dinode.c
> > @@ -406,6 +406,7 @@ verify_agbno(xfs_mount_t	*mp,
> >  static int
> >  process_rt_rec(
> >  	xfs_mount_t		*mp,
> > +	xfs_bmbt_irec_t 	*prev,
> >  	xfs_bmbt_irec_t 	*irec,
> >  	xfs_ino_t		ino,
> >  	xfs_drfsbno_t		*tot,
> > @@ -413,8 +414,11 @@ process_rt_rec(
> >  {
> >  	xfs_dfsbno_t		b;
> >  	xfs_drtbno_t		ext;
> > +	xfs_drtbno_t		start_block;
> > +	xfs_filblks_t		block_count;
> >  	int			state;
> >  	int			pwe;		/* partially-written extent */
> > +	int 			rtext_remainder;	/* start block is not aligned w.r.t rextsize */
> >
> >  	/*
> >  	 * check numeric validity of the extent
> > @@ -461,12 +465,32 @@ _("malformed rt inode extent [%" PRIu64 " %" PRIu64 "] (fs rtext size = %u)\n"),
> >  		return 1;
> >  	}
> >
> > +	/* If we have start of record unaligned w.r.t to rextsize, see
> > +	 * if we are sharing this realtime extent with previous record. sharing is only
> > +	 * allowed with previous extent. fail otherwise.
> > +	 * Also, we above condition is true, align start block and block count
> > +	 */
>
> Comment format is:
>
> /*
>  * this is a
>  * multiline comment
>  */
>
> > +	rtext_remainder = irec->br_startblock % mp->m_sb.sb_rextsize;
> > +	if (rtext_remainder) {
> > +		do_warn(
> > +_("data fork in rt ino %" PRIu64 " has unalinged start block %"PRIu64 "\n"),
>                                           unaligned
>
> > +		ino,
> > +		irec->br_startblock);
>
> indent these a bit so the fact they are part of the do_warn function
> call is obvious. i.e.
>
> 		do_warn(
> 				<format string>
> 			ino, irec->br_startblock);
>
> > +		if ((prev->br_startoff + prev->br_blockcount == irec->br_startoff) &&
> > +		    (prev->br_startblock + prev->br_blockcount == irec->br_startblock)) {
> > +			start_block = irec->br_startblock + (mp->m_sb.sb_rextsize - rtext_remainder);
> > +			block_count = irec->br_blockcount - (mp->m_sb.sb_rextsize - rtext_remainder);
> > +		}
> > +	} else {
> > +		start_block = irec->br_startblock;
> > +		block_count = irec->br_blockcount;
> > +	}
>
> So this just changes the loop below not to check the first part of
> the new extent and therefore avoid the duplicate extent usage
> detection?
>
> Any plans to correct the bmapbt extents so that repeated repair runs
> don't keep warning about the same problem?
>

I was planning on fixing kernel code first and tackle this later. Let me
know if you guys think otherwise.

> > +
> >  	/*
> >  	 * set the appropriate number of extents
> >  	 * this iterates block by block, this can be optimised using extents
> >  	 */
> > -	for (b = irec->br_startblock; b < irec->br_startblock +
> > -			irec->br_blockcount; b += mp->m_sb.sb_rextsize)  {
> > +	for (b = start_block; b < start_block + block_count; b += mp->m_sb.sb_rextsize)  {
> >  		ext = (xfs_drtbno_t) b / mp->m_sb.sb_rextsize;
> >  		pwe = xfs_sb_version_hasextflgbit(&mp->m_sb) &&
> >  				irec->br_state == XFS_EXT_UNWRITTEN &&
> > @@ -548,6 +572,7 @@ process_bmbt_reclist_int(
> >  	int			check_dups,
> >  	int			whichfork)
> >  {
> > +	xfs_bmbt_irec_t		prev;
> >  	xfs_bmbt_irec_t		irec;
> >  	xfs_dfilblks_t		cp = 0;		/* prev count */
> >  	xfs_dfsbno_t		sp = 0;		/* prev start */
> > @@ -574,6 +599,11 @@ process_bmbt_reclist_int(
> >  	else
> >  		ftype = _("regular");
> >
> > +	prev.br_startoff = 0;
> > +	prev.br_blockcount = 0;
> > +	prev.br_startblock = 0;
> > +	prev.br_state = 0;
>
> 	memset(&prev, 0, sizeof(prev));
>

which one is more preferred in XFS land,
a) 	xfs_bmbt_irec_t		prev = {0};
b)	memset(&prev, 0, sizeof(prev));

my vote is "a". I already addressed other suggestions.

> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@xxxxxxxxxxxxx
>

thanks a bunch,
anand

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux