diff options
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r-- | fs/ext4/balloc.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 5d45582f9517..c4dd1103ccf1 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -165,7 +165,7 @@ restart: | |||
165 | 165 | ||
166 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); | 166 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); |
167 | while (n) { | 167 | while (n) { |
168 | rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); | 168 | rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node); |
169 | if (verbose) | 169 | if (verbose) |
170 | printk("reservation window 0x%p " | 170 | printk("reservation window 0x%p " |
171 | "start: %llu, end: %llu\n", | 171 | "start: %llu, end: %llu\n", |
@@ -747,7 +747,7 @@ find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh, | |||
747 | here = 0; | 747 | here = 0; |
748 | 748 | ||
749 | p = ((char *)bh->b_data) + (here >> 3); | 749 | p = ((char *)bh->b_data) + (here >> 3); |
750 | r = memscan(p, 0, (maxblocks - here + 7) >> 3); | 750 | r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); |
751 | next = (r - ((char *)bh->b_data)) << 3; | 751 | next = (r - ((char *)bh->b_data)) << 3; |
752 | 752 | ||
753 | if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) | 753 | if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) |
@@ -966,7 +966,7 @@ static int find_next_reservable_window( | |||
966 | 966 | ||
967 | prev = rsv; | 967 | prev = rsv; |
968 | next = rb_next(&rsv->rsv_node); | 968 | next = rb_next(&rsv->rsv_node); |
969 | rsv = list_entry(next,struct ext4_reserve_window_node,rsv_node); | 969 | rsv = rb_entry(next,struct ext4_reserve_window_node,rsv_node); |
970 | 970 | ||
971 | /* | 971 | /* |
972 | * Reached the last reservation, we can just append to the | 972 | * Reached the last reservation, we can just append to the |
@@ -1165,7 +1165,7 @@ retry: | |||
1165 | * check if the first free block is within the | 1165 | * check if the first free block is within the |
1166 | * free space we just reserved | 1166 | * free space we just reserved |
1167 | */ | 1167 | */ |
1168 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) | 1168 | if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) |
1169 | return 0; /* success */ | 1169 | return 0; /* success */ |
1170 | /* | 1170 | /* |
1171 | * if the first free bit we found is out of the reservable space | 1171 | * if the first free bit we found is out of the reservable space |
@@ -1210,7 +1210,7 @@ static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv, | |||
1210 | if (!next) | 1210 | if (!next) |
1211 | my_rsv->rsv_end += size; | 1211 | my_rsv->rsv_end += size; |
1212 | else { | 1212 | else { |
1213 | next_rsv = list_entry(next, struct ext4_reserve_window_node, rsv_node); | 1213 | next_rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node); |
1214 | 1214 | ||
1215 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | 1215 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) |
1216 | my_rsv->rsv_end += size; | 1216 | my_rsv->rsv_end += size; |
@@ -1288,7 +1288,7 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1288 | } | 1288 | } |
1289 | /* | 1289 | /* |
1290 | * grp_goal is a group relative block number (if there is a goal) | 1290 | * grp_goal is a group relative block number (if there is a goal) |
1291 | * 0 < grp_goal < EXT4_BLOCKS_PER_GROUP(sb) | 1291 | * 0 <= grp_goal < EXT4_BLOCKS_PER_GROUP(sb) |
1292 | * first block is a filesystem wide block number | 1292 | * first block is a filesystem wide block number |
1293 | * first block is the block number of the first block in this group | 1293 | * first block is the block number of the first block in this group |
1294 | */ | 1294 | */ |
@@ -1324,10 +1324,14 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1324 | if (!goal_in_my_reservation(&my_rsv->rsv_window, | 1324 | if (!goal_in_my_reservation(&my_rsv->rsv_window, |
1325 | grp_goal, group, sb)) | 1325 | grp_goal, group, sb)) |
1326 | grp_goal = -1; | 1326 | grp_goal = -1; |
1327 | } else if (grp_goal > 0 && | 1327 | } else if (grp_goal >= 0) { |
1328 | (my_rsv->rsv_end-grp_goal+1) < *count) | 1328 | int curr = my_rsv->rsv_end - |
1329 | try_to_extend_reservation(my_rsv, sb, | 1329 | (grp_goal + group_first_block) + 1; |
1330 | *count-my_rsv->rsv_end + grp_goal - 1); | 1330 | |
1331 | if (curr < *count) | ||
1332 | try_to_extend_reservation(my_rsv, sb, | ||
1333 | *count - curr); | ||
1334 | } | ||
1331 | 1335 | ||
1332 | if ((my_rsv->rsv_start > group_last_block) || | 1336 | if ((my_rsv->rsv_start > group_last_block) || |
1333 | (my_rsv->rsv_end < group_first_block)) { | 1337 | (my_rsv->rsv_end < group_first_block)) { |
@@ -1525,10 +1529,8 @@ retry_alloc: | |||
1525 | if (group_no >= ngroups) | 1529 | if (group_no >= ngroups) |
1526 | group_no = 0; | 1530 | group_no = 0; |
1527 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); | 1531 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); |
1528 | if (!gdp) { | 1532 | if (!gdp) |
1529 | *errp = -EIO; | 1533 | goto io_error; |
1530 | goto out; | ||
1531 | } | ||
1532 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | 1534 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); |
1533 | /* | 1535 | /* |
1534 | * skip this group if the number of | 1536 | * skip this group if the number of |
@@ -1562,6 +1564,7 @@ retry_alloc: | |||
1562 | */ | 1564 | */ |
1563 | if (my_rsv) { | 1565 | if (my_rsv) { |
1564 | my_rsv = NULL; | 1566 | my_rsv = NULL; |
1567 | windowsz = 0; | ||
1565 | group_no = goal_group; | 1568 | group_no = goal_group; |
1566 | goto retry_alloc; | 1569 | goto retry_alloc; |
1567 | } | 1570 | } |