forked from Minki/linux
Btrfs: 64 bit div fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
39279cc3d2
commit
84f54cfa78
@ -65,7 +65,6 @@ static int cache_block_group(struct btrfs_root *root,
|
|||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path)
|
if (!path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
printk("cache block group %Lu\n", block_group->key.objectid);
|
|
||||||
key.objectid = block_group->key.objectid;
|
key.objectid = block_group->key.objectid;
|
||||||
key.flags = 0;
|
key.flags = 0;
|
||||||
key.offset = 0;
|
key.offset = 0;
|
||||||
@ -164,8 +163,8 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
|
|||||||
static u64 leaf_range(struct btrfs_root *root)
|
static u64 leaf_range(struct btrfs_root *root)
|
||||||
{
|
{
|
||||||
u64 size = BTRFS_LEAF_DATA_SIZE(root);
|
u64 size = BTRFS_LEAF_DATA_SIZE(root);
|
||||||
size = size / (sizeof(struct btrfs_extent_item) +
|
do_div(size, sizeof(struct btrfs_extent_item) +
|
||||||
sizeof(struct btrfs_item));
|
sizeof(struct btrfs_item));
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +218,13 @@ new_group:
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 div_factor(u64 num, int factor)
|
||||||
|
{
|
||||||
|
num *= factor;
|
||||||
|
do_div(num, 10);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
|
struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
|
||||||
struct btrfs_block_group_cache
|
struct btrfs_block_group_cache
|
||||||
*hint, u64 search_start,
|
*hint, u64 search_start,
|
||||||
@ -255,17 +261,18 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
|
|||||||
if (shint->data == data) {
|
if (shint->data == data) {
|
||||||
used = btrfs_block_group_used(&shint->item);
|
used = btrfs_block_group_used(&shint->item);
|
||||||
if (used + shint->pinned <
|
if (used + shint->pinned <
|
||||||
(shint->key.offset * factor) / 10) {
|
div_factor(shint->key.offset, factor)) {
|
||||||
return shint;
|
return shint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hint && hint->data == data) {
|
if (hint && hint->data == data) {
|
||||||
used = btrfs_block_group_used(&hint->item);
|
used = btrfs_block_group_used(&hint->item);
|
||||||
if (used + hint->pinned < (hint->key.offset * factor) / 10) {
|
if (used + hint->pinned <
|
||||||
|
div_factor(hint->key.offset, factor)) {
|
||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
if (used >= (hint->key.offset * 8) / 10) {
|
if (used >= div_factor(hint->key.offset, 8)) {
|
||||||
radix_tree_tag_clear(radix,
|
radix_tree_tag_clear(radix,
|
||||||
hint->key.objectid +
|
hint->key.objectid +
|
||||||
hint->key.offset - 1,
|
hint->key.offset - 1,
|
||||||
@ -297,11 +304,11 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
|
|||||||
cache[i]->key.offset;
|
cache[i]->key.offset;
|
||||||
used = btrfs_block_group_used(&cache[i]->item);
|
used = btrfs_block_group_used(&cache[i]->item);
|
||||||
if (used + cache[i]->pinned <
|
if (used + cache[i]->pinned <
|
||||||
(cache[i]->key.offset * factor) / 10) {
|
div_factor(cache[i]->key.offset, factor)) {
|
||||||
found_group = cache[i];
|
found_group = cache[i];
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
if (used >= (cache[i]->key.offset * 8) / 10) {
|
if (used >= div_factor(cache[i]->key.offset, 8)) {
|
||||||
radix_tree_tag_clear(radix,
|
radix_tree_tag_clear(radix,
|
||||||
cache[i]->key.objectid +
|
cache[i]->key.objectid +
|
||||||
cache[i]->key.offset - 1,
|
cache[i]->key.offset - 1,
|
||||||
@ -348,7 +355,6 @@ again:
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (!found_group) {
|
if (!found_group) {
|
||||||
printk("find block group bailing to zero data %d\n", data);
|
|
||||||
ret = radix_tree_gang_lookup(radix,
|
ret = radix_tree_gang_lookup(radix,
|
||||||
(void **)&found_group, 0, 1);
|
(void **)&found_group, 0, 1);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@ -386,7 +392,6 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
|
|||||||
ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
|
ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
|
||||||
0, 1);
|
0, 1);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printk("can't find block %Lu %Lu\n", blocknr, num_blocks);
|
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
BUG_ON(ret != 0);
|
BUG_ON(ret != 0);
|
||||||
@ -601,8 +606,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cache->data != data &&
|
if (cache->data != data &&
|
||||||
old_val < cache->key.offset / 2) {
|
old_val < (cache->key.offset >> 1)) {
|
||||||
printk("changing block group %Lu from %d to %d\n", cache->key.objectid, cache->data, data);
|
|
||||||
cache->data = data;
|
cache->data = data;
|
||||||
radix_tree_delete(cache->radix,
|
radix_tree_delete(cache->radix,
|
||||||
cache->key.objectid +
|
cache->key.objectid +
|
||||||
@ -634,9 +638,8 @@ printk("changing block group %Lu from %d to %d\n", cache->key.objectid, cache->d
|
|||||||
blocknr + i);
|
blocknr + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (old_val < cache->key.offset / 2 &&
|
if (old_val < (cache->key.offset >> 1) &&
|
||||||
old_val + num >= cache->key.offset / 2) {
|
old_val + num >= (cache->key.offset >> 1)) {
|
||||||
printk("group %Lu now available\n", cache->key.objectid);
|
|
||||||
radix_tree_tag_set(cache->radix,
|
radix_tree_tag_set(cache->radix,
|
||||||
cache->key.objectid +
|
cache->key.objectid +
|
||||||
cache->key.offset - 1,
|
cache->key.offset - 1,
|
||||||
@ -1000,10 +1003,10 @@ check_failed:
|
|||||||
}
|
}
|
||||||
if (start_found)
|
if (start_found)
|
||||||
limit = last_block +
|
limit = last_block +
|
||||||
block_group->key.offset / 2;
|
(block_group->key.offset >> 1);
|
||||||
else
|
else
|
||||||
limit = search_start +
|
limit = search_start +
|
||||||
block_group->key.offset / 2;
|
(block_group->key.offset >> 1);
|
||||||
ret = btrfs_next_leaf(root, path);
|
ret = btrfs_next_leaf(root, path);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -1534,9 +1537,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)
|
|||||||
struct btrfs_key key;
|
struct btrfs_key key;
|
||||||
struct btrfs_key found_key;
|
struct btrfs_key found_key;
|
||||||
struct btrfs_leaf *leaf;
|
struct btrfs_leaf *leaf;
|
||||||
u64 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE / root->blocksize;
|
u64 group_size_blocks;
|
||||||
u64 used;
|
u64 used;
|
||||||
|
|
||||||
|
group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >>
|
||||||
|
root->fs_info->sb->s_blocksize_bits;
|
||||||
root = info->extent_root;
|
root = info->extent_root;
|
||||||
key.objectid = 0;
|
key.objectid = 0;
|
||||||
key.offset = group_size_blocks;
|
key.offset = group_size_blocks;
|
||||||
@ -1590,7 +1595,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
|
|||||||
(void *)cache);
|
(void *)cache);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
used = btrfs_block_group_used(bi);
|
used = btrfs_block_group_used(bi);
|
||||||
if (used < (key.offset * 8) / 10) {
|
if (used < div_factor(key.offset, 8)) {
|
||||||
radix_tree_tag_set(radix, found_key.objectid +
|
radix_tree_tag_set(radix, found_key.objectid +
|
||||||
found_key.offset - 1,
|
found_key.offset - 1,
|
||||||
BTRFS_BLOCK_GROUP_AVAIL);
|
BTRFS_BLOCK_GROUP_AVAIL);
|
||||||
|
@ -239,7 +239,8 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
|
|||||||
if (isize <= key.offset)
|
if (isize <= key.offset)
|
||||||
return 0;
|
return 0;
|
||||||
new_item_span = isize - key.offset;
|
new_item_span = isize - key.offset;
|
||||||
blocks = (new_item_span + root->blocksize - 1) / root->blocksize;
|
blocks = (new_item_span + root->blocksize - 1) >>
|
||||||
|
root->fs_info->sb->s_blocksize_bits;
|
||||||
new_item_size = blocks * BTRFS_CRC32_SIZE;
|
new_item_size = blocks * BTRFS_CRC32_SIZE;
|
||||||
if (new_item_size >= btrfs_item_size(leaf->items + slot))
|
if (new_item_size >= btrfs_item_size(leaf->items + slot))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -82,7 +82,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
|
|||||||
|
|
||||||
for (i = 0; i < num_pages; i++) {
|
for (i = 0; i < num_pages; i++) {
|
||||||
offset = pos & (PAGE_CACHE_SIZE -1);
|
offset = pos & (PAGE_CACHE_SIZE -1);
|
||||||
this_write = min(PAGE_CACHE_SIZE - offset, write_bytes);
|
this_write = min((size_t)PAGE_CACHE_SIZE - offset, write_bytes);
|
||||||
/* FIXME, one block at a time */
|
/* FIXME, one block at a time */
|
||||||
|
|
||||||
mutex_lock(&root->fs_info->fs_mutex);
|
mutex_lock(&root->fs_info->fs_mutex);
|
||||||
@ -395,7 +395,7 @@ static int prepare_pages(struct btrfs_root *root,
|
|||||||
cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
|
cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
|
||||||
wait_on_page_writeback(pages[i]);
|
wait_on_page_writeback(pages[i]);
|
||||||
offset = pos & (PAGE_CACHE_SIZE -1);
|
offset = pos & (PAGE_CACHE_SIZE -1);
|
||||||
this_write = min(PAGE_CACHE_SIZE - offset, write_bytes);
|
this_write = min((size_t)PAGE_CACHE_SIZE - offset, write_bytes);
|
||||||
if (!page_has_buffers(pages[i])) {
|
if (!page_has_buffers(pages[i])) {
|
||||||
create_empty_buffers(pages[i],
|
create_empty_buffers(pages[i],
|
||||||
root->fs_info->sb->s_blocksize,
|
root->fs_info->sb->s_blocksize,
|
||||||
@ -567,7 +567,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
|
|||||||
|
|
||||||
while(count > 0) {
|
while(count > 0) {
|
||||||
size_t offset = pos & (PAGE_CACHE_SIZE - 1);
|
size_t offset = pos & (PAGE_CACHE_SIZE - 1);
|
||||||
size_t write_bytes = min(count, PAGE_CACHE_SIZE - offset);
|
size_t write_bytes = min(count,
|
||||||
|
(size_t)PAGE_CACHE_SIZE - offset);
|
||||||
size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >>
|
size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >>
|
||||||
PAGE_CACHE_SHIFT;
|
PAGE_CACHE_SHIFT;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|||||||
ret = btrfs_del_item(trans, root, path);
|
ret = btrfs_del_item(trans, root, path);
|
||||||
} else {
|
} else {
|
||||||
btrfs_set_root_refs(ri, refs - 1);
|
btrfs_set_root_refs(ri, refs - 1);
|
||||||
printk("ref now %u root %Lu %Lu %u\n", refs -1, key->objectid, key->offset, key->flags);
|
printk("ref now %u root %llu %Lu %u\n", refs -1, key->objectid, key->offset, key->flags);
|
||||||
mark_buffer_dirty(path->nodes[0]);
|
mark_buffer_dirty(path->nodes[0]);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
Loading…
Reference in New Issue
Block a user