diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-02-09 09:45:11 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-02-09 09:45:11 -0500 |
commit | 8dcfaad244cdfa245cc2b4ddf42cea5fd8b80ece (patch) | |
tree | 7045f5bebd461b6f2cf3e43c008f4d150232e05a /fs/ext4 | |
parent | 931b68649d31b6b52608110f34856f8eb77adb36 (diff) |
ext4: start handle at the last possible moment in ext4_rmdir()
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 4a27069d54ad..36a4afd12f39 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -2725,26 +2725,18 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) | |||
2725 | struct inode *inode; | 2725 | struct inode *inode; |
2726 | struct buffer_head *bh; | 2726 | struct buffer_head *bh; |
2727 | struct ext4_dir_entry_2 *de; | 2727 | struct ext4_dir_entry_2 *de; |
2728 | handle_t *handle; | 2728 | handle_t *handle = NULL; |
2729 | 2729 | ||
2730 | /* Initialize quotas before so that eventual writes go in | 2730 | /* Initialize quotas before so that eventual writes go in |
2731 | * separate transaction */ | 2731 | * separate transaction */ |
2732 | dquot_initialize(dir); | 2732 | dquot_initialize(dir); |
2733 | dquot_initialize(dentry->d_inode); | 2733 | dquot_initialize(dentry->d_inode); |
2734 | 2734 | ||
2735 | handle = ext4_journal_start(dir, EXT4_HT_DIR, | ||
2736 | EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); | ||
2737 | if (IS_ERR(handle)) | ||
2738 | return PTR_ERR(handle); | ||
2739 | |||
2740 | retval = -ENOENT; | 2735 | retval = -ENOENT; |
2741 | bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); | 2736 | bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); |
2742 | if (!bh) | 2737 | if (!bh) |
2743 | goto end_rmdir; | 2738 | goto end_rmdir; |
2744 | 2739 | ||
2745 | if (IS_DIRSYNC(dir)) | ||
2746 | ext4_handle_sync(handle); | ||
2747 | |||
2748 | inode = dentry->d_inode; | 2740 | inode = dentry->d_inode; |
2749 | 2741 | ||
2750 | retval = -EIO; | 2742 | retval = -EIO; |
@@ -2755,6 +2747,17 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) | |||
2755 | if (!empty_dir(inode)) | 2747 | if (!empty_dir(inode)) |
2756 | goto end_rmdir; | 2748 | goto end_rmdir; |
2757 | 2749 | ||
2750 | handle = ext4_journal_start(dir, EXT4_HT_DIR, | ||
2751 | EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); | ||
2752 | if (IS_ERR(handle)) { | ||
2753 | retval = PTR_ERR(handle); | ||
2754 | handle = NULL; | ||
2755 | goto end_rmdir; | ||
2756 | } | ||
2757 | |||
2758 | if (IS_DIRSYNC(dir)) | ||
2759 | ext4_handle_sync(handle); | ||
2760 | |||
2758 | retval = ext4_delete_entry(handle, dir, de, bh); | 2761 | retval = ext4_delete_entry(handle, dir, de, bh); |
2759 | if (retval) | 2762 | if (retval) |
2760 | goto end_rmdir; | 2763 | goto end_rmdir; |
@@ -2776,8 +2779,9 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) | |||
2776 | ext4_mark_inode_dirty(handle, dir); | 2779 | ext4_mark_inode_dirty(handle, dir); |
2777 | 2780 | ||
2778 | end_rmdir: | 2781 | end_rmdir: |
2779 | ext4_journal_stop(handle); | ||
2780 | brelse(bh); | 2782 | brelse(bh); |
2783 | if (handle) | ||
2784 | ext4_journal_stop(handle); | ||
2781 | return retval; | 2785 | return retval; |
2782 | } | 2786 | } |
2783 | 2787 | ||