Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Jun 2004 04:14:42 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Brian Bergstrand <brian@classicalguitar.net>
Cc:        fs@freebsd.org
Subject:   Re: Ext2 vs UFS getlbns
Message-ID:  <20040612035325.D15028@gamplex.bde.org>
In-Reply-To: <D517B455-BBC4-11D8-8C2A-0003930A674E@classicalguitar.net>
References:  <D517B455-BBC4-11D8-8C2A-0003930A674E@classicalguitar.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 11 Jun 2004, Brian Bergstrand wrote:

> I just noticed something in ext2_getlbns() (ext2_bmap.c, v1.57) vs.
> ufs_getlbns() (ufs_bmap.c, v1.60)
>
> In the last loop to setup the indir array,
>
> UFS does:
>
> {
> ...
> blockcnt /= MNINDIR(ump);
> off = (bn / blockcnt) % MNINDIR(ump);
>
> ++numlevels;
> ap->in_lbn = metalbn;
> ap->in_off = off;
> ap->in_exists = 0;
> ++ap;
>
> metalbn -= -1 + off * blockcnt;
> }
>
> While Ext2 does:
>
> {
> ...
> off = (bn / blockcnt) % MNINDIR(ump);
>
> ++numlevels;
> ap->in_lbn = metalbn;
> ap->in_off = off;
> ap->in_exists = 0;
> ++ap;
>
> metalbn -= -1 + off * blockcnt;
> blockcnt /= MNINDIR(ump);
> }
>
> Notice that blockcnt is changed AFTER offset/metalbn in Ext2 and BEFORE
> those in UFS.
>
> Was this change in Ext2 done on purpose for some reason? It makes a
> difference in calculating in_off and metalbn for some block #'s.

This is to fix overflow in the calculation of block numbers for triple
indirect blocks.  ffs used to do this, and ext2_getlbns() was a copy
ufs_getlbns(), but ffs was changed back to use simpler code when its
daddr type (ufs2_daddr_t) was changed to 64 bits and the longs in
ufs_getlbns() were fixed to use ufs_daddr_t.  Overflow is probably
theoretically possible again, but it would take a 128-bit calculation
to avoid it and 64 bit block numbers should be enough for anyone.

This difference shouldn't affect in_off or metalbn for any reachable
block number (32 bit ones in ext2fs).  There is another variable
"int64_t qblockcnt" that is used instead of "long blockcnt" in
some places in ext2_getlbns().  The logic for using blockcnt in the
above is a little different because earlier calculations set
qblockcnt instead of qblockcnt.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040612035325.D15028>