diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/inode.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index eb0b4e0d517b..cd098a7b77fc 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -2903,6 +2903,10 @@ static int ext3_do_update_inode(handle_t *handle, | |||
2903 | struct buffer_head *bh = iloc->bh; | 2903 | struct buffer_head *bh = iloc->bh; |
2904 | int err = 0, rc, block; | 2904 | int err = 0, rc, block; |
2905 | 2905 | ||
2906 | again: | ||
2907 | /* we can't allow multiple procs in here at once, its a bit racey */ | ||
2908 | lock_buffer(bh); | ||
2909 | |||
2906 | /* For fields not not tracking in the in-memory inode, | 2910 | /* For fields not not tracking in the in-memory inode, |
2907 | * initialise them to zero for new inodes. */ | 2911 | * initialise them to zero for new inodes. */ |
2908 | if (ei->i_state & EXT3_STATE_NEW) | 2912 | if (ei->i_state & EXT3_STATE_NEW) |
@@ -2962,16 +2966,20 @@ static int ext3_do_update_inode(handle_t *handle, | |||
2962 | /* If this is the first large file | 2966 | /* If this is the first large file |
2963 | * created, add a flag to the superblock. | 2967 | * created, add a flag to the superblock. |
2964 | */ | 2968 | */ |
2969 | unlock_buffer(bh); | ||
2965 | err = ext3_journal_get_write_access(handle, | 2970 | err = ext3_journal_get_write_access(handle, |
2966 | EXT3_SB(sb)->s_sbh); | 2971 | EXT3_SB(sb)->s_sbh); |
2967 | if (err) | 2972 | if (err) |
2968 | goto out_brelse; | 2973 | goto out_brelse; |
2974 | |||
2969 | ext3_update_dynamic_rev(sb); | 2975 | ext3_update_dynamic_rev(sb); |
2970 | EXT3_SET_RO_COMPAT_FEATURE(sb, | 2976 | EXT3_SET_RO_COMPAT_FEATURE(sb, |
2971 | EXT3_FEATURE_RO_COMPAT_LARGE_FILE); | 2977 | EXT3_FEATURE_RO_COMPAT_LARGE_FILE); |
2972 | handle->h_sync = 1; | 2978 | handle->h_sync = 1; |
2973 | err = ext3_journal_dirty_metadata(handle, | 2979 | err = ext3_journal_dirty_metadata(handle, |
2974 | EXT3_SB(sb)->s_sbh); | 2980 | EXT3_SB(sb)->s_sbh); |
2981 | /* get our lock and start over */ | ||
2982 | goto again; | ||
2975 | } | 2983 | } |
2976 | } | 2984 | } |
2977 | } | 2985 | } |
@@ -2994,6 +3002,7 @@ static int ext3_do_update_inode(handle_t *handle, | |||
2994 | raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); | 3002 | raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); |
2995 | 3003 | ||
2996 | BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); | 3004 | BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); |
3005 | unlock_buffer(bh); | ||
2997 | rc = ext3_journal_dirty_metadata(handle, bh); | 3006 | rc = ext3_journal_dirty_metadata(handle, bh); |
2998 | if (!err) | 3007 | if (!err) |
2999 | err = rc; | 3008 | err = rc; |