提交 84f54cfa 编写于 作者: C Chris Mason 提交者: David Woodhouse

Btrfs: 64 bit div fixes

Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 39279cc3
...@@ -65,7 +65,6 @@ static int cache_block_group(struct btrfs_root *root, ...@@ -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 ...@@ -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: ...@@ -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, ...@@ -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, ...@@ -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: ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册