[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120803183320.GU58276@kernel.stglabs.ibm.com>
Date: Fri, 3 Aug 2012 14:33:20 -0400
From: "Darrick J. Wong" <djwong@...ibm.com>
To: Wang Sheng-Hui <shhuiw@...il.com>
Cc: "Theodore Ts'o" <tytso@....edu>,
linux-ext4 <linux-ext4@...r.kernel.org>
Subject: Re: How to understand get_dx_countlimit?
On Wed, Aug 01, 2012 at 10:50:25PM +0800, Wang Sheng-Hui wrote:
> Dear all,
>
> Sorry to trouble you!
>
> I'm confused by the namei.c/get_dx_countlimit.
> This function seems support metadata checksum for dir/dx.
>
> I wonder what kind of dirent would meet:
>
> le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)
>
> The tail dirent of one dir block?
This case usually indicates that there's one big "empty" dirent that's hiding
some dx hash tree data. These ought to be non-root dx tree nodes.
> And the case "le16_to_cpu(dirent->rec_len) == 12"?
In a hashed directory, the first block (i.e. the root of the dx tree, if there
even is a tree) uses the first 24 bytes to present dirents for "." and "..". The
remaining space is a big "empty" dirent that hides the root of the dx tree.
> I suspect these kinds of dirents are the tail ones, but
> I cannot figure out the physical layout for one dir block
> with metadat checksum, e.g in which case we would have dirents
> meet the conditions in the function get_dx_countlimit?
FYI, there's some (slightly out of date) additional reference data at
https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout.
Before hashed directories, a directory file consisted of variable-length
dirents that weren't in any particular order. The dirents are packed in
such a way that they do not cross $BLOCKSIZE (usually 4KiB) boundaries. To add
metadata checksumming to one of these classic dirent blocks, I create an empty
"dirent" in the last 12 bytes of the block that looks deleted, and stuff the
crc32 into the name field. Obviously, if there's no room in the block then
e2fsck has to rebuild the directory.
When hashed directories were added, it was desired to retrofit them into the
existing directory file structure in such a way that the old code could read
the directory file without getting confused by the tree data. Furthermore, it
was decided that tree data should not be mixed in with regular dirents, i.e.
given a block in a directory, it either contains tree data or dirents pointing
to inodes, but not both.
To accomplish that, a block containing tree data is given a dirent header that
doesn't point to an inode ("null dirent"), since dirents that don't point to
valid inodes are skipped over by the old ext2 code. The dirent header claims
to take up all the space in the block, and the tree data goes in the space that
normally stores the file name. If metadata checksumming is enabled, the last
dx_entry in the tree block is reserved for storing the checksum.
There is one exception to what I just wrote -- the old ext2 code expects the
first block of a directory file to contain (at offset zero) two dirents
pointing to "." and "..". Therefore, the root of the tree is encapsulated
inside a null dirent (just like the non-root nodes, as I describe above) but
the null dirent begins 24 bytes into that first block, instead of at the very
beginning of the block.
Hope that doesn't muddy the situation any more....
--D
>
> Any explanations are welcomed!
>
> Thanks,
> Sheng-Hui
>
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists