* The file system contains group descriptors which are located after the
* super block. Each descriptor contains the number of the bitmap block and
* the free blocks count in the block. The descriptors are loaded in memory
- * when a file system is mounted (see ext3_read_super).
+ * when a file system is mounted (see ext3_fill_super).
*/
/**
* ext3_get_group_desc() -- load group descriptor from disk
- * @sb: super block
+ * @sb: super block
* @block_group: given block group
* @bh: pointer to the buffer head to store the block
* group descriptor
printk("Block Allocation Reservation Windows Map (%s):\n", fn);
while (n) {
- rsv = list_entry(n, struct ext3_reserve_window_node, rsv_node);
+ rsv = rb_entry(n, struct ext3_reserve_window_node, rsv_node);
if (verbose)
printk("reservation window 0x%p "
"start: %lu, end: %lu\n",
ext3_fsblk_t group_first_block, group_last_block;
group_first_block = ext3_group_first_block_no(sb, group);
- group_last_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
+ group_last_block = group_first_block + (EXT3_BLOCKS_PER_GROUP(sb) - 1);
if ((rsv->_rsv_start > group_last_block) ||
(rsv->_rsv_end < group_first_block))
rsv->rsv_start = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
rsv->rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
- /*
+ /*
* if filesystem is mounted with NORESERVATION, the goal
* reservation window size is set to zero to indicate
* block reservation is off
jbd_lock_bh_state(bh);
if (jh->b_committed_data)
start = ext3_find_next_zero_bit(jh->b_committed_data,
- maxblocks, next);
+ maxblocks, next);
jbd_unlock_bh_state(bh);
}
return -1;
here = 0;
p = ((char *)bh->b_data) + (here >> 3);
- r = memscan(p, 0, (maxblocks - here + 7) >> 3);
+ r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3));
next = (r - ((char *)bh->b_data)) << 3;
if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh))
* and at last, allocate the blocks by claiming the found free bit as allocated.
*
* To set the range of this allocation:
- * if there is a reservation window, only try to allocate block(s) from the
+ * if there is a reservation window, only try to allocate block(s) from the
* file's own reservation window;
* Otherwise, the allocation range starts from the give goal block, ends at
- * the block group's last block.
+ * the block group's last block.
*
* If we failed to allocate the desired block then we may end up crossing to a
* new bitmap. In that case we must release write access to the old one via
}
/**
- * find_next_reservable_window():
+ * find_next_reservable_window():
* find a reservable space within the given range.
* It does not allocate the reservation window for now:
* alloc_new_reservation() will do the work later.
*
- * @search_head: the head of the searching list;
+ * @search_head: the head of the searching list;
* This is not necessarily the list head of the whole filesystem
*
* We have both head and start_block to assist the search
* but we will shift to the place where start_block is,
* then start from there, when looking for a reservable space.
*
- * @size: the target new reservation window size
+ * @size: the target new reservation window size
*
- * @group_first_block: the first block we consider to start
+ * @group_first_block: the first block we consider to start
* the real search from
*
- * @last_block:
+ * @last_block:
* the maximum block number that our goal reservable space
* could start from. This is normally the last block in this
* group. The search will end when we found the start of next
* This could handle the cross boundary reservation window
* request.
*
- * basically we search from the given range, rather than the whole
- * reservation double linked list, (start_block, last_block)
- * to find a free region that is of my size and has not
- * been reserved.
+ * basically we search from the given range, rather than the whole
+ * reservation double linked list, (start_block, last_block)
+ * to find a free region that is of my size and has not
+ * been reserved.
*
*/
static int find_next_reservable_window(
prev = rsv;
next = rb_next(&rsv->rsv_node);
- rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node);
+ rsv = rb_entry(next,struct ext3_reserve_window_node,rsv_node);
/*
* Reached the last reservation, we can just append to the
/*
* Found a reserveable space big enough. We could
* have a reservation across the group boundary here
- */
+ */
break;
}
}
}
/**
- * alloc_new_reservation()--allocate a new reservation window
+ * alloc_new_reservation()--allocate a new reservation window
*
* To make a new reservation, we search part of the filesystem
* reservation list (the list that inside the group). We try to
spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
group_first_block = ext3_group_first_block_no(sb, group);
- group_end_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
+ group_end_block = group_first_block + (EXT3_BLOCKS_PER_GROUP(sb) - 1);
if (grp_goal < 0)
start_block = group_first_block;
* check if the first free block is within the
* free space we just reserved
*/
- if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end)
+ if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end)
return 0; /* success */
/*
* if the first free bit we found is out of the reservable space
if (!next)
my_rsv->rsv_end += size;
else {
- next_rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node);
+ next_rsv = rb_entry(next, struct ext3_reserve_window_node, rsv_node);
if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size)
my_rsv->rsv_end += size;
struct ext3_reserve_window_node * my_rsv,
unsigned long *count, int *errp)
{
- ext3_fsblk_t group_first_block;
+ ext3_fsblk_t group_first_block, group_last_block;
ext3_grpblk_t ret = 0;
int fatal;
unsigned long num = *count;
}
/*
* grp_goal is a group relative block number (if there is a goal)
- * 0 < grp_goal < EXT3_BLOCKS_PER_GROUP(sb)
+ * 0 <= grp_goal < EXT3_BLOCKS_PER_GROUP(sb)
* first block is a filesystem wide block number
* first block is the block number of the first block in this group
*/
group_first_block = ext3_group_first_block_no(sb, group);
+ group_last_block = group_first_block + (EXT3_BLOCKS_PER_GROUP(sb) - 1);
/*
* Basically we will allocate a new block from inode's reservation
if (!goal_in_my_reservation(&my_rsv->rsv_window,
grp_goal, group, sb))
grp_goal = -1;
- } else if (grp_goal > 0 &&
- (my_rsv->rsv_end-grp_goal+1) < *count)
- try_to_extend_reservation(my_rsv, sb,
- *count-my_rsv->rsv_end + grp_goal - 1);
-
- if ((my_rsv->rsv_start >= group_first_block +
- EXT3_BLOCKS_PER_GROUP(sb))
- || (my_rsv->rsv_end < group_first_block)) {
+ } else if (grp_goal >= 0) {
+ int curr = my_rsv->rsv_end -
+ (grp_goal + group_first_block) + 1;
+
+ if (curr < *count)
+ try_to_extend_reservation(my_rsv, sb,
+ *count - curr);
+ }
+
+ if ((my_rsv->rsv_start > group_last_block) ||
+ (my_rsv->rsv_end < group_first_block)) {
rsv_window_dump(&EXT3_SB(sb)->s_rsv_window_root, 1);
BUG();
}
if (group_no >= ngroups)
group_no = 0;
gdp = ext3_get_group_desc(sb, group_no, &gdp_bh);
- if (!gdp) {
- *errp = -EIO;
- goto out;
- }
+ if (!gdp)
+ goto io_error;
free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
/*
* skip this group if the number of
*/
if (my_rsv) {
my_rsv = NULL;
+ windowsz = 0;
group_no = goal_group;
goto retry_alloc;
}