ext34: ensure do_split leaves enough free space in both blocks
commitf36dab894e29637bae9a58a6fb43fa66e8a94f85
authorEric Sandeen <sandeen@redhat.com>
Wed, 19 Sep 2007 05:46:42 +0000 (18 22:46 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 26 Sep 2007 17:54:40 +0000 (26 10:54 -0700)
tree14a07a4bc84db2195cc134957fc6c27bffea6bd5
parentcb67b06fd170b6b429f7ade84e2e1d428ae34548
ext34: ensure do_split leaves enough free space in both blocks

commit ef2b02d3e617cb0400eedf2668f86215e1b0e6af in mainline.

The do_split() function for htree dir blocks is intended to split a leaf
block to make room for a new entry.  It sorts the entries in the original
block by hash value, then moves the last half of the entries to the new
block - without accounting for how much space this actually moves.  (IOW,
it moves half of the entry *count* not half of the entry *space*).  If by
chance we have both large & small entries, and we move only the smallest
entries, and we have a large new entry to insert, we may not have created
enough space for it.

The patch below stores each record size when calculating the dx_map, and
then walks the hash-sorted dx_map, calculating how many entries must be
moved to more evenly split the existing entries between the old block and
the new block, guaranteeing enough space for the new entry.

The dx_map "offs" member is reduced to u16 so that the overall map size
does not change - it is temporarily stored at the end of the new block, and
if it grows too large it may be overwritten.  By making offs and size both
u16, we won't grow the map size.

Also add a few comments to the functions involved.

This fixes the testcase reported by hooanon05@yahoo.co.jp on the
linux-ext4 list, "ext3 dir_index causes an error"

Thanks to Andreas Dilger for discussing the problem & solution with me.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
Tested-by: Junjiro Okajima <hooanon05@yahoo.co.jp>
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: ext4 <linux-ext4@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/ext3/namei.c
fs/ext4/namei.c