[Ocfs2-devel] [PATCH 2/2] ocfs2: Adjust rightmost path in ocfs2_add_branch.

Mark Fasheh mfasheh at suse.com
Fri Jun 12 09:13:02 PDT 2009


On Fri, Jun 12, 2009 at 02:18:36PM +0800, Tao Ma wrote:
> In ocfs2_add_branch, we use the rightmost rec of the leaf extent block
> to generate the e_cpos for the new added branch. In the most case, it
> is OK but if there is a gap between the the root(or branch) 's rightmost
> rec and the leaf, it will cause kernel panic if we insert some clusters
> in it. The message is something like:
> (7445,1):ocfs2_insert_at_leaf:3775 ERROR: bug expression:
> le16_to_cpu(el->l_next_free_rec) >= le16_to_cpu(el->l_count)
> (7445,1):ocfs2_insert_at_leaf:3775 ERROR: inode 66053, depth 0, count 28,
> next free 28, rec.cpos 270, rec.clusters 1, insert.cpos 275, insert.clusters 1
>  [<fa7ad565>] ? ocfs2_do_insert_extent+0xb58/0xda0 [ocfs2]
>  [<fa7b08f2>] ? ocfs2_insert_extent+0x5bd/0x6ba [ocfs2]
>  [<fa7b1b8b>] ? ocfs2_add_clusters_in_btree+0x37f/0x564 [ocfs2]
> ...
> 
> The panic can be easily reproduced by the following small test case
> (with bs=512, cs=4K, and I remove all the error handling so that it looks
> clear enough for reading).
> 
> int main(int argc, char **argv)
> {
> 	int fd, i;
> 	char buf[5] = "test";
> 
> 	fd = open(argv[1], O_RDWR|O_CREAT);
> 
> 	for (i = 0; i < 30; i++) {
> 		lseek(fd, 40960 * i, SEEK_SET);
> 		write(fd, buf, 5);
> 	}
> 
> 	ftruncate(fd, 1146880);
> 
> 	lseek(fd, 1126400, SEEK_SET);
> 	write(fd, buf, 5);
> 
> 	close(fd);
> 
> 	return 0;
> }
> 
> The reason of the panic is that:
> the 30 writes and the ftruncate makes the file's extent list looks like:
> 
> 	Tree Depth: 1   Count: 19   Next Free Rec: 1
> 	## Offset        Clusters       Block#
> 	0  0             280            86183
> 	SubAlloc Bit: 7   SubAlloc Slot: 0
> 	Blknum: 86183   Next Leaf: 0
> 	CRC32: 00000000   ECC: 0000
> 	Tree Depth: 0   Count: 28   Next Free Rec: 28
> 	## Offset        Clusters       Block#          Flags
> 	0  0             1              143368          0x0
> 	1  10            1              143376          0x0
> 	...
> 	26 260           1              143576          0x0
> 	27 270           1              143584          0x0
> 
> Now another write at 1126400(275 cluster) whiich will write at the gap
> between 271 and 280 will trigger ocfs2_add_branch, but the result after
> the function looks like:
> 	Tree Depth: 1   Count: 19   Next Free Rec: 1
> 	## Offset        Clusters       Block#
> 	0  0             280            86183
> 	0  271           0             143592
> So the extent record is intersected and make the following operation bug out.
> 
> This patch just try to remove the gap before we add the new branch, so that
> the root(branch) rightmost rec will cover the same right position. So in the
> above case, before adding branch the tree will be changed to
> 	Tree Depth: 1   Count: 19   Next Free Rec: 1
> 	## Offset        Clusters       Block#
> 	0  0             271            86183
> 	SubAlloc Bit: 7   SubAlloc Slot: 0
> 	Blknum: 86183   Next Leaf: 0
> 	CRC32: 00000000   ECC: 0000
> 	Tree Depth: 0   Count: 28   Next Free Rec: 28
> 	## Offset        Clusters       Block#          Flags
> 	0  0             1              143368          0x0
> 	1  10            1              143376          0x0
> 	...
> 	26 260           1              143576          0x0
> 	27 270           1              143584          0x0
> And after branch add, the tree looks like
> 	Tree Depth: 1   Count: 19   Next Free Rec: 1
> 	## Offset        Clusters       Block#
> 	0  0             271            86183
> 	0  271           0             143592
> 
> 
> Signed-off-by: Tao Ma <tao.ma at oracle.com>
Acked-by: Mark Fasheh <mfasheh at suse.com>


--
Mark Fasheh



More information about the Ocfs2-devel mailing list