diff options
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 521 | 
1 files changed, 340 insertions, 181 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 3f0ddfce96e..2b0a627cb5f 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -218,7 +218,6 @@ int btrfs_check_trunc_cache_free_space(struct btrfs_root *root,  int btrfs_truncate_free_space_cache(struct btrfs_root *root,  				    struct btrfs_trans_handle *trans, -				    struct btrfs_path *path,  				    struct inode *inode)  {  	int ret = 0; @@ -275,18 +274,32 @@ struct io_ctl {  };  static int io_ctl_init(struct io_ctl *io_ctl, struct inode *inode, -		       struct btrfs_root *root) +		       struct btrfs_root *root, int write)  { +	int num_pages; +	int check_crcs = 0; + +	num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> +		    PAGE_CACHE_SHIFT; + +	if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID) +		check_crcs = 1; + +	/* Make sure we can fit our crcs into the first page */ +	if (write && check_crcs && +	    (num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) +		return -ENOSPC; +  	memset(io_ctl, 0, sizeof(struct io_ctl)); -	io_ctl->num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> -		PAGE_CACHE_SHIFT; -	io_ctl->pages = kzalloc(sizeof(struct page *) * io_ctl->num_pages, -				GFP_NOFS); + +	io_ctl->pages = kzalloc(sizeof(struct page *) * num_pages, GFP_NOFS);  	if (!io_ctl->pages)  		return -ENOMEM; + +	io_ctl->num_pages = num_pages;  	io_ctl->root = root; -	if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID) -		io_ctl->check_crcs = 1; +	io_ctl->check_crcs = check_crcs; +  	return 0;  } @@ -348,8 +361,8 @@ static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode,  			btrfs_readpage(NULL, page);  			lock_page(page);  			if (!PageUptodate(page)) { -				printk(KERN_ERR "btrfs: error reading free " -				       "space cache\n"); +				btrfs_err(BTRFS_I(inode)->root->fs_info, +					   "error reading free space cache");  				io_ctl_drop_pages(io_ctl);  				return -EIO;  			} @@ -406,7 +419,7 @@ static int io_ctl_check_generation(struct io_ctl *io_ctl, u64 generation)  	gen = io_ctl->cur;  	if (le64_to_cpu(*gen) != generation) { -		printk_ratelimited(KERN_ERR "btrfs: space cache generation " +		printk_ratelimited(KERN_ERR "BTRFS: space cache generation "  				   "(%Lu) does not match inode (%Lu)\n", *gen,  				   generation);  		io_ctl_unmap_page(io_ctl); @@ -464,7 +477,7 @@ static int io_ctl_check_crc(struct io_ctl *io_ctl, int index)  			      PAGE_CACHE_SIZE - offset);  	btrfs_csum_final(crc, (char *)&crc);  	if (val != crc) { -		printk_ratelimited(KERN_ERR "btrfs: csum mismatch on free " +		printk_ratelimited(KERN_ERR "BTRFS: csum mismatch on free "  				   "space cache\n");  		io_ctl_unmap_page(io_ctl);  		return -EIO; @@ -667,6 +680,13 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,  	generation = btrfs_free_space_generation(leaf, header);  	btrfs_release_path(path); +	if (!BTRFS_I(inode)->generation) { +		btrfs_info(root->fs_info, +			   "The free space cache file (%llu) is invalid. skip it\n", +			   offset); +		return 0; +	} +  	if (BTRFS_I(inode)->generation != generation) {  		btrfs_err(root->fs_info,  			"free space inode generation (%llu) " @@ -678,7 +698,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,  	if (!num_entries)  		return 0; -	ret = io_ctl_init(&io_ctl, inode, root); +	ret = io_ctl_init(&io_ctl, inode, root, 0);  	if (ret)  		return ret; @@ -832,7 +852,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,  	if (!matched) {  		__btrfs_remove_free_space_cache(ctl); -		btrfs_err(fs_info, "block group %llu has wrong amount of free space", +		btrfs_warn(fs_info, "block group %llu has wrong amount of free space",  			block_group->key.objectid);  		ret = -1;  	} @@ -844,7 +864,7 @@ out:  		spin_unlock(&block_group->lock);  		ret = 0; -		btrfs_err(fs_info, "failed to load free space cache for block group %llu", +		btrfs_warn(fs_info, "failed to load free space cache for block group %llu, rebuild it now",  			block_group->key.objectid);  	} @@ -852,90 +872,44 @@ out:  	return ret;  } -/** - * __btrfs_write_out_cache - write out cached info to an inode - * @root - the root the inode belongs to - * @ctl - the free space cache we are going to write out - * @block_group - the block_group for this cache if it belongs to a block_group - * @trans - the trans handle - * @path - the path to use - * @offset - the offset for the key we'll insert - * - * This function writes out a free space cache struct to disk for quick recovery - * on mount.  This will return 0 if it was successfull in writing the cache out, - * and -1 if it was not. - */ -static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, -				   struct btrfs_free_space_ctl *ctl, -				   struct btrfs_block_group_cache *block_group, -				   struct btrfs_trans_handle *trans, -				   struct btrfs_path *path, u64 offset) +static noinline_for_stack +int write_cache_extent_entries(struct io_ctl *io_ctl, +			      struct btrfs_free_space_ctl *ctl, +			      struct btrfs_block_group_cache *block_group, +			      int *entries, int *bitmaps, +			      struct list_head *bitmap_list)  { -	struct btrfs_free_space_header *header; -	struct extent_buffer *leaf; -	struct rb_node *node; -	struct list_head *pos, *n; -	struct extent_state *cached_state = NULL; -	struct btrfs_free_cluster *cluster = NULL; -	struct extent_io_tree *unpin = NULL; -	struct io_ctl io_ctl; -	struct list_head bitmap_list; -	struct btrfs_key key; -	u64 start, extent_start, extent_end, len; -	int entries = 0; -	int bitmaps = 0;  	int ret; -	int err = -1; - -	INIT_LIST_HEAD(&bitmap_list); - -	if (!i_size_read(inode)) -		return -1; - -	ret = io_ctl_init(&io_ctl, inode, root); -	if (ret) -		return -1; +	struct btrfs_free_cluster *cluster = NULL; +	struct rb_node *node = rb_first(&ctl->free_space_offset);  	/* Get the cluster for this block_group if it exists */ -	if (block_group && !list_empty(&block_group->cluster_list)) +	if (block_group && !list_empty(&block_group->cluster_list)) {  		cluster = list_entry(block_group->cluster_list.next,  				     struct btrfs_free_cluster,  				     block_group_list); +	} -	/* Lock all pages first so we can lock the extent safely. */ -	io_ctl_prepare_pages(&io_ctl, inode, 0); - -	lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, -			 0, &cached_state); - -	node = rb_first(&ctl->free_space_offset);  	if (!node && cluster) {  		node = rb_first(&cluster->root);  		cluster = NULL;  	} -	/* Make sure we can fit our crcs into the first page */ -	if (io_ctl.check_crcs && -	    (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) -		goto out_nospc; - -	io_ctl_set_generation(&io_ctl, trans->transid); -  	/* Write out the extent entries */  	while (node) {  		struct btrfs_free_space *e;  		e = rb_entry(node, struct btrfs_free_space, offset_index); -		entries++; +		*entries += 1; -		ret = io_ctl_add_entry(&io_ctl, e->offset, e->bytes, +		ret = io_ctl_add_entry(io_ctl, e->offset, e->bytes,  				       e->bitmap);  		if (ret) -			goto out_nospc; +			goto fail;  		if (e->bitmap) { -			list_add_tail(&e->list, &bitmap_list); -			bitmaps++; +			list_add_tail(&e->list, bitmap_list); +			*bitmaps += 1;  		}  		node = rb_next(node);  		if (!node && cluster) { @@ -943,131 +917,289 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,  			cluster = NULL;  		}  	} +	return 0; +fail: +	return -ENOSPC; +} + +static noinline_for_stack int +update_cache_item(struct btrfs_trans_handle *trans, +		  struct btrfs_root *root, +		  struct inode *inode, +		  struct btrfs_path *path, u64 offset, +		  int entries, int bitmaps) +{ +	struct btrfs_key key; +	struct btrfs_free_space_header *header; +	struct extent_buffer *leaf; +	int ret; + +	key.objectid = BTRFS_FREE_SPACE_OBJECTID; +	key.offset = offset; +	key.type = 0; + +	ret = btrfs_search_slot(trans, root, &key, path, 0, 1); +	if (ret < 0) { +		clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, +				 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL, +				 GFP_NOFS); +		goto fail; +	} +	leaf = path->nodes[0]; +	if (ret > 0) { +		struct btrfs_key found_key; +		ASSERT(path->slots[0]); +		path->slots[0]--; +		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); +		if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID || +		    found_key.offset != offset) { +			clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, +					 inode->i_size - 1, +					 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, +					 NULL, GFP_NOFS); +			btrfs_release_path(path); +			goto fail; +		} +	} + +	BTRFS_I(inode)->generation = trans->transid; +	header = btrfs_item_ptr(leaf, path->slots[0], +				struct btrfs_free_space_header); +	btrfs_set_free_space_entries(leaf, header, entries); +	btrfs_set_free_space_bitmaps(leaf, header, bitmaps); +	btrfs_set_free_space_generation(leaf, header, trans->transid); +	btrfs_mark_buffer_dirty(leaf); +	btrfs_release_path(path); + +	return 0; + +fail: +	return -1; +} + +static noinline_for_stack int +write_pinned_extent_entries(struct btrfs_root *root, +			    struct btrfs_block_group_cache *block_group, +			    struct io_ctl *io_ctl, +			    int *entries) +{ +	u64 start, extent_start, extent_end, len; +	struct extent_io_tree *unpin = NULL; +	int ret; + +	if (!block_group) +		return 0;  	/*  	 * We want to add any pinned extents to our free space cache  	 * so we don't leak the space -	 */ - -	/* +	 *  	 * We shouldn't have switched the pinned extents yet so this is the  	 * right one  	 */  	unpin = root->fs_info->pinned_extents; -	if (block_group) -		start = block_group->key.objectid; +	start = block_group->key.objectid; -	while (block_group && (start < block_group->key.objectid + -			       block_group->key.offset)) { +	while (start < block_group->key.objectid + block_group->key.offset) {  		ret = find_first_extent_bit(unpin, start,  					    &extent_start, &extent_end,  					    EXTENT_DIRTY, NULL); -		if (ret) { -			ret = 0; -			break; -		} +		if (ret) +			return 0;  		/* This pinned extent is out of our range */  		if (extent_start >= block_group->key.objectid +  		    block_group->key.offset) -			break; +			return 0;  		extent_start = max(extent_start, start);  		extent_end = min(block_group->key.objectid +  				 block_group->key.offset, extent_end + 1);  		len = extent_end - extent_start; -		entries++; -		ret = io_ctl_add_entry(&io_ctl, extent_start, len, NULL); +		*entries += 1; +		ret = io_ctl_add_entry(io_ctl, extent_start, len, NULL);  		if (ret) -			goto out_nospc; +			return -ENOSPC;  		start = extent_end;  	} +	return 0; +} + +static noinline_for_stack int +write_bitmap_entries(struct io_ctl *io_ctl, struct list_head *bitmap_list) +{ +	struct list_head *pos, *n; +	int ret; +  	/* Write out the bitmaps */ -	list_for_each_safe(pos, n, &bitmap_list) { +	list_for_each_safe(pos, n, bitmap_list) {  		struct btrfs_free_space *entry =  			list_entry(pos, struct btrfs_free_space, list); -		ret = io_ctl_add_bitmap(&io_ctl, entry->bitmap); +		ret = io_ctl_add_bitmap(io_ctl, entry->bitmap);  		if (ret) -			goto out_nospc; +			return -ENOSPC;  		list_del_init(&entry->list);  	} -	/* Zero out the rest of the pages just to make sure */ -	io_ctl_zero_remaining_pages(&io_ctl); +	return 0; +} -	ret = btrfs_dirty_pages(root, inode, io_ctl.pages, io_ctl.num_pages, -				0, i_size_read(inode), &cached_state); -	io_ctl_drop_pages(&io_ctl); -	unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, -			     i_size_read(inode) - 1, &cached_state, GFP_NOFS); +static int flush_dirty_cache(struct inode *inode) +{ +	int ret; +	ret = btrfs_wait_ordered_range(inode, 0, (u64)-1);  	if (ret) -		goto out; - - -	btrfs_wait_ordered_range(inode, 0, (u64)-1); - -	key.objectid = BTRFS_FREE_SPACE_OBJECTID; -	key.offset = offset; -	key.type = 0; - -	ret = btrfs_search_slot(trans, root, &key, path, 0, 1); -	if (ret < 0) {  		clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,  				 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL,  				 GFP_NOFS); -		goto out; + +	return ret; +} + +static void noinline_for_stack +cleanup_write_cache_enospc(struct inode *inode, +			   struct io_ctl *io_ctl, +			   struct extent_state **cached_state, +			   struct list_head *bitmap_list) +{ +	struct list_head *pos, *n; + +	list_for_each_safe(pos, n, bitmap_list) { +		struct btrfs_free_space *entry = +			list_entry(pos, struct btrfs_free_space, list); +		list_del_init(&entry->list);  	} -	leaf = path->nodes[0]; -	if (ret > 0) { -		struct btrfs_key found_key; -		ASSERT(path->slots[0]); -		path->slots[0]--; -		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); -		if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID || -		    found_key.offset != offset) { -			clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, -					 inode->i_size - 1, -					 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, -					 NULL, GFP_NOFS); -			btrfs_release_path(path); +	io_ctl_drop_pages(io_ctl); +	unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, +			     i_size_read(inode) - 1, cached_state, +			     GFP_NOFS); +} + +/** + * __btrfs_write_out_cache - write out cached info to an inode + * @root - the root the inode belongs to + * @ctl - the free space cache we are going to write out + * @block_group - the block_group for this cache if it belongs to a block_group + * @trans - the trans handle + * @path - the path to use + * @offset - the offset for the key we'll insert + * + * This function writes out a free space cache struct to disk for quick recovery + * on mount.  This will return 0 if it was successfull in writing the cache out, + * and -1 if it was not. + */ +static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, +				   struct btrfs_free_space_ctl *ctl, +				   struct btrfs_block_group_cache *block_group, +				   struct btrfs_trans_handle *trans, +				   struct btrfs_path *path, u64 offset) +{ +	struct extent_state *cached_state = NULL; +	struct io_ctl io_ctl; +	LIST_HEAD(bitmap_list); +	int entries = 0; +	int bitmaps = 0; +	int ret; + +	if (!i_size_read(inode)) +		return -1; + +	ret = io_ctl_init(&io_ctl, inode, root, 1); +	if (ret) +		return -1; + +	if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) { +		down_write(&block_group->data_rwsem); +		spin_lock(&block_group->lock); +		if (block_group->delalloc_bytes) { +			block_group->disk_cache_state = BTRFS_DC_WRITTEN; +			spin_unlock(&block_group->lock); +			up_write(&block_group->data_rwsem); +			BTRFS_I(inode)->generation = 0; +			ret = 0;  			goto out;  		} +		spin_unlock(&block_group->lock);  	} -	BTRFS_I(inode)->generation = trans->transid; -	header = btrfs_item_ptr(leaf, path->slots[0], -				struct btrfs_free_space_header); -	btrfs_set_free_space_entries(leaf, header, entries); -	btrfs_set_free_space_bitmaps(leaf, header, bitmaps); -	btrfs_set_free_space_generation(leaf, header, trans->transid); -	btrfs_mark_buffer_dirty(leaf); -	btrfs_release_path(path); +	/* Lock all pages first so we can lock the extent safely. */ +	io_ctl_prepare_pages(&io_ctl, inode, 0); + +	lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, +			 0, &cached_state); + +	io_ctl_set_generation(&io_ctl, trans->transid); + +	/* Write out the extent entries in the free space cache */ +	ret = write_cache_extent_entries(&io_ctl, ctl, +					 block_group, &entries, &bitmaps, +					 &bitmap_list); +	if (ret) +		goto out_nospc; + +	/* +	 * Some spaces that are freed in the current transaction are pinned, +	 * they will be added into free space cache after the transaction is +	 * committed, we shouldn't lose them. +	 */ +	ret = write_pinned_extent_entries(root, block_group, &io_ctl, &entries); +	if (ret) +		goto out_nospc; -	err = 0; +	/* At last, we write out all the bitmaps. */ +	ret = write_bitmap_entries(&io_ctl, &bitmap_list); +	if (ret) +		goto out_nospc; + +	/* Zero out the rest of the pages just to make sure */ +	io_ctl_zero_remaining_pages(&io_ctl); + +	/* Everything is written out, now we dirty the pages in the file. */ +	ret = btrfs_dirty_pages(root, inode, io_ctl.pages, io_ctl.num_pages, +				0, i_size_read(inode), &cached_state); +	if (ret) +		goto out_nospc; + +	if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) +		up_write(&block_group->data_rwsem); +	/* +	 * Release the pages and unlock the extent, we will flush +	 * them out later +	 */ +	io_ctl_drop_pages(&io_ctl); + +	unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, +			     i_size_read(inode) - 1, &cached_state, GFP_NOFS); + +	/* Flush the dirty pages in the cache file. */ +	ret = flush_dirty_cache(inode); +	if (ret) +		goto out; + +	/* Update the cache item to tell everyone this cache file is valid. */ +	ret = update_cache_item(trans, root, inode, path, offset, +				entries, bitmaps);  out:  	io_ctl_free(&io_ctl); -	if (err) { +	if (ret) {  		invalidate_inode_pages2(inode->i_mapping);  		BTRFS_I(inode)->generation = 0;  	}  	btrfs_update_inode(trans, root, inode); -	return err; +	return ret;  out_nospc: -	list_for_each_safe(pos, n, &bitmap_list) { -		struct btrfs_free_space *entry = -			list_entry(pos, struct btrfs_free_space, list); -		list_del_init(&entry->list); -	} -	io_ctl_drop_pages(&io_ctl); -	unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, -			     i_size_read(inode) - 1, &cached_state, GFP_NOFS); +	cleanup_write_cache_enospc(inode, &io_ctl, &cached_state, &bitmap_list); + +	if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) +		up_write(&block_group->data_rwsem); +  	goto out;  } @@ -1087,6 +1219,12 @@ int btrfs_write_out_cache(struct btrfs_root *root,  		spin_unlock(&block_group->lock);  		return 0;  	} + +	if (block_group->delalloc_bytes) { +		block_group->disk_cache_state = BTRFS_DC_WRITTEN; +		spin_unlock(&block_group->lock); +		return 0; +	}  	spin_unlock(&block_group->lock);  	inode = lookup_free_space_inode(root, block_group, path); @@ -1431,13 +1569,19 @@ static void bitmap_set_bits(struct btrfs_free_space_ctl *ctl,  	ctl->free_space += bytes;  } +/* + * If we can not find suitable extent, we will use bytes to record + * the size of the max extent. + */  static int search_bitmap(struct btrfs_free_space_ctl *ctl,  			 struct btrfs_free_space *bitmap_info, u64 *offset,  			 u64 *bytes)  {  	unsigned long found_bits = 0; +	unsigned long max_bits = 0;  	unsigned long bits, i;  	unsigned long next_zero; +	unsigned long extent_bits;  	i = offset_to_bit(bitmap_info->offset, ctl->unit,  			  max_t(u64, *offset, bitmap_info->offset)); @@ -1446,9 +1590,12 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,  	for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) {  		next_zero = find_next_zero_bit(bitmap_info->bitmap,  					       BITS_PER_BITMAP, i); -		if ((next_zero - i) >= bits) { -			found_bits = next_zero - i; +		extent_bits = next_zero - i; +		if (extent_bits >= bits) { +			found_bits = extent_bits;  			break; +		} else if (extent_bits > max_bits) { +			max_bits = extent_bits;  		}  		i = next_zero;  	} @@ -1459,38 +1606,41 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,  		return 0;  	} +	*bytes = (u64)(max_bits) * ctl->unit;  	return -1;  } +/* Cache the size of the max extent in bytes */  static struct btrfs_free_space *  find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, -		unsigned long align) +		unsigned long align, u64 *max_extent_size)  {  	struct btrfs_free_space *entry;  	struct rb_node *node; -	u64 ctl_off;  	u64 tmp;  	u64 align_off;  	int ret;  	if (!ctl->free_space_offset.rb_node) -		return NULL; +		goto out;  	entry = tree_search_offset(ctl, offset_to_bitmap(ctl, *offset), 0, 1);  	if (!entry) -		return NULL; +		goto out;  	for (node = &entry->offset_index; node; node = rb_next(node)) {  		entry = rb_entry(node, struct btrfs_free_space, offset_index); -		if (entry->bytes < *bytes) +		if (entry->bytes < *bytes) { +			if (entry->bytes > *max_extent_size) +				*max_extent_size = entry->bytes;  			continue; +		}  		/* make sure the space returned is big enough  		 * to match our requested alignment  		 */  		if (*bytes >= align) { -			ctl_off = entry->offset - ctl->start; -			tmp = ctl_off + align - 1;; +			tmp = entry->offset - ctl->start + align - 1;  			do_div(tmp, align);  			tmp = tmp * align + ctl->start;  			align_off = tmp - entry->offset; @@ -1499,14 +1649,22 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,  			tmp = entry->offset;  		} -		if (entry->bytes < *bytes + align_off) +		if (entry->bytes < *bytes + align_off) { +			if (entry->bytes > *max_extent_size) +				*max_extent_size = entry->bytes;  			continue; +		}  		if (entry->bitmap) { -			ret = search_bitmap(ctl, entry, &tmp, bytes); +			u64 size = *bytes; + +			ret = search_bitmap(ctl, entry, &tmp, &size);  			if (!ret) {  				*offset = tmp; +				*bytes = size;  				return entry; +			} else if (size > *max_extent_size) { +				*max_extent_size = size;  			}  			continue;  		} @@ -1515,7 +1673,7 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,  		*bytes = entry->bytes - align_off;  		return entry;  	} - +out:  	return NULL;  } @@ -1878,7 +2036,7 @@ out:  	spin_unlock(&ctl->tree_lock);  	if (ret) { -		printk(KERN_CRIT "btrfs: unable to add free space :%d\n", ret); +		printk(KERN_CRIT "BTRFS: unable to add free space :%d\n", ret);  		ASSERT(ret != -EEXIST);  	} @@ -1987,14 +2145,15 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,  		info = rb_entry(n, struct btrfs_free_space, offset_index);  		if (info->bytes >= bytes && !block_group->ro)  			count++; -		printk(KERN_CRIT "entry offset %llu, bytes %llu, bitmap %s\n", -		       info->offset, info->bytes, +		btrfs_crit(block_group->fs_info, +			   "entry offset %llu, bytes %llu, bitmap %s", +			   info->offset, info->bytes,  		       (info->bitmap) ? "yes" : "no");  	} -	printk(KERN_INFO "block group has cluster?: %s\n", +	btrfs_info(block_group->fs_info, "block group has cluster?: %s",  	       list_empty(&block_group->cluster_list) ? "no" : "yes"); -	printk(KERN_INFO "%d blocks of free space at or bigger than bytes is" -	       "\n", count); +	btrfs_info(block_group->fs_info, +		   "%d blocks of free space at or bigger than bytes is", count);  }  void btrfs_init_free_space_ctl(struct btrfs_block_group_cache *block_group) @@ -2116,7 +2275,8 @@ void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group)  }  u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, -			       u64 offset, u64 bytes, u64 empty_size) +			       u64 offset, u64 bytes, u64 empty_size, +			       u64 *max_extent_size)  {  	struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;  	struct btrfs_free_space *entry = NULL; @@ -2127,7 +2287,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,  	spin_lock(&ctl->tree_lock);  	entry = find_free_space(ctl, &offset, &bytes_search, -				block_group->full_stripe_len); +				block_group->full_stripe_len, max_extent_size);  	if (!entry)  		goto out; @@ -2137,7 +2297,6 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,  		if (!entry->bytes)  			free_bitmap(ctl, entry);  	} else { -  		unlink_free_space(ctl, entry);  		align_gap_len = offset - entry->offset;  		align_gap = entry->offset; @@ -2151,7 +2310,6 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,  		else  			link_free_space(ctl, entry);  	} -  out:  	spin_unlock(&ctl->tree_lock); @@ -2206,7 +2364,8 @@ int btrfs_return_cluster_to_free_space(  static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,  				   struct btrfs_free_cluster *cluster,  				   struct btrfs_free_space *entry, -				   u64 bytes, u64 min_start) +				   u64 bytes, u64 min_start, +				   u64 *max_extent_size)  {  	struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;  	int err; @@ -2218,8 +2377,11 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,  	search_bytes = bytes;  	err = search_bitmap(ctl, entry, &search_start, &search_bytes); -	if (err) +	if (err) { +		if (search_bytes > *max_extent_size) +			*max_extent_size = search_bytes;  		return 0; +	}  	ret = search_start;  	__bitmap_clear_bits(ctl, entry, ret, bytes); @@ -2234,7 +2396,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,   */  u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,  			     struct btrfs_free_cluster *cluster, u64 bytes, -			     u64 min_start) +			     u64 min_start, u64 *max_extent_size)  {  	struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;  	struct btrfs_free_space *entry = NULL; @@ -2253,7 +2415,10 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,  		goto out;  	entry = rb_entry(node, struct btrfs_free_space, offset_index); -	while(1) { +	while (1) { +		if (entry->bytes < bytes && entry->bytes > *max_extent_size) +			*max_extent_size = entry->bytes; +  		if (entry->bytes < bytes ||  		    (!entry->bitmap && entry->offset < min_start)) {  			node = rb_next(&entry->offset_index); @@ -2267,7 +2432,8 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,  		if (entry->bitmap) {  			ret = btrfs_alloc_from_bitmap(block_group,  						      cluster, entry, bytes, -						      cluster->window_start); +						      cluster->window_start, +						      max_extent_size);  			if (ret == 0) {  				node = rb_next(&entry->offset_index);  				if (!node) @@ -2390,7 +2556,6 @@ setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,  	struct btrfs_free_space *entry = NULL;  	struct btrfs_free_space *last;  	struct rb_node *node; -	u64 window_start;  	u64 window_free;  	u64 max_extent;  	u64 total_size = 0; @@ -2412,7 +2577,6 @@ setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,  		entry = rb_entry(node, struct btrfs_free_space, offset_index);  	} -	window_start = entry->offset;  	window_free = entry->bytes;  	max_extent = entry->bytes;  	first = entry; @@ -2940,19 +3104,15 @@ out:  int btrfs_write_out_ino_cache(struct btrfs_root *root,  			      struct btrfs_trans_handle *trans, -			      struct btrfs_path *path) +			      struct btrfs_path *path, +			      struct inode *inode)  {  	struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; -	struct inode *inode;  	int ret;  	if (!btrfs_test_opt(root, INODE_MAP_CACHE))  		return 0; -	inode = lookup_free_ino_inode(root, path); -	if (IS_ERR(inode)) -		return 0; -  	ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0);  	if (ret) {  		btrfs_delalloc_release_metadata(inode, inode->i_size); @@ -2963,7 +3123,6 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,  #endif  	} -	iput(inode);  	return ret;  }  | 
