diff mbox series

[RFC,19/31] btrfs: Add reservation information to btrfs_iomap

Message ID d92db79ce8a41b7e0775f68f498ee6941264a0fd.1623567940.git.rgoldwyn@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs buffered iomap support | expand

Commit Message

Goldwyn Rodrigues June 13, 2021, 1:39 p.m. UTC
From: Goldwyn Rodrigues <rgoldwyn@suse.com>

Move reservation information into btrfs_iomap.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
---
 fs/btrfs/file.c | 49 +++++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 24 deletions(-)

Comments

David Sterba June 16, 2021, 8:03 p.m. UTC | #1
On Sun, Jun 13, 2021 at 08:39:47AM -0500, Goldwyn Rodrigues wrote:
> From: Goldwyn Rodrigues <rgoldwyn@suse.com>
> 
> Move reservation information into btrfs_iomap.
> 
> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
> ---
>  fs/btrfs/file.c | 49 +++++++++++++++++++++++++------------------------
>  1 file changed, 25 insertions(+), 24 deletions(-)
> 
> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> index 3d4b8fde47f4..ccae8ce7ec4f 100644
> --- a/fs/btrfs/file.c
> +++ b/fs/btrfs/file.c
> @@ -63,6 +63,11 @@ struct btrfs_iomap {
>  	u64 lockend;
>  	struct extent_state *cached_state;
>  	int extents_locked;
> +
> +	/* Reservation */
> +	bool metadata_only;
> +	struct extent_changeset *data_reserved;
> +	size_t reserved_bytes;
>  };
>  
>  static int __compare_inode_defrag(struct inode_defrag *defrag1,
> @@ -1630,12 +1635,10 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  	struct inode *inode = file_inode(file);
>  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
>  	struct page **pages = NULL;
> -	struct extent_changeset *data_reserved = NULL;
>  	u64 release_bytes = 0;
>  	size_t num_written = 0;
>  	int nrptrs;
> -	ssize_t ret;
> -	bool only_release_metadata = false;
> +	int ret;
>  	loff_t old_isize = i_size_read(inode);
>  	unsigned int ilock_flags = 0;
>  	struct btrfs_iomap *bi = NULL;
> @@ -1673,14 +1676,12 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  	}
>  
>  	while (iov_iter_count(i) > 0) {
> -		struct extent_state *cached_state = NULL;
>  		size_t offset = offset_in_page(pos);
>  		size_t sector_offset;
>  		size_t write_bytes = min(iov_iter_count(i),
>  					 nrptrs * (size_t)PAGE_SIZE -
>  					 offset);
>  		size_t num_pages;
> -		size_t reserve_bytes;
>  		size_t dirty_pages;
>  		size_t copied;
>  		size_t dirty_sectors;
> @@ -1696,12 +1697,12 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  		}
>  
>  		bi->extents_locked = false;
> -		only_release_metadata = false;
> +		bi->metadata_only = false;
>  		sector_offset = pos & (fs_info->sectorsize - 1);
>  
> -		extent_changeset_release(data_reserved);
> +		extent_changeset_release(bi->data_reserved);
>  		ret = btrfs_check_data_free_space(BTRFS_I(inode),
> -						  &data_reserved, pos,
> +						  &bi->data_reserved, pos,
>  						  write_bytes);
>  		if (ret < 0) {
>  			/*
> @@ -1711,36 +1712,36 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  			 */
>  			if (btrfs_check_nocow_lock(BTRFS_I(inode), pos,
>  						   &write_bytes) > 0)
> -				only_release_metadata = true;
> +				bi->metadata_only = true;
>  			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,
> +		bi->reserved_bytes = round_up(write_bytes + sector_offset,
>  					 fs_info->sectorsize);
> -		WARN_ON(reserve_bytes == 0);
> +		WARN_ON(bi->reserved_bytes == 0);
>  		ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode),
> -				reserve_bytes);
> +				bi->reserved_bytes);
>  		if (ret) {
> -			if (!only_release_metadata)
> +			if (!bi->metadata_only)
>  				btrfs_free_reserved_data_space(BTRFS_I(inode),
> -						data_reserved, pos,
> +						bi->data_reserved, pos,
>  						write_bytes);
>  			else
>  				btrfs_check_nocow_unlock(BTRFS_I(inode));
>  			break;
>  		}
>  
> -		release_bytes = reserve_bytes;
> +		release_bytes = bi->reserved_bytes;
>  
>  		if (pos < inode->i_size) {
>  			bi->lockstart = round_down(pos, fs_info->sectorsize);
>  			bi->lockend = round_up(pos + write_bytes, fs_info->sectorsize) - 1;
>  			btrfs_lock_and_flush_ordered_range(BTRFS_I(inode),
>  					bi->lockstart, bi->lockend,
> -					&cached_state);
> +					&bi->cached_state);
>  			bi->extents_locked = true;
>  		}
>  
> @@ -1753,13 +1754,13 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  				    pos, write_bytes);
>  		if (ret) {
>  			btrfs_delalloc_release_extents(BTRFS_I(inode),
> -						       reserve_bytes);
> +						       bi->reserved_bytes);
>  			break;
>  		}
>  
>  		copied = btrfs_copy_from_user(pos, write_bytes, pages, i);
>  
> -		num_sectors = BTRFS_BYTES_TO_BLKS(fs_info, reserve_bytes);
> +		num_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bi->reserved_bytes);
>  		dirty_sectors = round_up(copied + sector_offset,
>  					fs_info->sectorsize);
>  		dirty_sectors = BTRFS_BYTES_TO_BLKS(fs_info, dirty_sectors);
> @@ -1782,7 +1783,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  		if (num_sectors > dirty_sectors) {
>  			/* release everything except the sectors we dirtied */
>  			release_bytes -= dirty_sectors << fs_info->sectorsize_bits;
> -			if (only_release_metadata) {
> +			if (bi->metadata_only) {
>  				btrfs_delalloc_release_metadata(BTRFS_I(inode),
>  							release_bytes, true);
>  			} else {
> @@ -1792,7 +1793,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  						   fs_info->sectorsize) +
>  					(dirty_pages << PAGE_SHIFT);
>  				btrfs_delalloc_release_space(BTRFS_I(inode),
> -						data_reserved, __pos,
> +						bi->data_reserved, __pos,
>  						release_bytes, true);
>  			}
>  		}
> @@ -1802,7 +1803,8 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  
>  		ret = btrfs_dirty_pages(BTRFS_I(inode), pages,
>  					dirty_pages, pos, copied,
> -					&cached_state, only_release_metadata);
> +					&bi->cached_state,
> +					bi->metadata_only);
>  
>  		/*
>  		 * If we have not locked the extent range, because the range's
> @@ -1819,14 +1821,14 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  			free_extent_state(bi->cached_state);
>  		bi->extents_locked = false;
>  
> -		btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes);
> +		btrfs_delalloc_release_extents(BTRFS_I(inode), bi->reserved_bytes);
>  		if (ret) {
>  			btrfs_drop_pages(pages, num_pages);
>  			break;
>  		}
>  
>  		release_bytes = 0;
> -		if (only_release_metadata)
> +		if (bi->metadata_only)
>  			btrfs_check_nocow_unlock(BTRFS_I(inode));
>  
>  		btrfs_drop_pages(pages, num_pages);
> @@ -1850,7 +1852,6 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
>  		btrfs_check_nocow_unlock(BTRFS_I(inode));
>  	btrfs_iomap_release(inode, pos, release_bytes, bi);
>  out:
> -	kfree(bi);

Is this intentional? Or I don't see the pairing kfree that happens
elsewhere.

>  	btrfs_inode_unlock(inode, ilock_flags);
>  	return num_written ? num_written : ret;
>  }
> -- 
> 2.31.1
diff mbox series

Patch

diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 3d4b8fde47f4..ccae8ce7ec4f 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -63,6 +63,11 @@  struct btrfs_iomap {
 	u64 lockend;
 	struct extent_state *cached_state;
 	int extents_locked;
+
+	/* Reservation */
+	bool metadata_only;
+	struct extent_changeset *data_reserved;
+	size_t reserved_bytes;
 };
 
 static int __compare_inode_defrag(struct inode_defrag *defrag1,
@@ -1630,12 +1635,10 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 	struct inode *inode = file_inode(file);
 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 	struct page **pages = NULL;
-	struct extent_changeset *data_reserved = NULL;
 	u64 release_bytes = 0;
 	size_t num_written = 0;
 	int nrptrs;
-	ssize_t ret;
-	bool only_release_metadata = false;
+	int ret;
 	loff_t old_isize = i_size_read(inode);
 	unsigned int ilock_flags = 0;
 	struct btrfs_iomap *bi = NULL;
@@ -1673,14 +1676,12 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 	}
 
 	while (iov_iter_count(i) > 0) {
-		struct extent_state *cached_state = NULL;
 		size_t offset = offset_in_page(pos);
 		size_t sector_offset;
 		size_t write_bytes = min(iov_iter_count(i),
 					 nrptrs * (size_t)PAGE_SIZE -
 					 offset);
 		size_t num_pages;
-		size_t reserve_bytes;
 		size_t dirty_pages;
 		size_t copied;
 		size_t dirty_sectors;
@@ -1696,12 +1697,12 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 		}
 
 		bi->extents_locked = false;
