All of lore.kernel.org
 help / color / mirror / Atom feed
From: Naohiro Aota <naohiro.aota@wdc.com>
To: linux-btrfs@vger.kernel.org, dsterba@suse.com
Cc: hare@suse.com, linux-fsdevel@vger.kernel.org,
	Naohiro Aota <naohiro.aota@wdc.com>
Subject: [PATCH v8 25/41] btrfs: use ZONE_APPEND write for ZONED btrfs
Date: Fri,  2 Oct 2020 03:36:32 +0900	[thread overview]
Message-ID: <1727a2fbaa17db7c5d3447d2f547b98cb5f9bf32.1601574234.git.naohiro.aota@wdc.com> (raw)
In-Reply-To: <dece91bca322ce44bed19f2b0f460fa5ded2e512.1601574234.git.naohiro.aota@wdc.com>

This commit enables zone append writing for zoned btrfs. Three parts are
necessary to enable it. First, it modifies bio to use REQ_OP_ZONE_APPEND in
btrfs_submit_bio_hook() and adjust the bi_sector to point the beginning of
the zone.

Second, it records returned physical address (and disk/partno) to
the ordered extent in end_bio_extent_writepage().

Finally, it rewrites logical addresses of the extent mapping and checksum
data according to the physical address (using __btrfs_rmap_block). If the
returned address match to the originaly allocated address, we can skip the
rewriting process.

[Johannes] fixed bvec handling
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/extent_io.c    | 12 +++++++-
 fs/btrfs/inode.c        |  6 +++-
 fs/btrfs/ordered-data.c |  3 ++
 fs/btrfs/ordered-data.h |  4 +++
 fs/btrfs/volumes.c      |  9 ++++++
 fs/btrfs/zoned.c        | 68 +++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/zoned.h        |  9 ++++++
 7 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 5ee94a2ffa22..bbcdc8dfbd45 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2743,6 +2743,7 @@ static void end_bio_extent_writepage(struct bio *bio)
 	u64 start;
 	u64 end;
 	struct bvec_iter_all iter_all;
+	bool first_bvec = true;
 
 	ASSERT(!bio_flagged(bio, BIO_CLONED));
 	bio_for_each_segment_all(bvec, bio, iter_all) {
@@ -2769,6 +2770,11 @@ static void end_bio_extent_writepage(struct bio *bio)
 		start = page_offset(page);
 		end = start + bvec->bv_offset + bvec->bv_len - 1;
 
+		if (first_bvec) {
+			btrfs_record_physical_zoned(inode, start, bio);
+			first_bvec = false;
+		}
+
 		end_extent_writepage(page, error, start, end);
 		end_page_writeback(page);
 	}
@@ -3531,6 +3537,7 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
 	size_t blocksize;
 	int ret = 0;
 	int nr = 0;
+	int opf = REQ_OP_WRITE;
 	const unsigned int write_flags = wbc_to_write_flags(wbc);
 	bool compressed;
 
@@ -3543,6 +3550,9 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
 		return 1;
 	}
 
+	if (btrfs_fs_incompat(inode->root->fs_info, ZONED))
+		opf = REQ_OP_ZONE_APPEND;
+
 	/*
 	 * we don't want to touch the inode after unlocking the page,
 	 * so we update the mapping writeback index now
@@ -3603,7 +3613,7 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
 			       page->index, cur, end);
 		}
 
-		ret = submit_extent_page(REQ_OP_WRITE | write_flags, wbc,
+		ret = submit_extent_page(opf | write_flags, wbc,
 					 page, offset, iosize, pg_offset,
 					 &epd->bio,
 					 end_bio_extent_writepage,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4bc975eafbd8..b5fdc93b319f 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -51,6 +51,7 @@
 #include "delalloc-space.h"
 #include "block-group.h"
 #include "space-info.h"
+#include "zoned.h"
 
 struct btrfs_iget_args {
 	u64 ino;
@@ -2279,7 +2280,7 @@ blk_status_t btrfs_submit_data_bio(struct inode *inode, struct bio *bio,
 			goto out;
 	}
 
-	if (bio_op(bio) != REQ_OP_WRITE) {
+	if (btrfs_op(bio) != BTRFS_MAP_WRITE) {
 		ret = btrfs_bio_wq_end_io(fs_info, bio, metadata);
 		if (ret)
 			goto out;
@@ -2674,6 +2675,9 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
 	bool clear_reserved_extent = true;
 	unsigned int clear_bits;
 
+	if (ordered_extent->disk)
+		btrfs_rewrite_logical_zoned(ordered_extent);
+
 	start = ordered_extent->file_offset;
 	end = start + ordered_extent->num_bytes - 1;
 
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 7cd22cb07f26..b32cdbfd408d 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -199,6 +199,9 @@ static int __btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset
 	entry->compress_type = compress_type;
 	entry->truncated_len = (u64)-1;
 	entry->qgroup_rsv = ret;
+	entry->physical = (u64)-1;
+	entry->disk = NULL;
+	entry->partno = (u8)-1;
 	if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)
 		set_bit(type, &entry->flags);
 
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index e346b03bd66a..1d5a8dc00373 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -127,6 +127,10 @@ struct btrfs_ordered_extent {
 	struct completion completion;
 	struct btrfs_work flush_work;
 	struct list_head work_list;
+
+	u64 physical;
+	struct gendisk *disk;
+	u8 partno;
 };
 
 /*
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 44ef7b2fb46c..924ba96dc8fa 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -6500,6 +6500,15 @@ static void submit_stripe_bio(struct btrfs_bio *bbio, struct bio *bio,
 	btrfs_io_bio(bio)->device = dev;
 	bio->bi_end_io = btrfs_end_bio;
 	bio->bi_iter.bi_sector = physical >> 9;
+	/*
+	 * For zone append writing, bi_sector must point the beginning of the
+	 * zone
+	 */
+	if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
+		u64 zone_start = round_down(physical, fs_info->zone_size);
+
+		bio->bi_iter.bi_sector = zone_start >> SECTOR_SHIFT;
+	}
 	btrfs_debug_in_rcu(fs_info,
 	"btrfs_map_bio: rw %d 0x%x, sector=%llu, dev=%lu (%s id %llu), size=%u",
 		bio_op(bio), bio->bi_opf, (u64)bio->bi_iter.bi_sector,
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 88b45af60e4f..9e1056e2c2c8 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -1054,3 +1054,71 @@ void btrfs_free_redirty_list(struct btrfs_transaction *trans)
 	}
 	spin_unlock(&trans->releasing_ebs_lock);
 }
