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 | |
parent | 47564bfb95bf370d73906fc4ae57c271e8ba96cd (diff) |
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')
-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) | |||
2787 | struct inode *inode; | 2787 | struct inode *inode; |
2788 | struct buffer_head *bh; | 2788 | struct buffer_head *bh; |
2789 | struct ext4_dir_entry_2 *de; | 2789 | struct ext4_dir_entry_2 *de; |
2790 | handle_t *handle; | 2790 | handle_t *handle = NULL; |
2791 | 2791 | ||
2792 | trace_ext4_unlink_enter(dir, dentry); | 2792 | trace_ext4_unlink_enter(dir, dentry); |
2793 | /* Initialize quotas before so that eventual writes go | 2793 | /* Initialize quotas before so that eventual writes go |
@@ -2795,14 +2795,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) | |||
2795 | dquot_initialize(dir); | 2795 | dquot_initialize(dir); |
2796 | dquot_initialize(dentry->d_inode); | 2796 | dquot_initialize(dentry->d_inode); |
2797 | 2797 | ||
2798 | handle = ext4_journal_start(dir, EXT4_HT_DIR, | ||
2799 | EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); | ||
2800 | if (IS_ERR(handle)) | ||
2801 | return PTR_ERR(handle); | ||
2802 | |||
2803 | if (IS_DIRSYNC(dir)) | ||
2804 | ext4_handle_sync(handle); | ||
2805 | |||
2806 | retval = -ENOENT; | 2798 | retval = -ENOENT; |
2807 | bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); | 2799 | bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); |
2808 | if (!bh) | 2800 | if (!bh) |
@@ -2814,6 +2806,17 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) | |||
2814 | if (le32_to_cpu(de->inode) != inode->i_ino) | 2806 | if (le32_to_cpu(de->inode) != inode->i_ino) |
2815 | goto end_unlink; | 2807 | goto end_unlink; |
2816 | 2808 | ||
2809 | handle = ext4_journal_start(dir, EXT4_HT_DIR, | ||
2810 | EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); | ||
2811 | if (IS_ERR(handle)) { | ||
2812 | retval = PTR_ERR(handle); | ||
2813 | handle = NULL; | ||
2814 | goto end_unlink; | ||
2815 | } | ||
2816 | |||
2817 | if (IS_DIRSYNC(dir)) | ||
2818 | ext4_handle_sync(handle); | ||
2819 | |||
2817 | if (!inode->i_nlink) { | 2820 | if (!inode->i_nlink) { |
2818 | ext4_warning(inode->i_sb, | 2821 | ext4_warning(inode->i_sb, |
2819 | "Deleting nonexistent file (%lu), %d", | 2822 | "Deleting nonexistent file (%lu), %d", |
@@ -2834,8 +2837,9 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) | |||
2834 | retval = 0; | 2837 | retval = 0; |
2835 | 2838 | ||
2836 | end_unlink: | 2839 | end_unlink: |
2837 | ext4_journal_stop(handle); | ||
2838 | brelse(bh); | 2840 | brelse(bh); |
2841 | if (handle) | ||
2842 | ext4_journal_stop(handle); | ||
2839 | trace_ext4_unlink_exit(dentry, retval); | 2843 | trace_ext4_unlink_exit(dentry, retval); |
2840 | return retval; | 2844 | return retval; |
2841 | } | 2845 | } |