diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-02-09 09:43:39 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-02-09 09:43:39 -0500 |
commit | 931b68649d31b6b52608110f34856f8eb77adb36 (patch) | |
tree | 529614b33100e5758431696228485089107ab0e5 /fs/ext4/namei.c | |
parent | 47564bfb95bf370d73906fc4ae57c271e8ba96cd (diff) | |
download | linux-stable-931b68649d31b6b52608110f34856f8eb77adb36.tar.gz linux-stable-931b68649d31b6b52608110f34856f8eb77adb36.tar.bz2 linux-stable-931b68649d31b6b52608110f34856f8eb77adb36.zip |
ext4: start handle at the last possible moment in ext4_unlink()
Don't start the jbd2 transaction handle until after the directory
entry has been found, to minimize the amount of time that a handle is
held active.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 51841032ca03..4a27069d54ad 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2787,7 +2787,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) struct inode *inode; struct buffer_head *bh; struct ext4_dir_entry_2 *de; - handle_t *handle; + handle_t *handle = NULL; trace_ext4_unlink_enter(dir, dentry); /* Initialize quotas before so that eventual writes go @@ -2795,14 +2795,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) dquot_initialize(dir); dquot_initialize(dentry->d_inode); - handle = ext4_journal_start(dir, EXT4_HT_DIR, - EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - ext4_handle_sync(handle); - retval = -ENOENT; bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); if (!bh) @@ -2814,6 +2806,17 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) if (le32_to_cpu(de->inode) != inode->i_ino) goto end_unlink; + handle = ext4_journal_start(dir, EXT4_HT_DIR, + EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); + if (IS_ERR(handle)) { + retval = PTR_ERR(handle); + handle = NULL; + goto end_unlink; + } + + if (IS_DIRSYNC(dir)) + ext4_handle_sync(handle); + if (!inode->i_nlink) { ext4_warning(inode->i_sb, "Deleting nonexistent file (%lu), %d", @@ -2834,8 +2837,9 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) retval = 0; end_unlink: - ext4_journal_stop(handle); brelse(bh); + if (handle) + ext4_journal_stop(handle); trace_ext4_unlink_exit(dentry, retval); return retval; } |