diff options
Diffstat (limited to 'fs/btrfs/ordered-data.c')
| -rw-r--r-- | fs/btrfs/ordered-data.c | 63 | 
1 files changed, 38 insertions, 25 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index e13b3d28c063..ebac13389e7e 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -15,6 +15,7 @@  #include "disk-io.h"  #include "compression.h"  #include "delalloc-space.h" +#include "qgroup.h"  static struct kmem_cache *btrfs_ordered_extent_cache; @@ -152,23 +153,39 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,  	return ret;  } -/* allocate and add a new ordered_extent into the per-inode tree. +/* + * Allocate and add a new ordered_extent into the per-inode tree.   *   * The tree is given a single reference on the ordered extent that was   * inserted.   */ -static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, +static int __btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset,  				      u64 disk_bytenr, u64 num_bytes,  				      u64 disk_num_bytes, int type, int dio,  				      int compress_type)  { -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); -	struct btrfs_root *root = BTRFS_I(inode)->root; -	struct btrfs_ordered_inode_tree *tree; +	struct btrfs_root *root = inode->root; +	struct btrfs_fs_info *fs_info = root->fs_info; +	struct btrfs_ordered_inode_tree *tree = &inode->ordered_tree;  	struct rb_node *node;  	struct btrfs_ordered_extent *entry; +	int ret; -	tree = &BTRFS_I(inode)->ordered_tree; +	if (type == BTRFS_ORDERED_NOCOW || type == BTRFS_ORDERED_PREALLOC) { +		/* For nocow write, we can release the qgroup rsv right now */ +		ret = btrfs_qgroup_free_data(inode, NULL, file_offset, num_bytes); +		if (ret < 0) +			return ret; +		ret = 0; +	} else { +		/* +		 * The ordered extent has reserved qgroup space, release now +		 * and pass the reserved number for qgroup_record to free. +		 */ +		ret = btrfs_qgroup_release_data(inode, file_offset, num_bytes); +		if (ret < 0) +			return ret; +	}  	entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS);  	if (!entry)  		return -ENOMEM; @@ -178,9 +195,10 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,  	entry->num_bytes = num_bytes;  	entry->disk_num_bytes = disk_num_bytes;  	entry->bytes_left = num_bytes; -	entry->inode = igrab(inode); +	entry->inode = igrab(&inode->vfs_inode);  	entry->compress_type = compress_type;  	entry->truncated_len = (u64)-1; +	entry->qgroup_rsv = ret;  	if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)  		set_bit(type, &entry->flags); @@ -197,10 +215,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,  	INIT_LIST_HEAD(&entry->root_extent_list);  	INIT_LIST_HEAD(&entry->work_list);  	init_completion(&entry->completion); -	INIT_LIST_HEAD(&entry->log_list); -	INIT_LIST_HEAD(&entry->trans_list); -	trace_btrfs_ordered_extent_add(inode, entry); +	trace_btrfs_ordered_extent_add(&inode->vfs_inode, entry);  	spin_lock_irq(&tree->lock);  	node = tree_insert(&tree->tree, file_offset, @@ -228,14 +244,14 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,  	 * that work has been done at higher layers, so this is truly the  	 * smallest the extent is going to get.  	 */ -	spin_lock(&BTRFS_I(inode)->lock); -	btrfs_mod_outstanding_extents(BTRFS_I(inode), 1); -	spin_unlock(&BTRFS_I(inode)->lock); +	spin_lock(&inode->lock); +	btrfs_mod_outstanding_extents(inode, 1); +	spin_unlock(&inode->lock);  	return 0;  } -int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, +int btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset,  			     u64 disk_bytenr, u64 num_bytes, u64 disk_num_bytes,  			     int type)  { @@ -244,7 +260,7 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,  					  BTRFS_COMPRESS_NONE);  } -int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, +int btrfs_add_ordered_extent_dio(struct btrfs_inode *inode, u64 file_offset,  				 u64 disk_bytenr, u64 num_bytes,  				 u64 disk_num_bytes, int type)  { @@ -253,7 +269,7 @@ int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,  					  BTRFS_COMPRESS_NONE);  } -int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset, +int btrfs_add_ordered_extent_compress(struct btrfs_inode *inode, u64 file_offset,  				      u64 disk_bytenr, u64 num_bytes,  				      u64 disk_num_bytes, int type,  				      int compress_type) @@ -291,12 +307,12 @@ void btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry,   * file_offset is updated to one byte past the range that is recorded as   * complete.  This allows you to walk forward in the file.   */ -int btrfs_dec_test_first_ordered_pending(struct inode *inode, +int btrfs_dec_test_first_ordered_pending(struct btrfs_inode *inode,  				   struct btrfs_ordered_extent **cached,  				   u64 *file_offset, u64 io_size, int uptodate)  { -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); -	struct btrfs_ordered_inode_tree *tree; +	struct btrfs_fs_info *fs_info = inode->root->fs_info; +	struct btrfs_ordered_inode_tree *tree = &inode->ordered_tree;  	struct rb_node *node;  	struct btrfs_ordered_extent *entry = NULL;  	int ret; @@ -305,7 +321,6 @@ int btrfs_dec_test_first_ordered_pending(struct inode *inode,  	u64 dec_start;  	u64 to_dec; -	tree = &BTRFS_I(inode)->ordered_tree;  	spin_lock_irqsave(&tree->lock, flags);  	node = tree_search(tree, *file_offset);  	if (!node) { @@ -429,8 +444,6 @@ void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)  	trace_btrfs_ordered_extent_put(entry->inode, entry);  	if (refcount_dec_and_test(&entry->refs)) { -		ASSERT(list_empty(&entry->log_list)); -		ASSERT(list_empty(&entry->trans_list));  		ASSERT(list_empty(&entry->root_extent_list));  		ASSERT(RB_EMPTY_NODE(&entry->rb_node));  		if (entry->inode) @@ -698,14 +711,14 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)   * find an ordered extent corresponding to file_offset.  return NULL if   * nothing is found, otherwise take a reference on the extent and return it   */ -struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, +struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct btrfs_inode *inode,  							 u64 file_offset)  {  	struct btrfs_ordered_inode_tree *tree;  	struct rb_node *node;  	struct btrfs_ordered_extent *entry = NULL; -	tree = &BTRFS_I(inode)->ordered_tree; +	tree = &inode->ordered_tree;  	spin_lock_irq(&tree->lock);  	node = tree_search(tree, file_offset);  	if (!node) @@ -803,7 +816,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,  	const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);  	int index = 0; -	ordered = btrfs_lookup_ordered_extent(inode, offset); +	ordered = btrfs_lookup_ordered_extent(BTRFS_I(inode), offset);  	if (!ordered)  		return 0;  |