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

Commit d9d8b2a5 authored by Qu Wenruo's avatar Qu Wenruo Committed by Chris Mason
Browse files

btrfs: extent-tree: Switch to new check_data_free_space and free_reserved_data_space



Use new reserve/free for buffered write and inode cache.

For buffered write case, as nodatacow write won't increase quota account,
so unlike old behavior which does reserve before check nocow, now we
check nocow first and then only reserve data if we can't do nocow write.

Signed-off-by: default avatarQu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 4ceff079
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3356,7 +3356,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
	num_pages *= 16;
	num_pages *= PAGE_CACHE_SIZE;

	ret = btrfs_check_data_free_space(inode, num_pages, num_pages);
	ret = __btrfs_check_data_free_space(inode, 0, num_pages);
	if (ret)
		goto out_put;

@@ -3365,7 +3365,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
					      &alloc_hint);
	if (!ret)
		dcs = BTRFS_DC_SETUP;
	btrfs_free_reserved_data_space(inode, num_pages);
	__btrfs_free_reserved_data_space(inode, 0, num_pages);

out_put:
	iput(inode);
+21 −13
Original line number Diff line number Diff line
@@ -1507,12 +1507,17 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
		}

		reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
		ret = btrfs_check_data_free_space(inode, reserve_bytes, write_bytes);
		if (ret == -ENOSPC &&
		    (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
					      BTRFS_INODE_PREALLOC))) {

		if (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
					     BTRFS_INODE_PREALLOC)) {
			ret = check_can_nocow(inode, pos, &write_bytes);
			if (ret < 0)
				break;
			if (ret > 0) {
				/*
				 * For nodata cow case, no need to reserve
				 * data space.
				 */
				only_release_metadata = true;
				/*
				 * our prealloc extent may be smaller than
@@ -1521,20 +1526,19 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
				num_pages = DIV_ROUND_UP(write_bytes + offset,
							 PAGE_CACHE_SIZE);
				reserve_bytes = num_pages << PAGE_CACHE_SHIFT;
				ret = 0;
			} else {
				ret = -ENOSPC;
				goto reserve_metadata;
			}
		}

		if (ret)
		ret = __btrfs_check_data_free_space(inode, pos, write_bytes);
		if (ret < 0)
			break;

reserve_metadata:
		ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes);
		if (ret) {
			if (!only_release_metadata)
				btrfs_free_reserved_data_space(inode,
							       reserve_bytes);
				__btrfs_free_reserved_data_space(inode, pos,
							         write_bytes);
			else
				btrfs_end_write_no_snapshoting(root);
			break;
@@ -2566,8 +2570,11 @@ static long btrfs_fallocate(struct file *file, int mode,
	/*
	 * Make sure we have enough space before we do the
	 * allocation.
	 * XXX: The behavior must be changed to do accurate check first
	 * and then check data reserved space.
	 */
	ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start, alloc_end - alloc_start);
	ret = btrfs_check_data_free_space(inode, alloc_start,
					  alloc_end - alloc_start);
	if (ret)
		return ret;

@@ -2700,7 +2707,8 @@ static long btrfs_fallocate(struct file *file, int mode,
out:
	mutex_unlock(&inode->i_mutex);
	/* Let go of our reservation. */
	btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
	__btrfs_free_reserved_data_space(inode, alloc_start,
					 alloc_end - alloc_start);
	return ret;
}

+4 −4
Original line number Diff line number Diff line
@@ -3034,8 +3034,8 @@ int prealloc_file_extent_cluster(struct inode *inode,
	BUG_ON(cluster->start != cluster->boundary[0]);
	mutex_lock(&inode->i_mutex);

	ret = btrfs_check_data_free_space(inode, cluster->end +
					  1 - cluster->start, 0);
	ret = __btrfs_check_data_free_space(inode, cluster->start,
					    cluster->end + 1 - cluster->start);
	if (ret)
		goto out;

@@ -3056,8 +3056,8 @@ int prealloc_file_extent_cluster(struct inode *inode,
			break;
		nr++;
	}
	btrfs_free_reserved_data_space(inode, cluster->end +
				       1 - cluster->start);
	__btrfs_free_reserved_data_space(inode, cluster->start,
					 cluster->end + 1 - cluster->start);
out:
	mutex_unlock(&inode->i_mutex);
	return ret;