+
+void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset,
+				 struct bio *bio)
+{
+	struct btrfs_ordered_extent *ordered;
+	u64 physical = (u64)bio->bi_iter.bi_sector << SECTOR_SHIFT;
+
+	if (bio_op(bio) != REQ_OP_ZONE_APPEND)
+		return;
+
+	ordered = btrfs_lookup_ordered_extent(BTRFS_I(inode), file_offset);
+	if (WARN_ON(!ordered))
+		return;
+
+	ordered->physical = physical;
+	ordered->disk = bio->bi_disk;
+	ordered->partno = bio->bi_partno;
+
+	btrfs_put_ordered_extent(ordered);
+}
+
+void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered)
+{
+	struct extent_map_tree *em_tree;
+	struct extent_map *em;
+	struct inode *inode = ordered->inode;
+	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+	struct btrfs_ordered_sum *sum;
+	struct block_device *bdev;
+	u64 orig_logical = ordered->disk_bytenr;
+	u64 *logical = NULL;
+	int nr, stripe_len;
+
+	bdev = bdget_disk(ordered->disk, ordered->partno);
+	if (WARN_ON(!bdev))
+		return;
+
+	if (WARN_ON(__btrfs_rmap_block(fs_info, orig_logical, bdev,
+				       ordered->physical, &logical, &nr,
+				       &stripe_len)))
+		goto out;
+
+	WARN_ON(nr != 1);
+
+	if (orig_logical == *logical)
+		goto out;
+
+	ordered->disk_bytenr = *logical;
+
+	em_tree = &BTRFS_I(inode)->extent_tree;
+	write_lock(&em_tree->lock);
+	em = search_extent_mapping(em_tree, ordered->file_offset,
+				   ordered->num_bytes);
+	em->block_start = *logical;
+	free_extent_map(em);
+	write_unlock(&em_tree->lock);
+
+	list_for_each_entry(sum, &ordered->list, list) {
+		if (*logical < orig_logical)
+			sum->bytenr -= orig_logical - *logical;
+		else
+			sum->bytenr += *logical - orig_logical;
+	}
+
+out:
+	kfree(logical);
+	bdput(bdev);
+}
diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
index 32446135e882..f6263a893a07 100644
--- a/fs/btrfs/zoned.h
+++ b/fs/btrfs/zoned.h
@@ -50,6 +50,9 @@ void btrfs_calc_zone_unusable(struct btrfs_block_group *cache);
 void btrfs_redirty_list_add(struct btrfs_transaction *trans,
 			    struct extent_buffer *eb);
 void btrfs_free_redirty_list(struct btrfs_transaction *trans);
+void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset,
+				 struct bio *bio);
+void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered);
 #else /* CONFIG_BLK_DEV_ZONED */
 static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
 				     struct blk_zone *zone)
@@ -119,6 +122,12 @@ static inline void btrfs_calc_zone_unusable(struct btrfs_block_group *cache) { }
 static inline void btrfs_redirty_list_add(struct btrfs_transaction *trans,
 					  struct extent_buffer *eb) { }
 static inline void btrfs_free_redirty_list(struct btrfs_transaction *trans) { }
