Index: linux-stage/fs/ext4/ext4.h =================================================================== --- linux-stage.orig/fs/ext4/ext4.h 2012-08-07 11:52:38.994200699 -0700 +++ linux-stage/fs/ext4/ext4.h 2012-08-07 12:28:19.497442862 -0700 @@ -706,6 +707,9 @@ __u32 i_dtime; ext4_fsblk_t i_file_acl; + /* following fields for parallel directory operations -bzzz */ + 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, Index: linux-stage/fs/ext4/namei.c =================================================================== --- linux-stage.orig/fs/ext4/namei.c 2012-08-07 11:52:38.992199430 -0700 +++ linux-stage/fs/ext4/namei.c 2012-08-07 12:27:24.845281099 -0700 @@ -53,6 +53,11 @@ 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; @@ -65,7 +70,9 @@ brelse(bh); bh = NULL; } + ei->i_disksize = inode->i_size; } + up(&ei->i_append_sem); return bh; } Index: linux-stage/fs/ext4/super.c =================================================================== --- linux-stage.orig/fs/ext4/super.c 2012-08-07 11:52:39.009197356 -0700 +++ linux-stage/fs/ext4/super.c 2012-08-07 12:28:29.499112997 -0700 @@ -749,6 +749,7 @@ ei->vfs_inode.i_version = 1; ei->vfs_inode.i_data.writeback_index = 0; + 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);