aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2006-03-26 04:37:57 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:57:01 -0500
commitb54e41ec17ae91dce174eb5a3515e7af4a440d42 (patch)
treeaa98a38e05188b204950eb0756fb792675951b0d
parentb47b24781c59565f45acd765dc995a752d561e96 (diff)
[PATCH] ext3_get_blocks: support multiple blocks allocation in ext3_new_block()
Change ext3_try_to_allocate() (called via ext3_new_blocks()) to try to allocate the requested number of blocks on a best effort basis: After allocated the first block, it will always attempt to allocate the next few(up to the requested size and not beyond the reservation window) adjacent blocks at the same time. 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.c46
-rw-r--r--include/linux/ext3_fs.h5
2 files changed, 40 insertions, 11 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 46623f77666b..bba4aeb4a708 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -653,9 +653,11 @@ claim_block(spinlock_t *lock, int block, struct buffer_head *bh)
653 */ 653 */
654static int 654static int
655ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group, 655ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
656 struct buffer_head *bitmap_bh, int goal, struct ext3_reserve_window *my_rsv) 656 struct buffer_head *bitmap_bh, int goal,
657 unsigned long *count, struct ext3_reserve_window *my_rsv)
657{ 658{
658 int group_first_block, start, end; 659 int group_first_block, start, end;
660 unsigned long num = 0;
659 661
660 /* we do allocation within the reservation window if we have a window */ 662 /* we do allocation within the reservation window if we have a window */
661 if (my_rsv) { 663 if (my_rsv) {
@@ -713,8 +715,18 @@ repeat:
713 goto fail_access; 715 goto fail_access;
714 goto repeat; 716 goto repeat;
715 } 717 }
716 return goal; 718 num++;
719 goal++;
720 while (num < *count && goal < end
721 && ext3_test_allocatable(goal, bitmap_bh)
722 && claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) {
723 num++;
724 goal++;
725 }
726 *count = num;
727 return goal - num;
717fail_access: 728fail_access:
729 *count = num;
718 return -1; 730 return -1;
719} 731}
720 732
@@ -1024,11 +1036,12 @@ static int
1024ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, 1036ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
1025 unsigned int group, struct buffer_head *bitmap_bh, 1037 unsigned int group, struct buffer_head *bitmap_bh,
1026 int goal, struct ext3_reserve_window_node * my_rsv, 1038 int goal, struct ext3_reserve_window_node * my_rsv,
1027 int *errp) 1039 unsigned long *count, int *errp)
1028{ 1040{
1029 unsigned long group_first_block; 1041 unsigned long group_first_block;
1030 int ret = 0; 1042 int ret = 0;
1031 int fatal; 1043 int fatal;
1044 unsigned long num = *count;
1032 1045
1033 *errp = 0; 1046 *errp = 0;
1034 1047
@@ -1051,7 +1064,8 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
1051 * or last attempt to allocate a block with reservation turned on failed 1064 * or last attempt to allocate a block with reservation turned on failed
1052 */ 1065 */
1053 if (my_rsv == NULL ) { 1066 if (my_rsv == NULL ) {
1054 ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL); 1067 ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh,
1068 goal, count, NULL);
1055 goto out; 1069 goto out;
1056 } 1070 }
1057 /* 1071 /*
@@ -1093,11 +1107,13 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
1093 || (my_rsv->rsv_end < group_first_block)) 1107 || (my_rsv->rsv_end < group_first_block))
1094 BUG(); 1108 BUG();
1095 ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, 1109 ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
1096 &my_rsv->rsv_window); 1110 &num, &my_rsv->rsv_window);
1097 if (ret >= 0) { 1111 if (ret >= 0) {
1098 my_rsv->rsv_alloc_hit++; 1112 my_rsv->rsv_alloc_hit += num;
1113 *count = num;
1099 break; /* succeed */ 1114 break; /* succeed */
1100 } 1115 }
1116 num = *count;
1101 } 1117 }
1102out: 1118out:
1103 if (ret >= 0) { 1119 if (ret >= 0) {
@@ -1154,8 +1170,8 @@ int ext3_should_retry_alloc(struct super_block *sb, int *retries)
1154 * bitmap, and then for any free bit if that fails. 1170 * bitmap, and then for any free bit if that fails.
1155 * This function also updates quota and i_blocks field. 1171 * This function also updates quota and i_blocks field.
1156 */ 1172 */
1157int ext3_new_block(handle_t *handle, struct inode *inode, 1173int ext3_new_blocks(handle_t *handle, struct inode *inode,
1158 unsigned long goal, int *errp) 1174 unsigned long goal, unsigned long *count, int *errp)
1159{ 1175{
1160 struct buffer_head *bitmap_bh = NULL; 1176 struct buffer_head *bitmap_bh = NULL;
1161 struct buffer_head *gdp_bh; 1177 struct buffer_head *gdp_bh;
@@ -1178,6 +1194,7 @@ int ext3_new_block(handle_t *handle, struct inode *inode,
1178 static int goal_hits, goal_attempts; 1194 static int goal_hits, goal_attempts;
1179#endif 1195#endif
1180 unsigned long ngroups; 1196 unsigned long ngroups;
1197 unsigned long num = *count;
1181 1198
1182 *errp = -ENOSPC; 1199 *errp = -ENOSPC;
1183 sb = inode->i_sb; 1200 sb = inode->i_sb;
@@ -1244,7 +1261,7 @@ retry:
1244 if (!bitmap_bh) 1261 if (!bitmap_bh)
1245 goto io_error; 1262 goto io_error;
1246 ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no, 1263 ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
1247 bitmap_bh, ret_block, my_rsv, &fatal); 1264 bitmap_bh, ret_block, my_rsv, &num, &fatal);
1248 if (fatal) 1265 if (fatal)
1249 goto out; 1266 goto out;
1250 if (ret_block >= 0) 1267 if (ret_block >= 0)
@@ -1281,7 +1298,7 @@ retry:
1281 if (!bitmap_bh) 1298 if (!bitmap_bh)
1282 goto io_error; 1299 goto io_error;
1283 ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no, 1300 ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
1284 bitmap_bh, -1, my_rsv, &fatal); 1301 bitmap_bh, -1, my_rsv, &num, &fatal);
1285 if (fatal) 1302 if (fatal)
1286 goto out; 1303 goto out;
1287 if (ret_block >= 0) 1304 if (ret_block >= 0)
@@ -1388,6 +1405,7 @@ allocated:
1388 1405
1389 *errp = 0; 1406 *errp = 0;
1390 brelse(bitmap_bh); 1407 brelse(bitmap_bh);
1408 *count = num;
1391 return ret_block; 1409 return ret_block;
1392 1410
1393io_error: 1411io_error:
@@ -1406,6 +1424,14 @@ out:
1406 return 0; 1424 return 0;
1407} 1425}
1408 1426
1427int ext3_new_block(handle_t *handle, struct inode *inode,
1428 unsigned long goal, int *errp)
1429{
1430 unsigned long count = 1;
1431
1432 return ext3_new_blocks(handle, inode, goal, &count, errp);
1433}
1434
1409unsigned long ext3_count_free_blocks(struct super_block *sb) 1435unsigned long ext3_count_free_blocks(struct super_block *sb)
1410{ 1436{
1411 unsigned long desc_count; 1437 unsigned long desc_count;
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 0adadd85fa66..8bb4f842cded 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -36,7 +36,8 @@ struct statfs;
36 * Define EXT3_RESERVATION to reserve data blocks for expanding files 36 * Define EXT3_RESERVATION to reserve data blocks for expanding files
37 */ 37 */
38#define EXT3_DEFAULT_RESERVE_BLOCKS 8 38#define EXT3_DEFAULT_RESERVE_BLOCKS 8
39#define EXT3_MAX_RESERVE_BLOCKS 1024 39/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
40#define EXT3_MAX_RESERVE_BLOCKS 1027
40#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 41#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0
41/* 42/*
42 * Always enable hashed directories 43 * Always enable hashed directories
@@ -732,6 +733,8 @@ struct dir_private_info {
732extern int ext3_bg_has_super(struct super_block *sb, int group); 733extern int ext3_bg_has_super(struct super_block *sb, int group);
733extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); 734extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
734extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *); 735extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
736extern int ext3_new_blocks (handle_t *, struct inode *, unsigned long,
737 unsigned long *, int *);
735extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long, 738extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long,
736 unsigned long); 739 unsigned long);
737extern void ext3_free_blocks_sb (handle_t *, struct super_block *, 740extern void ext3_free_blocks_sb (handle_t *, struct super_block *,