diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/namei.c linux-2.6.18-128.1.6_2/fs/ext3/namei.c --- linux-2.6.18-128.1.6_1/fs/ext3/namei.c 2009-08-13 19:27:12.000000000 +0530 +++ linux-2.6.18-128.1.6_2/fs/ext3/namei.c 2009-08-13 19:33:34.000000000 +0530 @@ -51,19 +51,25 @@ #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) -static struct buffer_head *ext3_append(handle_t *handle, +struct buffer_head *ext3_append(handle_t *handle, struct inode *inode, u32 *block, int *err) { struct buffer_head *bh; + struct ext3_inode_info *ei = EXT3_I(inode); + + /* with parallel dir operations all appends + * have to be serialized -bzzz */ + down(&ei->i_append_sem); *block = inode->i_size >> inode->i_sb->s_blocksize_bits; - if ((bh = ext3_bread(handle, inode, *block, 1, err))) { + bh = ext3_bread(handle, inode, *block, 1, err); + if (bh != NULL) { inode->i_size += inode->i_sb->s_blocksize; - EXT3_I(inode)->i_disksize = inode->i_size; - ext3_journal_get_write_access(handle,bh); + ei->i_disksize = inode->i_size; } + up(&ei->i_append_sem); return bh; } diff -rupN linux-2.6.18-128.1.6_1/fs/ext3/super.c linux-2.6.18-128.1.6_2/fs/ext3/super.c --- linux-2.6.18-128.1.6_1/fs/ext3/super.c 2009-08-13 19:27:12.000000000 +0530 +++ linux-2.6.18-128.1.6_2/fs/ext3/super.c 2009-08-13 19:27:40.000000000 +0530 @@ -481,6 +481,9 @@ static struct inode *ext3_alloc_inode(st ei->i_acl = EXT3_ACL_NOT_CACHED; ei->i_default_acl = EXT3_ACL_NOT_CACHED; #endif + dynlock_init(&ei->i_htree_lock); + sema_init(&ei->i_append_sem, 1); + ei->i_block_alloc_info = NULL; ei->vfs_inode.i_version = 1; diff -rupN linux-2.6.18-128.1.6_1/include/linux/ext3_fs_i.h linux-2.6.18-128.1.6_2/include/linux/ext3_fs_i.h --- linux-2.6.18-128.1.6_1/include/linux/ext3_fs_i.h 2009-08-13 19:27:12.000000000 +0530 +++ linux-2.6.18-128.1.6_2/include/linux/ext3_fs_i.h 2009-08-13 19:31:22.000000000 +0530 @@ -16,6 +16,7 @@ #ifndef _LINUX_EXT3_FS_I #define _LINUX_EXT3_FS_I +#include #include #include #include @@ -104,6 +105,10 @@ struct ext3_inode_info { /* block reservation info */ struct ext3_block_alloc_info *i_block_alloc_info; + /* following fields for parallel directory operations -bzzz */ + struct dynlock i_htree_lock; + struct semaphore i_append_sem; + __u32 i_dir_start_lookup; #ifdef CONFIG_EXT3_FS_XATTR /*