diff options
| author | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-01 11:08:43 -0400 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-01 11:08:43 -0400 |
| commit | c0d268c3661efdfc76dde90ff2bc12806410cd0a (patch) | |
| tree | c5db188c6ce105b26d392099e15635fa7c9e419d | |
| parent | da1ce0670c14d8380e423a3239e562a1dc15fa9e (diff) | |
ext4: rename: create ext4_renament structure for local vars
Need to split up ext4_rename() into helpers but there are too many local
variables involved, so create a new structure. This also, apparently,
makes the generated code size slightly smaller.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Reviewed-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/ext4/namei.c | 211 |
1 files changed, 114 insertions, 97 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5f19171b3e1f..7193cea805ff 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -3000,6 +3000,22 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle, | |||
| 3000 | return ext4_get_first_inline_block(inode, parent_de, retval); | 3000 | return ext4_get_first_inline_block(inode, parent_de, retval); |
| 3001 | } | 3001 | } |
| 3002 | 3002 | ||
| 3003 | struct ext4_renament { | ||
| 3004 | struct inode *dir; | ||
| 3005 | struct dentry *dentry; | ||
| 3006 | struct inode *inode; | ||
| 3007 | |||
| 3008 | /* entry for "dentry" */ | ||
| 3009 | struct buffer_head *bh; | ||
| 3010 | struct ext4_dir_entry_2 *de; | ||
| 3011 | int inlined; | ||
| 3012 | |||
| 3013 | /* entry for ".." in inode if it's a directory */ | ||
| 3014 | struct buffer_head *dir_bh; | ||
| 3015 | struct ext4_dir_entry_2 *parent_de; | ||
| 3016 | int dir_inlined; | ||
| 3017 | }; | ||
| 3018 | |||
| 3003 | /* | 3019 | /* |
| 3004 | * Anybody can rename anything with this: the permission checks are left to the | 3020 | * Anybody can rename anything with this: the permission checks are left to the |
| 3005 | * higher-level routines. | 3021 | * higher-level routines. |
| @@ -3012,193 +3028,194 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 3012 | struct inode *new_dir, struct dentry *new_dentry) | 3028 | struct inode *new_dir, struct dentry *new_dentry) |
| 3013 | { | 3029 | { |
| 3014 | handle_t *handle = NULL; | 3030 | handle_t *handle = NULL; |
| 3015 | struct inode *old_inode, *new_inode; | 3031 | struct ext4_renament old = { |
| 3016 | struct buffer_head *old_bh, *new_bh, *dir_bh; | 3032 | .dir = old_dir, |
| 3017 | struct ext4_dir_entry_2 *old_de, *new_de; | 3033 | .dentry = old_dentry, |
| 3034 | .inode = old_dentry->d_inode, | ||
| 3035 | }; | ||
| 3036 | struct ext4_renament new = { | ||
| 3037 | .dir = new_dir, | ||
| 3038 | .dentry = new_dentry, | ||
| 3039 | .inode = new_dentry->d_inode, | ||
| 3040 | }; | ||
| 3018 | int retval; | 3041 | int retval; |
| 3019 | int inlined = 0, new_inlined = 0; | ||
| 3020 | struct ext4_dir_entry_2 *parent_de; | ||
| 3021 | |||
| 3022 | dquot_initialize(old_dir); | ||
| 3023 | dquot_initialize(new_dir); | ||
| 3024 | 3042 | ||
| 3025 | old_bh = new_bh = dir_bh = NULL; | 3043 | dquot_initialize(old.dir); |
| 3044 | dquot_initialize(new.dir); | ||
| 3026 | 3045 | ||
| 3027 | /* Initialize quotas before so that eventual writes go | 3046 | /* Initialize quotas before so that eventual writes go |
| 3028 | * in separate transaction */ | 3047 | * in separate transaction */ |
| 3029 | if (new_dentry->d_inode) | 3048 | if (new.inode) |
| 3030 | dquot_initialize(new_dentry->d_inode); | 3049 | dquot_initialize(new.inode); |
| 3031 | 3050 | ||
| 3032 | old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de, NULL); | 3051 | old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); |
| 3033 | /* | 3052 | /* |
| 3034 | * Check for inode number is _not_ due to possible IO errors. | 3053 | * Check for inode number is _not_ due to possible IO errors. |
| 3035 | * We might rmdir the source, keep it as pwd of some process | 3054 | * We might rmdir the source, keep it as pwd of some process |
| 3036 | * and merrily kill the link to whatever was created under the | 3055 | * and merrily kill the link to whatever was created under the |
| 3037 | * same name. Goodbye sticky bit ;-< | 3056 | * same name. Goodbye sticky bit ;-< |
| 3038 | */ | 3057 | */ |
| 3039 | old_inode = old_dentry->d_inode; | ||
| 3040 | retval = -ENOENT; | 3058 | retval = -ENOENT; |
| 3041 | if (!old_bh || le32_to_cpu(old_de->inode) != old_inode->i_ino) | 3059 | if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino) |
| 3042 | goto end_rename; | 3060 | goto end_rename; |
| 3043 | 3061 | ||
| 3044 | new_inode = new_dentry->d_inode; | 3062 | new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, |
| 3045 | new_bh = ext4_find_entry(new_dir, &new_dentry->d_name, | 3063 | &new.de, &new.inlined); |
| 3046 | &new_de, &new_inlined); | 3064 | if (new.bh) { |
| 3047 | if (new_bh) { | 3065 | if (!new.inode) { |
| 3048 | if (!new_inode) { | 3066 | brelse(new.bh); |
| 3049 | brelse(new_bh); | 3067 | new.bh = NULL; |
| 3050 | new_bh = NULL; | ||
| 3051 | } | 3068 | } |
| 3052 | } | 3069 | } |
| 3053 | if (new_inode && !test_opt(new_dir->i_sb, NO_AUTO_DA_ALLOC)) | 3070 | if (new.inode && !test_opt(new.dir->i_sb, NO_AUTO_DA_ALLOC)) |
| 3054 | ext4_alloc_da_blocks(old_inode); | 3071 | ext4_alloc_da_blocks(old.inode); |
| 3055 | 3072 | ||
| 3056 | handle = ext4_journal_start(old_dir, EXT4_HT_DIR, | 3073 | handle = ext4_journal_start(old.dir, EXT4_HT_DIR, |
| 3057 | (2 * EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) + | 3074 | (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) + |
| 3058 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2)); | 3075 | EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2)); |
| 3059 | if (IS_ERR(handle)) | 3076 | if (IS_ERR(handle)) |
| 3060 | return PTR_ERR(handle); | 3077 | return PTR_ERR(handle); |
| 3061 | 3078 | ||
| 3062 | if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) | 3079 | if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) |
| 3063 | ext4_handle_sync(handle); | 3080 | ext4_handle_sync(handle); |
| 3064 | 3081 | ||
| 3065 | if (S_ISDIR(old_inode->i_mode)) { | 3082 | if (S_ISDIR(old.inode->i_mode)) { |
| 3066 | if (new_inode) { | 3083 | if (new.inode) { |
| 3067 | retval = -ENOTEMPTY; | 3084 | retval = -ENOTEMPTY; |
| 3068 | if (!empty_dir(new_inode)) | 3085 | if (!empty_dir(new.inode)) |
| 3069 | goto end_rename; | 3086 | goto end_rename; |
| 3070 | } | 3087 | } |
| 3071 | retval = -EIO; | 3088 | retval = -EIO; |
| 3072 | dir_bh = ext4_get_first_dir_block(handle, old_inode, | 3089 | old.dir_bh = ext4_get_first_dir_block(handle, old.inode, |
| 3073 | &retval, &parent_de, | 3090 | &retval, &old.parent_de, |
| 3074 | &inlined); | 3091 | &old.dir_inlined); |
| 3075 | if (!dir_bh) | 3092 | if (!old.dir_bh) |
| 3076 | goto end_rename; | 3093 | goto end_rename; |
| 3077 | if (le32_to_cpu(parent_de->inode) != old_dir->i_ino) | 3094 | if (le32_to_cpu(old.parent_de->inode) != old.dir->i_ino) |
| 3078 | goto end_rename; | 3095 | goto end_rename; |
| 3079 | retval = -EMLINK; | 3096 | retval = -EMLINK; |
| 3080 | if (!new_inode && new_dir != old_dir && | 3097 | if (!new.inode && new.dir != old.dir && |
| 3081 | EXT4_DIR_LINK_MAX(new_dir)) | 3098 | EXT4_DIR_LINK_MAX(new.dir)) |
| 3082 | goto end_rename; | 3099 | goto end_rename; |
| 3083 | BUFFER_TRACE(dir_bh, "get_write_access"); | 3100 | BUFFER_TRACE(old.dir_bh, "get_write_access"); |
| 3084 | retval = ext4_journal_get_write_access(handle, dir_bh); | 3101 | retval = ext4_journal_get_write_access(handle, old.dir_bh); |
| 3085 | if (retval) | 3102 | if (retval) |
| 3086 | goto end_rename; | 3103 | goto end_rename; |
| 3087 | } | 3104 | } |
| 3088 | if (!new_bh) { | 3105 | if (!new.bh) { |
| 3089 | retval = ext4_add_entry(handle, new_dentry, old_inode); | 3106 | retval = ext4_add_entry(handle, new.dentry, old.inode); |
| 3090 | if (retval) | 3107 | if (retval) |
| 3091 | goto end_rename; | 3108 | goto end_rename; |
| 3092 | } else { | 3109 | } else { |
| 3093 | BUFFER_TRACE(new_bh, "get write access"); | 3110 | BUFFER_TRACE(new.bh, "get write access"); |
| 3094 | retval = ext4_journal_get_write_access(handle, new_bh); | 3111 | retval = ext4_journal_get_write_access(handle, new.bh); |
| 3095 | if (retval) | 3112 | if (retval) |
| 3096 | goto end_rename; | 3113 | goto end_rename; |
| 3097 | new_de->inode = cpu_to_le32(old_inode->i_ino); | 3114 | new.de->inode = cpu_to_le32(old.inode->i_ino); |
| 3098 | if (EXT4_HAS_INCOMPAT_FEATURE(new_dir->i_sb, | 3115 | if (EXT4_HAS_INCOMPAT_FEATURE(new.dir->i_sb, |
| 3099 | EXT4_FEATURE_INCOMPAT_FILETYPE)) | 3116 | EXT4_FEATURE_INCOMPAT_FILETYPE)) |
| 3100 | new_de->file_type = old_de->file_type; | 3117 | new.de->file_type = old.de->file_type; |
| 3101 | new_dir->i_version++; | 3118 | new.dir->i_version++; |
| 3102 | new_dir->i_ctime = new_dir->i_mtime = | 3119 | new.dir->i_ctime = new.dir->i_mtime = |
| 3103 | ext4_current_time(new_dir); | 3120 | ext4_current_time(new.dir); |
| 3104 | ext4_mark_inode_dirty(handle, new_dir); | 3121 | ext4_mark_inode_dirty(handle, new.dir); |
| 3105 | BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata"); | 3122 | BUFFER_TRACE(new.bh, "call ext4_handle_dirty_metadata"); |
| 3106 | if (!new_inlined) { | 3123 | if (!new.inlined) { |
| 3107 | retval = ext4_handle_dirty_dirent_node(handle, | 3124 | retval = ext4_handle_dirty_dirent_node(handle, |
| 3108 | new_dir, new_bh); | 3125 | new.dir, new.bh); |
| 3109 | if (unlikely(retval)) { | 3126 | if (unlikely(retval)) { |
| 3110 | ext4_std_error(new_dir->i_sb, retval); | 3127 | ext4_std_error(new.dir->i_sb, retval); |
