diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/ext4_i.h linux-2.6.27.21-0.1_2//fs/ext4/ext4_i.h --- linux-2.6.27.21-0.1_1//fs/ext4/ext4.h 2009-08-24 13:00:59.000000000 +0530 +++ linux-2.6.27.21-0.1_2//fs/ext4/ext4.h 2009-08-24 13:01:25.000000000 +0530 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,9 @@ struct ext4_inode_info { __u32 i_flags; ext4_fsblk_t i_file_acl; __u32 i_dtime; - + /* following fields for parallel directory operations -bzzz */ + struct dynlock i_htree_lock; + struct semaphore i_append_sem; /* * i_block_group is the number of the block group which contains * this file's inode. Constant across the lifetime of the inode, diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/namei.c linux-2.6.27.21-0.1_2//fs/ext4/namei.c --- linux-2.6.27.21-0.1_1//fs/ext4/namei.c 2009-08-24 13:00:59.000000000 +0530 +++ linux-2.6.27.21-0.1_2//fs/ext4/namei.c 2009-08-24 13:03:45.000000000 +0530 @@ -55,6 +55,11 @@ static struct buffer_head *ext4_append(h ext4_lblk_t *block, int *err) { struct buffer_head *bh; + struct ext4_inode_info *ei = EXT4_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; @@ -67,7 +72,9 @@ static struct buffer_head *ext4_append(h brelse(bh); bh = NULL; } + ei->i_disksize = inode->i_size; } + up(&ei->i_append_sem); return bh; } diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/super.c linux-2.6.27.21-0.1_2//fs/ext4/super.c --- linux-2.6.27.21-0.1_1//fs/ext4/super.c 2009-08-24 13:00:59.000000000 +0530 +++ linux-2.6.27.21-0.1_2//fs/ext4/super.c 2009-08-24 13:01:25.000000000 +0530 @@ -635,6 +635,8 @@ static struct inode *ext4_alloc_inode(st #endif ei->vfs_inode.i_version = 1; ei->vfs_inode.i_data.writeback_index = 0; + dynlock_init(&ei->i_htree_lock); + sema_init(&ei->i_append_sem, 1); memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); INIT_LIST_HEAD(&ei->i_prealloc_list); spin_lock_init(&ei->i_prealloc_lock);