xfs
[Top] [All Lists]

Re: How to find the inodes in XFS

To: Felipe Monteiro de Carvalho <felipemonteiro.carvalho@xxxxxxxxx>
Subject: Re: How to find the inodes in XFS
From: Eric Sandeen <sandeen@xxxxxxxxxxx>
Date: Fri, 25 Apr 2014 17:28:45 -0500
Cc: xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <CACyNnZPV89C87DggE4fiJX+_r3zh1hKhcX3ExmXRzpLLhWJ6CQ@xxxxxxxxxxxxxx>
References: <CACyNnZMtP87y6VHum+J4xKEZqaYp2YERVnt3YuaCmeiZBmMTzQ@xxxxxxxxxxxxxx> <5359912A.70603@xxxxxxxxxxx> <CACyNnZPV89C87DggE4fiJX+_r3zh1hKhcX3ExmXRzpLLhWJ6CQ@xxxxxxxxxxxxxx>
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.4.0
On 4/25/14, 4:51 PM, Felipe Monteiro de Carvalho wrote:
> Thanks a lot! That's really helpful =)
> 
> Unfortunately something is going wrong here, and the implementation of
> XFS_INO_TO_FSB is quite intrincated, enough that it is hard to be sure
> what is wrong here ... I am trying to resolve the location of the root
> inode, which has number 128, but my XFS_INO_TO_FSB call is resolving
> to $80000 which is not an inode.

Then perhaps you have mp set up wrong?  Or maybe it's an endian isue?

If I stuff:

printf("%lld\n", XFS_INO_TO_FSB(mp, 128));

into, say, xfs_repair where we have a valid mp, I get "8"

And xfs_db agrees:

xfs_db> inode 128
xfs_db> fsblock
current fsblock is 8
xfs_db>


> XFS_INO_AGINO_BITS returns m_agino_log which is defined as sb_inopblog
> + sb_agblklog. Both are zero here, so this whole part resolves to
> zero.

0, really?

        __uint16_t      sb_inopblock;   /* inodes per block */
        __uint8_t       sb_inopblog;    /* log2 of sb_inopblock */

Even with maximally-sized inodes at 2k, sb_inopblog would be 1.


> About sb_agcount I read and reread the code and it is really hard to
> figure what number it should have in this part of the code, but in my
> superblock it comes with value 4, so I am using this.
> 
> XFS_INO_TO_AGNO = (i) shr XFS_INO_AGINO_BITS, with i (inode nr) =128
> shr 0 = so this part resolves to 128
> 
> XFS_INO_TO_AGBNO = (i shr XFS_INO_OFFSET_BITS(m_sb)) and
> XFS_INO_MASK(XFS_INO_AGBNO_BITS(m_sb));
> 
> XFS_INO_OFFSET_BITS = sb_inopblog which is 0 in my partition
> 
> XFS_INO_AGBNO_BITS = sb_agblklog which is 0 in my partition

That doesn't sound right:

xfs_db> sb 0
xfs_db> p inopblog
inopblog = 4
xfs_db> p agblklog
agblklog = 20
xfs_db> 

-Eric


> XFS_INO_MASK = (1 shl k) - 1; with k=0 it resolves to 0
> 
> #define XFS_INO_TO_AGBNO(mp,i) \
> (((xfs_agblock_t)(i) >> XFS_INO_OFFSET_BITS(mp)) & \
> XFS_INO_MASK(XFS_INO_AGBNO_BITS(mp)))
> 
> With i=128 >> 0 we get 0, but then we have & 0, so this whole part
> resolves to zero
> 
> So now we are left with         XFS_AGB_TO_FSB(mp, 128, 0)
> 
> #define XFS_AGB_TO_FSB(mp,agno,agbno) \
> (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno))
> 
> Which resolves to 128 because 128 << 0 | 0 = 128
> 
> So I calculate 128 * block_size, I have a blocksize of $1000 in my
> supernode, so that's how I arrived at $80000
> 
> But looking inside my partition I'm pretty sure that $80000 is not an 
> inode....
> 
> Any ideas where I got things wrong?? =( I've been trying for hours to
> figure where I got things wrong but no ideas yet =/
> 
> I can post my superblock content here if it would be helpful.
> 
> thanks again =)
> 
> Felipe Monteiro de Carvalho
> 
> On Thu, Apr 24, 2014 at 7:33 PM, Eric Sandeen <sandeen@xxxxxxxxxxx> wrote:
>> On 4/24/14, 5:09 PM, Felipe Monteiro de Carvalho wrote:
>>> Hello,
>>>
>>> I am writing an application which reads XFS partitions, so I am trying
>>> to understand the internal working of XFS. I read the documentation
>>> here: 
>>> http://www.dubeyko.com/development/FileSystems/XFS/xfs_filesystem_structure.pdf
>>>
>>> But I am stuck at a particular point. To get to the inodes I see that
>>> I should first read xfs_agi_t, no problem here, then its root field
>>> points to a block which contains xfs_inobt_block_t + a sequence of
>>> xfs_inobt_rec_t records and those records are supposed to show me
>>> where the inodes are, but there is no field in xfs_inobt_rec_t such as
>>> a block number =( Any idea how to get then the physical position in
>>> the disk where the inodes are from xfs_inobt_block_t + a sequence of
>>> xfs_inobt_rec_t?
>>
>> The inode's location is encoded in its inode number.
>>
>> See for example:
>>
>>
>> /*
>>  * Inode number format:
>>  * low inopblog bits - offset in block
>>  * next agblklog bits - block number in ag
>>  * next agno_log bits - ag number
>>  * high agno_log-agblklog-inopblog bits - 0
>>  */
>>
>>
>> #define XFS_INO_TO_FSB(mp,i)            \
>>         XFS_AGB_TO_FSB(mp, XFS_INO_TO_AGNO(mp,i), XFS_INO_TO_AGBNO(mp,i))
>>
>> -Eric
>>
>>> thanks,
>>>
>>
> 
> 
> 

<Prev in Thread] Current Thread [Next in Thread>