-		only_release_metadata = false;
+		bi->metadata_only = false;
 		sector_offset = pos & (fs_info->sectorsize - 1);
 
-		extent_changeset_release(data_reserved);
+		extent_changeset_release(bi->data_reserved);
 		ret = btrfs_check_data_free_space(BTRFS_I(inode),
-						  &data_reserved, pos,
+						  &bi->data_reserved, pos,
 						  write_bytes);
 		if (ret < 0) {
 			/*
@@ -1711,36 +1712,36 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 			 */
 			if (btrfs_check_nocow_lock(BTRFS_I(inode), pos,
 						   &write_bytes) > 0)
-				only_release_metadata = true;
+				bi->metadata_only = true;
 			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,
+		bi->reserved_bytes = round_up(write_bytes + sector_offset,
 					 fs_info->sectorsize);
-		WARN_ON(reserve_bytes == 0);
+		WARN_ON(bi->reserved_bytes == 0);
 		ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode),
-				reserve_bytes);
+				bi->reserved_bytes);
 		if (ret) {
-			if (!only_release_metadata)
+			if (!bi->metadata_only)
 				btrfs_free_reserved_data_space(BTRFS_I(inode),
-						data_reserved, pos,
+						bi->data_reserved, pos,
 						write_bytes);
 			else
 				btrfs_check_nocow_unlock(BTRFS_I(inode));
 			break;
 		}
 
