Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84f54cfa authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse
Browse files

Btrfs: 64 bit div fixes

parent 39279cc3
Loading
Loading
Loading
Loading
+24 −19
Original line number Diff line number Diff line
@@ -65,7 +65,6 @@ static int cache_block_group(struct btrfs_root *root,
	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
printk("cache block group %Lu\n", block_group->key.objectid);
	key.objectid = block_group->key.objectid;
	key.flags = 0;
	key.offset = 0;
@@ -164,7 +163,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
static u64 leaf_range(struct btrfs_root *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));
	return size;
}
@@ -219,6 +218,13 @@ static u64 find_search_start(struct btrfs_root *root,
	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
						 *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) {
			used = btrfs_block_group_used(&shint->item);
			if (used + shint->pinned <
			    (shint->key.offset * factor) / 10) {
			    div_factor(shint->key.offset, factor)) {
				return shint;
			}
		}
	}
	if (hint && hint->data == data) {
		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;
		}
		if (used >= (hint->key.offset * 8) / 10) {
		if (used >= div_factor(hint->key.offset, 8)) {
			radix_tree_tag_clear(radix,
					     hint->key.objectid +
					     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;
			used = btrfs_block_group_used(&cache[i]->item);
			if (used + cache[i]->pinned <
			    (cache[i]->key.offset * factor) / 10) {
			    div_factor(cache[i]->key.offset, factor)) {
				found_group = cache[i];
				goto found;
			}
			if (used >= (cache[i]->key.offset * 8) / 10) {
			if (used >= div_factor(cache[i]->key.offset, 8)) {
				radix_tree_tag_clear(radix,
						     cache[i]->key.objectid +
						     cache[i]->key.offset - 1,
@@ -348,7 +355,6 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
		goto again;
	}
	if (!found_group) {
printk("find block group bailing to zero data %d\n", data);
		ret = radix_tree_gang_lookup(radix,
					     (void **)&found_group, 0, 1);
		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,
				0, 1);
	if (ret != 0) {
printk("can't find block %Lu %Lu\n", blocknr, num_blocks);
		BUG();
	}
	BUG_ON(ret != 0);
@@ -601,8 +606,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
				}
			}
			if (cache->data != data &&
			    old_val < cache->key.offset / 2) {
printk("changing block group %Lu from %d to %d\n", cache->key.objectid, cache->data, data);
			    old_val < (cache->key.offset >> 1)) {
				cache->data = data;
				radix_tree_delete(cache->radix,
						  cache->key.objectid +
@@ -634,9 +638,8 @@ printk("changing block group %Lu from %d to %d\n", cache->key.objectid, cache->d
						      blocknr + i);
				}
			}
			if (old_val < cache->key.offset / 2 &&
			    old_val + num >= cache->key.offset / 2) {
printk("group %Lu now available\n", cache->key.objectid);
			if (old_val < (cache->key.offset >> 1) &&
			    old_val + num >= (cache->key.offset >> 1)) {
				radix_tree_tag_set(cache->radix,
						   cache->key.objectid +
						   cache->key.offset - 1,
@@ -1000,10 +1003,10 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
			}
			if (start_found)
				limit = last_block +
					block_group->key.offset / 2;
					(block_group->key.offset >> 1);
			else
				limit = search_start +
					block_group->key.offset / 2;
					(block_group->key.offset >> 1);
			ret = btrfs_next_leaf(root, path);
			if (ret == 0)
				continue;
@@ -1534,9 +1537,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)
	struct btrfs_key key;
	struct btrfs_key found_key;
	struct btrfs_leaf *leaf;
	u64 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE / root->blocksize;
	u64 group_size_blocks;
	u64 used;

	group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >>
		root->fs_info->sb->s_blocksize_bits;
	root = info->extent_root;
	key.objectid = 0;
	key.offset = group_size_blocks;
@@ -1590,7 +1595,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
					(void *)cache);
		BUG_ON(ret);
		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 +
					   found_key.offset - 1,
					   BTRFS_BLOCK_GROUP_AVAIL);
+2 −1
Original line number Diff line number Diff line
@@ -239,7 +239,8 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
	if (isize <= key.offset)
		return 0;
	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;
	if (new_item_size >= btrfs_item_size(leaf->items + slot))
		return 0;
+4 −3
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,

	for (i = 0; i < num_pages; i++) {
		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 */

		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);
		wait_on_page_writeback(pages[i]);
		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])) {
			create_empty_buffers(pages[i],
					     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) {
		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) >>
					PAGE_CACHE_SHIFT;

+1 −1
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		ret = btrfs_del_item(trans, root, path);
	} else {
		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]);
	}
out: