Commit eefa45f5 authored by Goldwyn Rodrigues's avatar Goldwyn Rodrigues Committed by David Sterba
Browse files

btrfs: calculate num_pages, reserve_bytes once in btrfs_buffered_write



write_bytes can change in btrfs_check_nocow_lock(). Calculate variables
such as num_pages and reserve_bytes once we are sure of the value of
write_bytes so there is no need to re-calculate.

Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent fb8a7e94
Loading
Loading
Loading
Loading
+12 −22
Original line number Diff line number Diff line
@@ -1591,8 +1591,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
		size_t write_bytes = min(iov_iter_count(i),
					 nrptrs * (size_t)PAGE_SIZE -
					 offset);
		size_t num_pages = DIV_ROUND_UP(write_bytes + offset,
						PAGE_SIZE);
		size_t num_pages;
		size_t reserve_bytes;
		size_t dirty_pages;
		size_t copied;
@@ -1600,8 +1599,6 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
		size_t num_sectors;
		int extents_locked;

		WARN_ON(num_pages > nrptrs);

		/*
		 * Fault pages before locking them in prepare_pages
		 * to avoid recursive lock
@@ -1613,35 +1610,28 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,

		only_release_metadata = false;
		sector_offset = pos & (fs_info->sectorsize - 1);
		reserve_bytes = round_up(write_bytes + sector_offset,
				fs_info->sectorsize);

		extent_changeset_release(data_reserved);
		ret = btrfs_check_data_free_space(BTRFS_I(inode),
						  &data_reserved, pos,
						  write_bytes);
		if (ret < 0) {
			if (btrfs_check_nocow_lock(BTRFS_I(inode), pos,
						   &write_bytes) > 0) {
			/*
				 * For nodata cow case, no need to reserve
				 * data space.
			 * 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;
				/*
				 * our prealloc extent may be smaller than
				 * write_bytes, so scale down.
				 */
				num_pages = DIV_ROUND_UP(write_bytes + offset,
							 PAGE_SIZE);
				reserve_bytes = round_up(write_bytes +
							 sector_offset,
							 fs_info->sectorsize);
			} else {
			else
				break;
		}
		}

		num_pages = DIV_ROUND_UP(write_bytes + offset, PAGE_SIZE);
		WARN_ON(num_pages > nrptrs);
		reserve_bytes = round_up(write_bytes + sector_offset,
					 fs_info->sectorsize);
		WARN_ON(reserve_bytes == 0);
		ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode),
				reserve_bytes);