-		release_bytes = reserve_bytes;
+		release_bytes = bi->reserved_bytes;
 
 		if (pos < inode->i_size) {
 			bi->lockstart = round_down(pos, fs_info->sectorsize);
 			bi->lockend = round_up(pos + write_bytes, fs_info->sectorsize) - 1;
 			btrfs_lock_and_flush_ordered_range(BTRFS_I(inode),
 					bi->lockstart, bi->lockend,
-					&cached_state);
+					&bi->cached_state);
 			bi->extents_locked = true;
 		}
 
@@ -1753,13 +1754,13 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 				    pos, write_bytes);
 		if (ret) {
 			btrfs_delalloc_release_extents(BTRFS_I(inode),
-						       reserve_bytes);
+						       bi->reserved_bytes);
 			break;
 		}
 
 		copied = btrfs_copy_from_user(pos, write_bytes, pages, i);
 
-		num_sectors = BTRFS_BYTES_TO_BLKS(fs_info, reserve_bytes);
+		num_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bi->reserved_bytes);
 		dirty_sectors = round_up(copied + sector_offset,
 					fs_info->sectorsize);
 		dirty_sectors = BTRFS_BYTES_TO_BLKS(fs_info, dirty_sectors);
@@ -1782,7 +1783,7 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 		if (num_sectors > dirty_sectors) {
 			/* release everything except the sectors we dirtied */
 			release_bytes -= dirty_sectors << fs_info->sectorsize_bits;
-			if (only_release_metadata) {
+			if (bi->metadata_only) {
 				btrfs_delalloc_release_metadata(BTRFS_I(inode),
 							release_bytes, true);
 			} else {
@@ -1792,7 +1793,7 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 						   fs_info->sectorsize) +
 					(dirty_pages << PAGE_SHIFT);
 				btrfs_delalloc_release_space(BTRFS_I(inode),
-						data_reserved, __pos,
+						bi->data_reserved, __pos,
 						release_bytes, true);
 			}
 		}
@@ -1802,7 +1803,8 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 
 		ret = btrfs_dirty_pages(BTRFS_I(inode), pages,
 					dirty_pages, pos, copied,
-					&cached_state, only_release_metadata);
+					&bi->cached_state,
+					bi->metadata_only);
 
 		/*
 		 * If we have not locked the extent range, because the range's
@@ -1819,14 +1821,14 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 			free_extent_state(bi->cached_state);
 		bi->extents_locked = false;
 
-		btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes);
+		btrfs_delalloc_release_extents(BTRFS_I(inode), bi->reserved_bytes);
 		if (ret) {
 			btrfs_drop_pages(pages, num_pages);
 			break;
 		}
 
 		release_bytes = 0;
-		if (only_release_metadata)
+		if (bi->metadata_only)
 			btrfs_check_nocow_unlock(BTRFS_I(inode));
 
 		btrfs_drop_pages(pages, num_pages);
@@ -1850,7 +1852,6 @@  static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 		btrfs_check_nocow_unlock(BTRFS_I(inode));
 	btrfs_iomap_release(inode, pos, release_bytes, bi);
 out:
-	kfree(bi);
 	btrfs_inode_unlock(inode, ilock_flags);
 	return num_written ? num_written : ret;
 }