Commit e067dc3c authored by Daeho Jeong's avatar Daeho Jeong Committed by Jaegeuk Kim
Browse files

f2fs: maintain six open zones for zoned devices



To keep six open zone constraints, make them not to be open over six
open zones.

Signed-off-by: default avatarDaeho Jeong <daehojeong@google.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 08c3eab5
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -383,6 +383,17 @@ static void f2fs_write_end_io(struct bio *bio)
	bio_put(bio);
}

#ifdef CONFIG_BLK_DEV_ZONED
static void f2fs_zone_write_end_io(struct bio *bio)
{
	struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private;

	bio->bi_private = io->bi_private;
	complete(&io->zone_wait);
	f2fs_write_end_io(bio);
}
#endif

struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
		block_t blk_addr, sector_t *sector)
{
@@ -639,6 +650,11 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi)
			INIT_LIST_HEAD(&sbi->write_io[i][j].io_list);
			INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list);
			init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock);
#ifdef CONFIG_BLK_DEV_ZONED
			init_completion(&sbi->write_io[i][j].zone_wait);
			sbi->write_io[i][j].zone_pending_bio = NULL;
			sbi->write_io[i][j].bi_private = NULL;
#endif
		}
	}

@@ -965,6 +981,26 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
	return 0;
}

#ifdef CONFIG_BLK_DEV_ZONED
static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr)
{
	int devi = 0;

	if (f2fs_is_multi_device(sbi)) {
		devi = f2fs_target_device_index(sbi, blkaddr);
		if (blkaddr < FDEV(devi).start_blk ||
		    blkaddr > FDEV(devi).end_blk) {
			f2fs_err(sbi, "Invalid block %x", blkaddr);
			return false;
		}
		blkaddr -= FDEV(devi).start_blk;
	}
	return bdev_zoned_model(FDEV(devi).bdev) == BLK_ZONED_HM &&
		f2fs_blkz_is_seq(sbi, devi, blkaddr) &&
		(blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1);
}
#endif

void f2fs_submit_page_write(struct f2fs_io_info *fio)
{
	struct f2fs_sb_info *sbi = fio->sbi;
@@ -975,6 +1011,16 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
	f2fs_bug_on(sbi, is_read_io(fio->op));

	f2fs_down_write(&io->io_rwsem);

#ifdef CONFIG_BLK_DEV_ZONED
	if (f2fs_sb_has_blkzoned(sbi) && btype < META && io->zone_pending_bio) {
		wait_for_completion_io(&io->zone_wait);
		bio_put(io->zone_pending_bio);
		io->zone_pending_bio = NULL;
		io->bi_private = NULL;
	}
#endif

next:
	if (fio->in_list) {
		spin_lock(&io->io_lock);
@@ -1038,6 +1084,18 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
	if (fio->in_list)
		goto next;
out:
#ifdef CONFIG_BLK_DEV_ZONED
	if (f2fs_sb_has_blkzoned(sbi) && btype < META &&
			is_end_zone_blkaddr(sbi, fio->new_blkaddr)) {
		bio_get(io->bio);
		reinit_completion(&io->zone_wait);
		io->bi_private = io->bio->bi_private;
		io->bio->bi_private = io;
		io->bio->bi_end_io = f2fs_zone_write_end_io;
		io->zone_pending_bio = io->bio;
		__submit_merged_bio(io);
	}
#endif
	if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) ||
				!f2fs_is_checkpoint_ready(sbi))
		__submit_merged_bio(io);
+5 −0
Original line number Diff line number Diff line
@@ -1218,6 +1218,11 @@ struct f2fs_bio_info {
	struct bio *bio;		/* bios to merge */
	sector_t last_block_in_bio;	/* last block number */
	struct f2fs_io_info fio;	/* store buffered io info. */
#ifdef CONFIG_BLK_DEV_ZONED
	struct completion zone_wait;	/* condition value for the previous open zone to close */
	struct bio *zone_pending_bio;	/* pending bio for the previous zone */
	void *bi_private;		/* previous bi_private for pending bio */
#endif
	struct f2fs_rwsem io_rwsem;	/* blocking op for bio */
	spinlock_t io_lock;		/* serialize DATA/NODE IOs */
	struct list_head io_list;	/* track fios */