diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-08-16 22:06:14 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-08-16 22:06:14 -0400 |
commit | 5b61de757535095c99212c1ed857c3a0e0bbe386 (patch) | |
tree | f09415201c98595e10e5fdb84a2e39bd97e9a554 /fs/ext4 | |
parent | 7869a4a6c5caa7b2e5c41ccaf46eb3371f88eea7 (diff) |
ext4: start handle at least possible moment when renaming files
In ext4_rename(), don't start the journal handle until the the
directory entries have been successfully looked up.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/namei.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 35f55a0dbc4b..d9b721c172a6 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -3009,7 +3009,7 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle, | |||
3009 | static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | 3009 | static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, |
3010 | struct inode *new_dir, struct dentry *new_dentry) | 3010 | struct inode *new_dir, struct dentry *new_dentry) |
3011 | { | 3011 | { |
3012 | handle_t *handle; | 3012 | handle_t *handle = NULL; |
3013 | struct inode *old_inode, *new_inode; | 3013 | struct inode *old_inode, *new_inode; |
3014 | struct buffer_head *old_bh, *new_bh, *dir_bh; | 3014 | struct buffer_head *old_bh, *new_bh, *dir_bh; |
3015 | struct ext4_dir_entry_2 *old_de, *new_de; | 3015 | struct ext4_dir_entry_2 *old_de, *new_de; |
@@ -3026,14 +3026,6 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
3026 | * in separate transaction */ | 3026 | * in separate transaction */ |
3027 | if (new_dentry->d_inode) | 3027 | if (new_dentry->d_inode) |
3028 | dquot_initialize(new_dentry->d_inode); | 3028 | dquot_initialize(new_dentry->d_inode); |
3029 | handle = ext4_journal_start(old_dir, EXT4_HT_DIR, | ||
3030 | (2 * EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) + | ||
3031 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2)); | ||
3032 | if (IS_ERR(handle)) | ||
3033 | return PTR_ERR(handle); | ||
3034 | |||
3035 | if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) | ||
3036 | ext4_handle_sync(handle); | ||
3037 | 3029 | ||
3038 | old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de, NULL); | 3030 | old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de, NULL); |
3039 | /* | 3031 | /* |
@@ -3056,6 +3048,16 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
3056 | new_bh = NULL; | 3048 | new_bh = NULL; |
3057 | } | 3049 | } |
3058 | } | 3050 | } |
3051 | |||
3052 | handle = ext4_journal_start(old_dir, EXT4_HT_DIR, | ||
3053 | (2 * EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) + | ||
3054 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2)); | ||
3055 | if (IS_ERR(handle)) | ||
3056 | return PTR_ERR(handle); | ||
3057 | |||
3058 | if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) | ||
3059 | ext4_handle_sync(handle); | ||
3060 | |||
3059 | if (S_ISDIR(old_inode->i_mode)) { | 3061 | if (S_ISDIR(old_inode->i_mode)) { |
3060 | if (new_inode) { | 3062 | if (new_inode) { |
3061 | retval = -ENOTEMPTY; | 3063 | retval = -ENOTEMPTY; |
@@ -3195,7 +3197,8 @@ end_rename: | |||
3195 | brelse(dir_bh); | 3197 | brelse(dir_bh); |
3196 | brelse(old_bh); | 3198 | brelse(old_bh); |
3197 | brelse(new_bh); | 3199 | brelse(new_bh); |
3198 | ext4_journal_stop(handle); | 3200 | if (handle) |
3201 | ext4_journal_stop(handle); | ||
3199 | if (retval == 0 && force_da_alloc) | 3202 | if (retval == 0 && force_da_alloc) |
3200 | ext4_alloc_da_blocks(old_inode); | 3203 | ext4_alloc_da_blocks(old_inode); |
3201 | return retval; | 3204 | return retval; |