[v5,17/28] btrfs: support direct write IO in HMZONED
diff mbox series

Message ID 20191204081735.852438-18-naohiro.aota@wdc.com
State New
Headers show
Series
  • btrfs: zoned block device support
Related show

Commit Message

Naohiro Aota Dec. 4, 2019, 8:17 a.m. UTC
As same as with other IO submission, we must unlock a block group for the
next allocation.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/inode.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Patch
diff mbox series

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e09089e24a8f..44658590c6e8 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -60,6 +60,7 @@  struct btrfs_dio_data {
 	u64 reserve;
 	u64 unsubmitted_oe_range_start;
 	u64 unsubmitted_oe_range_end;
+	u64 alloc_end;
 	int overwrite;
 };
 
@@ -7787,6 +7788,12 @@  static int btrfs_get_blocks_direct_write(struct extent_map **map,
 		}
 	}
 
+	if (dio_data->alloc_end) {
+		btrfs_hmzoned_data_io_unlock_logical(fs_info,
+						     dio_data->alloc_end - 1);
+		dio_data->alloc_end = 0;
+	}
+
 	/* this will cow the extent */
 	len = bh_result->b_size;
 	free_extent_map(em);
@@ -7818,6 +7825,7 @@  static int btrfs_get_blocks_direct_write(struct extent_map **map,
 	WARN_ON(dio_data->reserve < len);
 	dio_data->reserve -= len;
 	dio_data->unsubmitted_oe_range_end = start + len;
+	dio_data->alloc_end = em->block_start + (start - em->start) + len;
 	current->journal_info = dio_data;
 out:
 	return ret;
@@ -8585,6 +8593,7 @@  static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode,
 	struct btrfs_io_bio *io_bio;
 	bool write = (bio_op(dio_bio) == REQ_OP_WRITE);
 	int ret = 0;
+	u64 disk_bytenr, len;
 
 	bio = btrfs_bio_clone(dio_bio);
 
@@ -8628,7 +8637,18 @@  static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode,
 			dio_data->unsubmitted_oe_range_end;
 	}
 
+	disk_bytenr = dip->disk_bytenr;
+	len = dip->bytes;
 	ret = btrfs_submit_direct_hook(dip);
+	if (write) {
+		struct btrfs_dio_data *dio_data = current->journal_info;
+
+		if (disk_bytenr + len == dio_data->alloc_end) {
+			btrfs_hmzoned_data_io_unlock_logical(
+				btrfs_sb(inode->i_sb), disk_bytenr);
+			dio_data->alloc_end = 0;
+		}
+	}
 	if (!ret)
 		return;
 
@@ -8804,6 +8824,11 @@  static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 			btrfs_delalloc_release_space(inode, data_reserved,
 					offset, count - (size_t)ret, true);
 		btrfs_delalloc_release_extents(BTRFS_I(inode), count);
+		if (dio_data.alloc_end) {
+			pr_info("unlock final direct %llu", dio_data.alloc_end);
+			btrfs_hmzoned_data_io_unlock_logical(
+				fs_info, dio_data.alloc_end - 1);
+		}
 	}
 out:
 	if (wakeup)