+static inline void btrfs_record_physical_zoned(struct inode *inode,
+					       u64 file_offset, struct bio *bio)
+{
+}
+static inline void
+btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered) { }
 #endif
 
 static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
-- 
2.27.0


  parent reply	other threads:[~2020-10-01 18:39 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-01 18:36 [PATCH v8 00/41] btrfs: zoned block device support Naohiro Aota
2020-10-01 18:36 ` [PATCH v8 01/41] block: add bio_add_zone_append_page Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 02/41] btrfs: introduce ZONED feature flag Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 03/41] btrfs: Get zone information of zoned block devices Naohiro Aota
2020-10-13 15:53     ` David Sterba
2020-10-15  7:45       ` Johannes Thumshirn
2020-10-01 18:36   ` [PATCH v8 04/41] btrfs: Check and enable ZONED mode Naohiro Aota
2020-10-13 15:56     ` David Sterba
2020-10-28 14:49       ` Johannes Thumshirn
2020-10-13 16:13     ` David Sterba
2020-10-01 18:36   ` [PATCH v8 05/41] btrfs: introduce max_zone_append_size Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 06/41] btrfs: disallow space_cache in ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 07/41] btrfs: disallow NODATACOW " Naohiro Aota
2020-10-13 15:39     ` David Sterba
2020-10-21  8:53       ` Johannes Thumshirn
2020-10-01 18:36   ` [PATCH v8 08/41] btrfs: disable fallocate " Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 09/41] btrfs: disallow mixed-bg " Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 10/41] btrfs: disallow inode_cache " Naohiro Aota
2020-10-13 15:41     ` David Sterba
2020-10-22  6:48       ` Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 11/41] btrfs: implement log-structured superblock for " Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 12/41] btrfs: implement zoned chunk allocator Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 13/41] btrfs: verify device extent is aligned to zone Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 14/41] btrfs: load zone's alloction offset Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 15/41] btrfs: emulate write pointer for conventional zones Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 16/41] btrfs: track unusable bytes for zones Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 17/41] btrfs: do sequential extent allocation in ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 18/41] btrfs: reset zones of unused block groups Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 19/41] btrfs: redirty released extent buffers in ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 20/41] btrfs: extract page adding function Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 21/41] btrfs: use bio_add_zone_append_page for zoned btrfs Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 22/41] btrfs: handle REQ_OP_ZONE_APPEND as writing Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 23/41] btrfs: split ordered extent when bio is sent Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 24/41] btrfs: extend btrfs_rmap_block for specifying a device Naohiro Aota
2020-10-01 18:36   ` Naohiro Aota [this message]
2020-10-13 16:45     ` [PATCH v8 25/41] btrfs: use ZONE_APPEND write for ZONED btrfs David Sterba
2020-10-01 18:36   ` [PATCH v8 26/41] btrfs: enable zone append writing for direct IO Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 27/41] btrfs: introduce dedicated data write path for ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 28/41] btrfs: serialize meta IOs on " Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 29/41] btrfs: wait existing extents before truncating Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 30/41] btrfs: avoid async metadata checksum on ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 31/41] btrfs: mark block groups to copy for device-replace Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 32/41] btrfs: implement cloning for ZONED device-replace Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 33/41] btrfs: implement copying " Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 34/41] btrfs: support dev-replace in ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 35/41] btrfs: enable relocation " Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 36/41] btrfs: relocate block group to repair IO failure in ZONED Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 37/41] btrfs: split alloc_log_tree() Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 38/41] btrfs: extend zoned allocator to use dedicated tree-log block group Naohiro Aota
2020-10-13 16:26     ` David Sterba
2020-10-15  7:21       ` Johannes Thumshirn
2020-10-01 18:36   ` [PATCH v8 39/41] btrfs: serialize log transaction on ZONED mode Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 40/41] btrfs: reorder log node allocation Naohiro Aota
2020-10-01 18:36   ` [PATCH v8 41/41] btrfs: enable to mount ZONED incompat flag Naohiro Aota
2020-10-02 13:39   ` [PATCH v8 01/41] block: add bio_add_zone_append_page Martin K. Petersen
2020-10-05  1:46     ` Damien Le Moal
2020-10-05 13:43     ` Christoph Hellwig
2020-10-06  1:26       ` Martin K. Petersen
2020-10-06  5:12         ` Damien Le Moal
2020-10-09 15:40 ` [PATCH v8 00/41] btrfs: zoned block device support Josef Bacik
2020-10-12  9:17   ` Naohiro Aota

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1727a2fbaa17db7c5d3447d2f547b98cb5f9bf32.1601574234.git.naohiro.aota@wdc.com \
    --to=naohiro.aota@wdc.com \
    --cc=dsterba@suse.com \
    --cc=hare@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.