diff options
| -rw-r--r-- | fs/ext4/ialloc.c | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 57f6eef6ccd6..52618d5a1773 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -240,56 +240,49 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
| 240 | if (fatal) | 240 | if (fatal) |
| 241 | goto error_return; | 241 | goto error_return; |
| 242 | 242 | ||
| 243 | /* Ok, now we can actually update the inode bitmaps.. */ | 243 | fatal = -ESRCH; |
| 244 | cleared = ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), | 244 | gdp = ext4_get_group_desc(sb, block_group, &bh2); |
| 245 | bit, bitmap_bh->b_data); | 245 | if (gdp) { |
| 246 | if (!cleared) | ||
| 247 | ext4_error(sb, "bit already cleared for inode %lu", ino); | ||
| 248 | else { | ||
| 249 | gdp = ext4_get_group_desc(sb, block_group, &bh2); | ||
| 250 | |||
| 251 | BUFFER_TRACE(bh2, "get_write_access"); | 246 | BUFFER_TRACE(bh2, "get_write_access"); |
| 252 | fatal = ext4_journal_get_write_access(handle, bh2); | 247 | fatal = ext4_journal_get_write_access(handle, bh2); |
| 253 | if (fatal) goto error_return; | 248 | } |
| 254 | 249 | ext4_lock_group(sb, block_group); | |
| 255 | if (gdp) { | 250 | cleared = ext4_clear_bit(bit, bitmap_bh->b_data); |
| 256 | ext4_lock_group(sb, block_group); | 251 | if (fatal || !cleared) { |
| 257 | count = ext4_free_inodes_count(sb, gdp) + 1; | 252 | ext4_unlock_group(sb, block_group); |
| 258 | ext4_free_inodes_set(sb, gdp, count); | 253 | goto out; |
| 259 | if (is_directory) { | 254 | } |
| 260 | count = ext4_used_dirs_count(sb, gdp) - 1; | ||
| 261 | ext4_used_dirs_set(sb, gdp, count); | ||
| 262 | if (sbi->s_log_groups_per_flex) { | ||
| 263 | ext4_group_t f; | ||
| 264 | |||
| 265 | f = ext4_flex_group(sbi, block_group); | ||
| 266 | atomic_dec(&sbi->s_flex_groups[f].used_dirs); | ||
| 267 | } | ||
| 268 | 255 | ||
| 269 | } | 256 | count = ext4_free_inodes_count(sb, gdp) + 1; |
| 270 | gdp->bg_checksum = ext4_group_desc_csum(sbi, | 257 | ext4_free_inodes_set(sb, gdp, count); |
| 271 | block_group, gdp); | 258 | if (is_directory) { |
| 272 | ext4_unlock_group(sb, block_group); | 259 | count = ext4_used_dirs_count(sb, gdp) - 1; |
| 273 | percpu_counter_inc(&sbi->s_freeinodes_counter); | 260 | ext4_used_dirs_set(sb, gdp, count); |
| 274 | if (is_directory) | 261 | percpu_counter_dec(&sbi->s_dirs_counter); |
| 275 | percpu_counter_dec(&sbi->s_dirs_counter); | ||
| 276 | |||
| 277 | if (sbi->s_log_groups_per_flex) { | ||
| 278 | ext4_group_t f; | ||
| 279 | |||
| 280 | f = ext4_flex_group(sbi, block_group); | ||
| 281 | atomic_inc(&sbi->s_flex_groups[f].free_inodes); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); | ||
| 285 | err = ext4_handle_dirty_metadata(handle, NULL, bh2); | ||
| 286 | if (!fatal) fatal = err; | ||
| 287 | } | 262 | } |
| 288 | BUFFER_TRACE(bitmap_bh, "call ext4_handle_dirty_metadata"); | 263 | gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); |
| 289 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | 264 | ext4_unlock_group(sb, block_group); |
| 290 | if (!fatal) | 265 | |
| 291 | fatal = err; | 266 | percpu_counter_inc(&sbi->s_freeinodes_counter); |
| 292 | sb->s_dirt = 1; | 267 | if (sbi->s_log_groups_per_flex) { |
| 268 | ext4_group_t f = ext4_flex_group(sbi, block_group); | ||
| 269 | |||
| 270 | atomic_inc(&sbi->s_flex_groups[f].free_inodes); | ||
| 271 | if (is_directory) | ||
| 272 | atomic_dec(&sbi->s_flex_groups[f].used_dirs); | ||
| 273 | } | ||
| 274 | BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); | ||
| 275 | fatal = ext4_handle_dirty_metadata(handle, NULL, bh2); | ||
| 276 | out: | ||
| 277 | if (cleared) { | ||
| 278 | BUFFER_TRACE(bitmap_bh, "call ext4_handle_dirty_metadata"); | ||
| 279 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | ||
| 280 | if (!fatal) | ||
| 281 | fatal = err; | ||
| 282 | sb->s_dirt = 1; | ||
| 283 | } else | ||
| 284 | ext4_error(sb, "bit already cleared for inode %lu", ino); | ||
| 285 | |||
| 293 | error_return: | 286 | error_return: |
| 294 | brelse(bitmap_bh); | 287 | brelse(bitmap_bh); |
| 295 | ext4_std_error(sb, fatal); | 288 | ext4_std_error(sb, fatal); |
