diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-03-04 19:09:10 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-03-04 19:09:10 -0500 |
commit | 9f24e4208f7ee2748f157368b63287dc903fcf60 (patch) | |
tree | 255989fe69ebfb2b031dc7cf6dbe975df67c711a /fs/ext4/ialloc.c | |
parent | b713a5ec55bf73c833f9883cdd761b20ee61a1ab (diff) |
ext4: Use atomic_t's in struct flex_groups
Reduce pressure on the sb_bgl_lock family of locks by using atomic_t's
to track the number of free blocks and inodes in each flex_group.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r-- | fs/ext4/ialloc.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 617f5a2d800a..5f393927fd25 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -189,7 +189,6 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
189 | struct ext4_super_block *es; | 189 | struct ext4_super_block *es; |
190 | struct ext4_sb_info *sbi; | 190 | struct ext4_sb_info *sbi; |
191 | int fatal = 0, err, count, cleared; | 191 | int fatal = 0, err, count, cleared; |
192 | ext4_group_t flex_group; | ||
193 | 192 | ||
194 | if (atomic_read(&inode->i_count) > 1) { | 193 | if (atomic_read(&inode->i_count) > 1) { |
195 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", | 194 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", |
@@ -277,10 +276,10 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
277 | percpu_counter_dec(&sbi->s_dirs_counter); | 276 | percpu_counter_dec(&sbi->s_dirs_counter); |
278 | 277 | ||
279 | if (sbi->s_log_groups_per_flex) { | 278 | if (sbi->s_log_groups_per_flex) { |
280 | flex_group = ext4_flex_group(sbi, block_group); | 279 | ext4_group_t f; |
281 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 280 | |
282 | sbi->s_flex_groups[flex_group].free_inodes++; | 281 | f = ext4_flex_group(sbi, block_group); |
283 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | 282 | atomic_inc(&sbi->s_flex_groups[f].free_inodes); |
284 | } | 283 | } |
285 | } | 284 | } |
286 | BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); | 285 | BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); |
@@ -360,9 +359,9 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, | |||
360 | sbi->s_log_groups_per_flex; | 359 | sbi->s_log_groups_per_flex; |
361 | 360 | ||
362 | find_close_to_parent: | 361 | find_close_to_parent: |
363 | flexbg_free_blocks = flex_group[best_flex].free_blocks; | 362 | flexbg_free_blocks = atomic_read(&flex_group[best_flex].free_blocks); |
364 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; | 363 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; |
365 | if (flex_group[best_flex].free_inodes && | 364 | if (atomic_read(&flex_group[best_flex].free_inodes) && |
366 | flex_freeb_ratio > free_block_ratio) | 365 | flex_freeb_ratio > free_block_ratio) |
367 | goto found_flexbg; | 366 | goto found_flexbg; |
368 | 367 | ||
@@ -375,24 +374,24 @@ find_close_to_parent: | |||
375 | if (i == parent_fbg_group || i == parent_fbg_group - 1) | 374 | if (i == parent_fbg_group || i == parent_fbg_group - 1) |
376 | continue; | 375 | continue; |
377 | 376 | ||
378 | flexbg_free_blocks = flex_group[i].free_blocks; | 377 | flexbg_free_blocks = atomic_read(&flex_group[i].free_blocks); |
379 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; | 378 | flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; |
380 | 379 | ||
381 | if (flex_freeb_ratio > free_block_ratio && | 380 | if (flex_freeb_ratio > free_block_ratio && |
382 | flex_group[i].free_inodes) { | 381 | (atomic_read(&flex_group[i].free_inodes))) { |
383 | best_flex = i; | 382 | best_flex = i; |
384 | goto found_flexbg; | 383 | goto found_flexbg; |
385 | } | 384 | } |
386 | 385 | ||
387 | if (flex_group[best_flex].free_inodes == 0 || | 386 | if ((atomic_read(&flex_group[best_flex].free_inodes) == 0) || |
388 | (flex_group[i].free_blocks > | 387 | ((atomic_read(&flex_group[i].free_blocks) > |
389 | flex_group[best_flex].free_blocks && | 388 | atomic_read(&flex_group[best_flex].free_blocks)) && |
390 | flex_group[i].free_inodes)) | 389 | atomic_read(&flex_group[i].free_inodes))) |
391 | best_flex = i; | 390 | best_flex = i; |
392 | } | 391 | } |
393 | 392 | ||
394 | if (!flex_group[best_flex].free_inodes || | 393 | if (!atomic_read(&flex_group[best_flex].free_inodes) || |
395 | !flex_group[best_flex].free_blocks) | 394 | !atomic_read(&flex_group[best_flex].free_blocks)) |
396 | return -1; | 395 | return -1; |
397 | 396 | ||
398 | found_flexbg: | 397 | found_flexbg: |
@@ -960,9 +959,7 @@ got: | |||
960 | 959 | ||
961 | if (sbi->s_log_groups_per_flex) { | 960 | if (sbi->s_log_groups_per_flex) { |
962 | flex_group = ext4_flex_group(sbi, group); | 961 | flex_group = ext4_flex_group(sbi, group); |
963 | spin_lock(sb_bgl_lock(sbi, flex_group)); | 962 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); |
964 | sbi->s_flex_groups[flex_group].free_inodes--; | ||
965 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | ||
966 | } | 963 | } |
967 | 964 | ||
968 | inode->i_uid = current_fsuid(); | 965 | inode->i_uid = current_fsuid(); |