diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-26 19:46:19 -0800 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-26 19:46:48 -0800 | 
| commit | 47b649590dbbea182f854d6470ee1cd59b7b7684 (patch) | |
| tree | a2de3610f9c5e963234cffb35b9d559aab62e164 /fs/btrfs/free-space-cache.c | |
| parent | 3af5154a869bc278a829bb03e65a709480e821b0 (diff) | |
| parent | caca6a03d365883564885f2c1da3e88dcf65d139 (diff) | |
| download | olio-linux-3.10-47b649590dbbea182f854d6470ee1cd59b7b7684.tar.xz olio-linux-3.10-47b649590dbbea182f854d6470ee1cd59b7b7684.zip  | |
Merge 3.2-rc3 into usb-linus
This pulls in the latest USB bugfixes and helps a few of the drivers
merge nicer in the future due to changes in both branches.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 80 | 
1 files changed, 36 insertions, 44 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 7a15fcfb3e1..6e5b7e46369 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -351,6 +351,11 @@ static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode,  		}  	} +	for (i = 0; i < io_ctl->num_pages; i++) { +		clear_page_dirty_for_io(io_ctl->pages[i]); +		set_page_extent_mapped(io_ctl->pages[i]); +	} +  	return 0;  } @@ -537,6 +542,13 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl,  			    struct btrfs_free_space *entry, u8 *type)  {  	struct btrfs_free_space_entry *e; +	int ret; + +	if (!io_ctl->cur) { +		ret = io_ctl_check_crc(io_ctl, io_ctl->index); +		if (ret) +			return ret; +	}  	e = io_ctl->cur;  	entry->offset = le64_to_cpu(e->offset); @@ -550,10 +562,7 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl,  	io_ctl_unmap_page(io_ctl); -	if (io_ctl->index >= io_ctl->num_pages) -		return 0; - -	return io_ctl_check_crc(io_ctl, io_ctl->index); +	return 0;  }  static int io_ctl_read_bitmap(struct io_ctl *io_ctl, @@ -561,9 +570,6 @@ static int io_ctl_read_bitmap(struct io_ctl *io_ctl,  {  	int ret; -	if (io_ctl->cur && io_ctl->cur != io_ctl->orig) -		io_ctl_unmap_page(io_ctl); -  	ret = io_ctl_check_crc(io_ctl, io_ctl->index);  	if (ret)  		return ret; @@ -699,6 +705,8 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,  		num_entries--;  	} +	io_ctl_unmap_page(&io_ctl); +  	/*  	 * We add the bitmaps at the end of the entries in order that  	 * the bitmap entries are added to the cache. @@ -1841,7 +1849,13 @@ again:  		info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset),  					  1, 0);  		if (!info) { -			WARN_ON(1); +			/* the tree logging code might be calling us before we +			 * have fully loaded the free space rbtree for this +			 * block group.  So it is possible the entry won't +			 * be in the rbtree yet at all.  The caching code +			 * will make sure not to put it in the rbtree if +			 * the logging code has pinned it. +			 */  			goto out_lock;  		}  	} @@ -2448,16 +2462,23 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,  {  	struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;  	struct btrfs_free_space *entry; -	struct rb_node *node;  	int ret = -ENOSPC; +	u64 bitmap_offset = offset_to_bitmap(ctl, offset);  	if (ctl->total_bitmaps == 0)  		return -ENOSPC;  	/* -	 * First check our cached list of bitmaps and see if there is an entry -	 * here that will work. +	 * The bitmap that covers offset won't be in the list unless offset +	 * is just its start offset.  	 */ +	entry = list_first_entry(bitmaps, struct btrfs_free_space, list); +	if (entry->offset != bitmap_offset) { +		entry = tree_search_offset(ctl, bitmap_offset, 1, 0); +		if (entry && list_empty(&entry->list)) +			list_add(&entry->list, bitmaps); +	} +  	list_for_each_entry(entry, bitmaps, list) {  		if (entry->bytes < min_bytes)  			continue; @@ -2468,38 +2489,10 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,  	}  	/* -	 * If we do have entries on our list and we are here then we didn't find -	 * anything, so go ahead and get the next entry after the last entry in -	 * this list and start the search from there. +	 * The bitmaps list has all the bitmaps that record free space +	 * starting after offset, so no more search is required.  	 */ -	if (!list_empty(bitmaps)) { -		entry = list_entry(bitmaps->prev, struct btrfs_free_space, -				   list); -		node = rb_next(&entry->offset_index); -		if (!node) -			return -ENOSPC; -		entry = rb_entry(node, struct btrfs_free_space, offset_index); -		goto search; -	} - -	entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1); -	if (!entry) -		return -ENOSPC; - -search: -	node = &entry->offset_index; -	do { -		entry = rb_entry(node, struct btrfs_free_space, offset_index); -		node = rb_next(&entry->offset_index); -		if (!entry->bitmap) -			continue; -		if (entry->bytes < min_bytes) -			continue; -		ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, -					   bytes, min_bytes); -	} while (ret && node); - -	return ret; +	return -ENOSPC;  }  /* @@ -2517,8 +2510,8 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,  			     u64 offset, u64 bytes, u64 empty_size)  {  	struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; -	struct list_head bitmaps;  	struct btrfs_free_space *entry, *tmp; +	LIST_HEAD(bitmaps);  	u64 min_bytes;  	int ret; @@ -2557,7 +2550,6 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,  		goto out;  	} -	INIT_LIST_HEAD(&bitmaps);  	ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset,  				      bytes, min_bytes);  	if (ret)  |