mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	btrfs: make btrfs_check_nocow_lock nowait compatible
Now all the helpers that btrfs_check_nocow_lock uses handle nowait, add a nowait flag to btrfs_check_nocow_lock so it can be used by the write path. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Stefan Roesch <shr@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									d2c7a19f5c
								
							
						
					
					
						commit
						80f9d24130
					
				
					 3 changed files with 25 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -3525,7 +3525,7 @@ int btrfs_dirty_pages(struct btrfs_inode *inode, struct page **pages,
 | 
			
		|||
		      struct extent_state **cached, bool noreserve);
 | 
			
		||||
int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end);
 | 
			
		||||
int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
 | 
			
		||||
			   size_t *write_bytes);
 | 
			
		||||
			   size_t *write_bytes, bool nowait);
 | 
			
		||||
void btrfs_check_nocow_unlock(struct btrfs_inode *inode);
 | 
			
		||||
bool btrfs_find_delalloc_in_range(struct btrfs_inode *inode, u64 start, u64 end,
 | 
			
		||||
				  u64 *delalloc_start_ret, u64 *delalloc_end_ret);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1480,7 +1480,7 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages,
 | 
			
		|||
 * NOTE: Callers need to call btrfs_check_nocow_unlock() if we return > 0.
 | 
			
		||||
 */
 | 
			
		||||
int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
 | 
			
		||||
			   size_t *write_bytes)
 | 
			
		||||
			   size_t *write_bytes, bool nowait)
 | 
			
		||||
{
 | 
			
		||||
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
 | 
			
		||||
	struct btrfs_root *root = inode->root;
 | 
			
		||||
| 
						 | 
				
			
			@ -1499,16 +1499,21 @@ int btrfs_check_nocow_lock(struct btrfs_inode *inode, loff_t pos,
 | 
			
		|||
			   fs_info->sectorsize) - 1;
 | 
			
		||||
	num_bytes = lockend - lockstart + 1;
 | 
			
		||||
 | 
			
		||||
	btrfs_lock_and_flush_ordered_range(inode, lockstart, lockend, NULL);
 | 
			
		||||
	ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes,
 | 
			
		||||
			NULL, NULL, NULL, false, false);
 | 
			
		||||
	if (ret <= 0) {
 | 
			
		||||
		ret = 0;
 | 
			
		||||
		btrfs_drew_write_unlock(&root->snapshot_lock);
 | 
			
		||||
	if (nowait) {
 | 
			
		||||
		if (!btrfs_try_lock_ordered_range(inode, lockstart, lockend)) {
 | 
			
		||||
			btrfs_drew_write_unlock(&root->snapshot_lock);
 | 
			
		||||
			return -EAGAIN;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		btrfs_lock_and_flush_ordered_range(inode, lockstart, lockend, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	ret = can_nocow_extent(&inode->vfs_inode, lockstart, &num_bytes,
 | 
			
		||||
			NULL, NULL, NULL, nowait, false);
 | 
			
		||||
	if (ret <= 0)
 | 
			
		||||
		btrfs_drew_write_unlock(&root->snapshot_lock);
 | 
			
		||||
	else
 | 
			
		||||
		*write_bytes = min_t(size_t, *write_bytes ,
 | 
			
		||||
				     num_bytes - pos + lockstart);
 | 
			
		||||
	}
 | 
			
		||||
	unlock_extent(&inode->io_tree, lockstart, lockend, NULL);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -1665,16 +1670,22 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 | 
			
		|||
						  &data_reserved, pos,
 | 
			
		||||
						  write_bytes, false);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			int can_nocow;
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * If we don't have to COW at the offset, reserve
 | 
			
		||||
			 * metadata only. write_bytes may get smaller than
 | 
			
		||||
			 * requested here.
 | 
			
		||||
			 */
 | 
			
		||||
			if (btrfs_check_nocow_lock(BTRFS_I(inode), pos,
 | 
			
		||||
						   &write_bytes) > 0)
 | 
			
		||||
				only_release_metadata = true;
 | 
			
		||||
			else
 | 
			
		||||
			can_nocow = btrfs_check_nocow_lock(BTRFS_I(inode), pos,
 | 
			
		||||
							   &write_bytes, false);
 | 
			
		||||
			if (can_nocow < 0)
 | 
			
		||||
				ret = can_nocow;
 | 
			
		||||
			if (can_nocow > 0)
 | 
			
		||||
				ret = 0;
 | 
			
		||||
			if (ret)
 | 
			
		||||
				break;
 | 
			
		||||
			only_release_metadata = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		num_pages = DIV_ROUND_UP(write_bytes + offset, PAGE_SIZE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4887,7 +4887,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len,
 | 
			
		|||
	ret = btrfs_check_data_free_space(inode, &data_reserved, block_start,
 | 
			
		||||
					  blocksize, false);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		if (btrfs_check_nocow_lock(inode, block_start, &write_bytes) > 0) {
 | 
			
		||||
		if (btrfs_check_nocow_lock(inode, block_start, &write_bytes, false) > 0) {
 | 
			
		||||
			/* For nocow case, no need to reserve data space */
 | 
			
		||||
			only_release_metadata = true;
 | 
			
		||||
		} else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue