diff options
author | Mingming Cao <cmm@us.ibm.com> | 2006-03-26 04:37:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-26 11:57:01 -0500 |
commit | d48589bfad0e60bff0aa3f9e4875983f607bd44b (patch) | |
tree | 3ec6d645847ea451b15abd6c9f1f27ce93591fd9 | |
parent | faa569763a7753e0a7cb8fd3919a62c0f7cc1e3c (diff) |
[PATCH] ext3_get_blocks: Adjust reservation window size for mblocks
Optimize the block reservation and the multiple block allocation: with the
knowledge of the total number of blocks ahead, set or adjust the reservation
window size properly (based on the number of blocks needed) before block
allocation happens: if there isn't any reservation yet, make sure the
reservation window equals to or greater than the number of blocks needed,
before create an reservation window; if a reservation window is already
exists, try to extends the window size to match the number of blocks to
allocate. This could increase the possibility of completing multiple blocks
allocation in a single request, as blocks are only allocated in the range of
the inode's reservation window.
Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/ext3/balloc.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 7a2c7198b059..77927d6938f6 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1011,6 +1011,31 @@ retry: | |||
1011 | goto retry; | 1011 | goto retry; |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv, | ||
1015 | struct super_block *sb, int size) | ||
1016 | { | ||
1017 | struct ext3_reserve_window_node *next_rsv; | ||
1018 | struct rb_node *next; | ||
1019 | spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; | ||
1020 | |||
1021 | if (!spin_trylock(rsv_lock)) | ||
1022 | return; | ||
1023 | |||
1024 | next = rb_next(&my_rsv->rsv_node); | ||
1025 | |||
1026 | if (!next) | ||
1027 | my_rsv->rsv_end += size; | ||
1028 | else { | ||
1029 | next_rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); | ||
1030 | |||
1031 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | ||
1032 | my_rsv->rsv_end += size; | ||
1033 | else | ||
1034 | my_rsv->rsv_end = next_rsv->rsv_start - 1; | ||
1035 | } | ||
1036 | spin_unlock(rsv_lock); | ||
1037 | } | ||
1038 | |||
1014 | /* | 1039 | /* |
1015 | * This is the main function used to allocate a new block and its reservation | 1040 | * This is the main function used to allocate a new block and its reservation |
1016 | * window. | 1041 | * window. |
@@ -1095,6 +1120,8 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1095 | while (1) { | 1120 | while (1) { |
1096 | if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || | 1121 | if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || |
1097 | !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) { | 1122 | !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) { |
1123 | if (my_rsv->rsv_goal_size < *count) | ||
1124 | my_rsv->rsv_goal_size = *count; | ||
1098 | ret = alloc_new_reservation(my_rsv, goal, sb, | 1125 | ret = alloc_new_reservation(my_rsv, goal, sb, |
1099 | group, bitmap_bh); | 1126 | group, bitmap_bh); |
1100 | if (ret < 0) | 1127 | if (ret < 0) |
@@ -1102,7 +1129,10 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1102 | 1129 | ||
1103 | if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) | 1130 | if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) |
1104 | goal = -1; | 1131 | goal = -1; |
1105 | } | 1132 | } else if (goal > 0 && (my_rsv->rsv_end-goal+1) < *count) |
1133 | try_to_extend_reservation(my_rsv, sb, | ||
1134 | *count-my_rsv->rsv_end + goal - 1); | ||
1135 | |||
1106 | if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) | 1136 | if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) |
1107 | || (my_rsv->rsv_end < group_first_block)) | 1137 | || (my_rsv->rsv_end < group_first_block)) |
1108 | BUG(); | 1138 | BUG(); |