LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] f2fs: multidevice: support direct IO
@ 2021-07-19  8:47 Chao Yu
  2021-07-19 18:28 ` Jaegeuk Kim
  0 siblings, 1 reply; 3+ messages in thread
From: Chao Yu @ 2021-07-19  8:47 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, Chao Yu

Commit 3c62be17d4f5 ("f2fs: support multiple devices") missed
to support direct IO for multiple device feature, this patch
adds to support the missing part of multidevice feature.

In addition, for multiple device image, we should be aware of
any issued direct write IO rather than just buffered write IO,
so that fsync and syncfs can issue a preflush command to the
device where direct write IO goes, to persist user data for
posix compliant.

Signed-off-by: Chao Yu <chao@kernel.org>
---
 fs/f2fs/data.c    | 52 +++++++++++++++++++++++++++++++++++++++++++++--
 fs/f2fs/f2fs.h    | 24 +++++++++++++++++++---
 fs/f2fs/segment.c | 29 +++++++++++++-------------
 fs/f2fs/super.c   |  7 +++++++
 4 files changed, 93 insertions(+), 19 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 095350ccf80d..be65dca0de40 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1451,10 +1451,16 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 	struct extent_info ei = {0,0,0};
 	block_t blkaddr;
 	unsigned int start_pgofs;
+	int bidx = 0;
+	bool multidevice_dio;
 
 	if (!maxblocks)
 		return 0;
 
+	multidevice_dio = f2fs_allow_multi_device_dio(sbi, flag);
+	if (multidevice_dio)
+		map->m_bdev = sbi->sb->s_bdev;
+
 	map->m_len = 0;
 	map->m_flags = 0;
 
@@ -1477,6 +1483,16 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 		if (flag == F2FS_GET_BLOCK_DIO)
 			f2fs_wait_on_block_writeback_range(inode,
 						map->m_pblk, map->m_len);
+
+		if (multidevice_dio) {
+			bidx = f2fs_target_device_index(sbi, map->m_pblk);
+			if (bidx) {
+				map->m_bdev = FDEV(bidx).bdev;
+				map->m_pblk -= FDEV(bidx).start_blk;
+				map->m_len = min(map->m_len,
+					FDEV(bidx).end_blk + 1 - map->m_pblk);
+			}
+		}
 		goto out;
 	}
 
@@ -1574,6 +1590,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 	if (flag == F2FS_GET_BLOCK_PRE_AIO)
 		goto skip;
 
+	if (multidevice_dio)
+		bidx = f2fs_target_device_index(sbi, blkaddr);
+
 	if (map->m_len == 0) {
 		/* preallocated unwritten block should be mapped for fiemap. */
 		if (blkaddr == NEW_ADDR)
@@ -1582,10 +1601,15 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 
 		map->m_pblk = blkaddr;
 		map->m_len = 1;
+
+		if (multidevice_dio && map->m_bdev != FDEV(bidx).bdev)
+			map->m_bdev = FDEV(bidx).bdev;
 	} else if ((map->m_pblk != NEW_ADDR &&
 			blkaddr == (map->m_pblk + ofs)) ||
 			(map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) ||
 			flag == F2FS_GET_BLOCK_PRE_DIO) {
+		if (multidevice_dio && map->m_bdev != FDEV(bidx).bdev)
+			goto sync_out;
 		ofs++;
 		map->m_len++;
 	} else {
@@ -1638,11 +1662,27 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 
 sync_out:
 
-	/* for hardware encryption, but to avoid potential issue in future */
-	if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED)
+	if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED) {
+		/*
+		 * for hardware encryption, but to avoid potential issue
+		 * in future
+		 */
 		f2fs_wait_on_block_writeback_range(inode,
 						map->m_pblk, map->m_len);
 
+		if (multidevice_dio) {
+			bidx = f2fs_target_device_index(sbi, map->m_pblk);
+			if (bidx) {
+				map->m_bdev = FDEV(bidx).bdev;
+				map->m_pblk -= FDEV(bidx).start_blk;
+				f2fs_bug_on(sbi,
+					map->m_bdev != FDEV(bidx).bdev ||
+					map->m_pblk + map->m_len >
+						FDEV(bidx).end_blk + 1);
+			}
+		}
+	}
+
 	if (flag == F2FS_GET_BLOCK_PRECACHE) {
 		if (map->m_flags & F2FS_MAP_MAPPED) {
 			unsigned int ofs = start_pgofs - map->m_lblk;
@@ -1720,6 +1760,9 @@ static int __get_data_block(struct inode *inode, sector_t iblock,
 		map_bh(bh, inode->i_sb, map.m_pblk);
 		bh->b_state = (bh->b_state & ~F2FS_MAP_FLAGS) | map.m_flags;
 		bh->b_size = blks_to_bytes(inode, map.m_len);
+
+		if (f2fs_allow_multi_device_dio(F2FS_I_SB(inode), flag))
+			bh->b_bdev = map.m_bdev;
 	}
 	return err;
 }
@@ -3511,6 +3554,7 @@ static void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
 {
 	struct f2fs_private_dio *dio;
 	bool write = (bio_op(bio) == REQ_OP_WRITE);
+	block_t blkaddr = SECTOR_TO_BLOCK(bio->bi_iter.bi_sector);
 	unsigned int blkcnt = bio_sectors(bio) >> F2FS_LOG_SECTORS_PER_BLOCK;
 
 	dio = f2fs_kzalloc(F2FS_I_SB(inode),
@@ -3527,6 +3571,10 @@ static void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
 	bio->bi_end_io = f2fs_dio_end_io;
 	bio->bi_private = dio;
 
+	if (write)
+		f2fs_update_device_state(F2FS_I_SB(inode), inode->i_ino,
+							blkaddr, blkcnt);
+
 	inc_page_counts(F2FS_I_SB(inode),
 			write ? F2FS_DIO_WRITE : F2FS_DIO_READ, dio->blkcnt);
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 7369f8087f64..f3ac3cbad2e3 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -607,6 +607,7 @@ struct extent_tree {
 				F2FS_MAP_UNWRITTEN)
 
 struct f2fs_map_blocks {
+	struct block_device *m_bdev;	/* for multi-device */
 	block_t m_pblk;
 	block_t m_lblk;
 	unsigned int m_len;
@@ -1712,12 +1713,15 @@ struct f2fs_sb_info {
 
 	/* For shrinker support */
 	struct list_head s_list;
+	struct mutex umount_mutex;
+	unsigned int shrinker_run_no;
+
+	/* For multi devices */
 	int s_ndevs;				/* number of devices */
 	struct f2fs_dev_info *devs;		/* for device list */
 	unsigned int dirty_device;		/* for checkpoint data flush */
 	spinlock_t dev_lock;			/* protect dirty_device */
-	struct mutex umount_mutex;
-	unsigned int shrinker_run_no;
+	bool aligned_blksize;			/* all devices has the same logical blksize */
 
 	/* For write statistics */
 	u64 sectors_written_start;
@@ -3527,6 +3531,8 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 			block_t old_blkaddr, block_t *new_blkaddr,
 			struct f2fs_summary *sum, int type,
 			struct f2fs_io_info *fio);
+void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
+					block_t blkaddr, unsigned int blkcnt);
 void f2fs_wait_on_page_writeback(struct page *page,
 			enum page_type type, bool ordered, bool locked);
 void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
@@ -4334,6 +4340,16 @@ static inline int allow_outplace_dio(struct inode *inode,
 				!block_unaligned_IO(inode, iocb, iter));
 }
 
+static inline bool f2fs_allow_multi_device_dio(struct f2fs_sb_info *sbi,
+								int flag)
+{
+	if (!f2fs_is_multi_device(sbi))
+		return false;
+	if (flag != F2FS_GET_BLOCK_DIO)
+		return false;
+	return sbi->aligned_blksize;
+}
+
 static inline bool f2fs_force_buffered_io(struct inode *inode,
 				struct kiocb *iocb, struct iov_iter *iter)
 {
@@ -4342,7 +4358,9 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
 
 	if (f2fs_post_read_required(inode))
 		return true;
-	if (f2fs_is_multi_device(sbi))
+
+	/* disallow direct IO if any of devices has unaligned blksize */
+	if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
 		return true;
 	/*
 	 * for blkzoned device, fallback direct IO to buffered IO, so
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 15cc89eef28d..6fcfd234108a 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3442,24 +3442,24 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 	up_read(&SM_I(sbi)->curseg_lock);
 }
 
-static void update_device_state(struct f2fs_io_info *fio)
+void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
+					block_t blkaddr, unsigned int blkcnt)
 {
-	struct f2fs_sb_info *sbi = fio->sbi;
-	unsigned int devidx;
-
 	if (!f2fs_is_multi_device(sbi))
 		return;
 
-	devidx = f2fs_target_device_index(sbi, fio->new_blkaddr);
+	for (; blkcnt > 0; blkcnt--, blkaddr++) {
+		unsigned int devidx = f2fs_target_device_index(sbi, blkaddr);
 
-	/* update device state for fsync */
-	f2fs_set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO);
+		/* update device state for fsync */
+		f2fs_set_dirty_device(sbi, ino, devidx, FLUSH_INO);
 
-	/* update device state for checkpoint */
-	if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) {
-		spin_lock(&sbi->dev_lock);
-		f2fs_set_bit(devidx, (char *)&sbi->dirty_device);
-		spin_unlock(&sbi->dev_lock);
+		/* update device state for checkpoint */
+		if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) {
+			spin_lock(&sbi->dev_lock);
+			f2fs_set_bit(devidx, (char *)&sbi->dirty_device);
+			spin_unlock(&sbi->dev_lock);
+		}
 	}
 }
 
@@ -3486,7 +3486,7 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
 		goto reallocate;
 	}
 
-	update_device_state(fio);
+	f2fs_update_device_state(fio->sbi, fio->ino, fio->new_blkaddr, 1);
 
 	if (keep_order)
 		up_read(&fio->sbi->io_order_lock);
@@ -3575,7 +3575,8 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
 	else
 		err = f2fs_submit_page_bio(fio);
 	if (!err) {
-		update_device_state(fio);
+		f2fs_update_device_state(fio->sbi, fio->ino,
+						fio->new_blkaddr, 1);
 		f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE);
 	}
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 72eb9d70969f..dced7778d530 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -3646,6 +3646,7 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
 {
 	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
 	unsigned int max_devices = MAX_DEVICES;
+	unsigned int logical_blksize;
 	int i;
 
 	/* Initialize single device information */
@@ -3666,6 +3667,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
 	if (!sbi->devs)
 		return -ENOMEM;
 
+	logical_blksize = bdev_logical_block_size(sbi->sb->s_bdev);
+	sbi->aligned_blksize = true;
+
 	for (i = 0; i < max_devices; i++) {
 
 		if (i > 0 && !RDEV(i).path[0])
@@ -3702,6 +3706,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
 		/* to release errored devices */
 		sbi->s_ndevs = i + 1;
 
+		if (logical_blksize != bdev_logical_block_size(FDEV(i).bdev))
+			sbi->aligned_blksize = false;
+
 #ifdef CONFIG_BLK_DEV_ZONED
 		if (bdev_zoned_model(FDEV(i).bdev) == BLK_ZONED_HM &&
 				!f2fs_sb_has_blkzoned(sbi)) {
-- 
2.22.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] f2fs: multidevice: support direct IO
  2021-07-19  8:47 [PATCH] f2fs: multidevice: support direct IO Chao Yu
@ 2021-07-19 18:28 ` Jaegeuk Kim
  2021-07-20  1:25   ` Chao Yu
  0 siblings, 1 reply; 3+ messages in thread
From: Jaegeuk Kim @ 2021-07-19 18:28 UTC (permalink / raw)
  To: Chao Yu; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu

On 07/19, Chao Yu wrote:
> Commit 3c62be17d4f5 ("f2fs: support multiple devices") missed
> to support direct IO for multiple device feature, this patch
> adds to support the missing part of multidevice feature.
> 
> In addition, for multiple device image, we should be aware of
> any issued direct write IO rather than just buffered write IO,
> so that fsync and syncfs can issue a preflush command to the
> device where direct write IO goes, to persist user data for
> posix compliant.

Is this aligned to Eric's iomap work?

> 
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
>  fs/f2fs/data.c    | 52 +++++++++++++++++++++++++++++++++++++++++++++--
>  fs/f2fs/f2fs.h    | 24 +++++++++++++++++++---
>  fs/f2fs/segment.c | 29 +++++++++++++-------------
>  fs/f2fs/super.c   |  7 +++++++
>  4 files changed, 93 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 095350ccf80d..be65dca0de40 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -1451,10 +1451,16 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>  	struct extent_info ei = {0,0,0};
>  	block_t blkaddr;
>  	unsigned int start_pgofs;
> +	int bidx = 0;
> +	bool multidevice_dio;
>  
>  	if (!maxblocks)
>  		return 0;
>  
> +	multidevice_dio = f2fs_allow_multi_device_dio(sbi, flag);
> +	if (multidevice_dio)
> +		map->m_bdev = sbi->sb->s_bdev;
> +
>  	map->m_len = 0;
>  	map->m_flags = 0;
>  
> @@ -1477,6 +1483,16 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>  		if (flag == F2FS_GET_BLOCK_DIO)
>  			f2fs_wait_on_block_writeback_range(inode,
>  						map->m_pblk, map->m_len);
> +
> +		if (multidevice_dio) {
> +			bidx = f2fs_target_device_index(sbi, map->m_pblk);
> +			if (bidx) {
> +				map->m_bdev = FDEV(bidx).bdev;
> +				map->m_pblk -= FDEV(bidx).start_blk;
> +				map->m_len = min(map->m_len,
> +					FDEV(bidx).end_blk + 1 - map->m_pblk);
> +			}
> +		}
>  		goto out;
>  	}
>  
> @@ -1574,6 +1590,9 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>  	if (flag == F2FS_GET_BLOCK_PRE_AIO)
>  		goto skip;
>  
> +	if (multidevice_dio)
> +		bidx = f2fs_target_device_index(sbi, blkaddr);
> +
>  	if (map->m_len == 0) {
>  		/* preallocated unwritten block should be mapped for fiemap. */
>  		if (blkaddr == NEW_ADDR)
> @@ -1582,10 +1601,15 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>  
>  		map->m_pblk = blkaddr;
>  		map->m_len = 1;
> +
> +		if (multidevice_dio && map->m_bdev != FDEV(bidx).bdev)
> +			map->m_bdev = FDEV(bidx).bdev;
>  	} else if ((map->m_pblk != NEW_ADDR &&
>  			blkaddr == (map->m_pblk + ofs)) ||
>  			(map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) ||
>  			flag == F2FS_GET_BLOCK_PRE_DIO) {
> +		if (multidevice_dio && map->m_bdev != FDEV(bidx).bdev)
> +			goto sync_out;
>  		ofs++;
>  		map->m_len++;
>  	} else {
> @@ -1638,11 +1662,27 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>  
>  sync_out:
>  
> -	/* for hardware encryption, but to avoid potential issue in future */
> -	if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED)
> +	if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED) {
> +		/*
> +		 * for hardware encryption, but to avoid potential issue
> +		 * in future
> +		 */
>  		f2fs_wait_on_block_writeback_range(inode,
>  						map->m_pblk, map->m_len);
>  
> +		if (multidevice_dio) {
> +			bidx = f2fs_target_device_index(sbi, map->m_pblk);
> +			if (bidx) {
> +				map->m_bdev = FDEV(bidx).bdev;
> +				map->m_pblk -= FDEV(bidx).start_blk;
> +				f2fs_bug_on(sbi,
> +					map->m_bdev != FDEV(bidx).bdev ||
> +					map->m_pblk + map->m_len >
> +						FDEV(bidx).end_blk + 1);
> +			}
> +		}
> +	}
> +
>  	if (flag == F2FS_GET_BLOCK_PRECACHE) {
>  		if (map->m_flags & F2FS_MAP_MAPPED) {
>  			unsigned int ofs = start_pgofs - map->m_lblk;
> @@ -1720,6 +1760,9 @@ static int __get_data_block(struct inode *inode, sector_t iblock,
>  		map_bh(bh, inode->i_sb, map.m_pblk);
>  		bh->b_state = (bh->b_state & ~F2FS_MAP_FLAGS) | map.m_flags;
>  		bh->b_size = blks_to_bytes(inode, map.m_len);
> +
> +		if (f2fs_allow_multi_device_dio(F2FS_I_SB(inode), flag))
> +			bh->b_bdev = map.m_bdev;
>  	}
>  	return err;
>  }
> @@ -3511,6 +3554,7 @@ static void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
>  {
>  	struct f2fs_private_dio *dio;
>  	bool write = (bio_op(bio) == REQ_OP_WRITE);
> +	block_t blkaddr = SECTOR_TO_BLOCK(bio->bi_iter.bi_sector);
>  	unsigned int blkcnt = bio_sectors(bio) >> F2FS_LOG_SECTORS_PER_BLOCK;
>  
>  	dio = f2fs_kzalloc(F2FS_I_SB(inode),
> @@ -3527,6 +3571,10 @@ static void f2fs_dio_submit_bio(struct bio *bio, struct inode *inode,
>  	bio->bi_end_io = f2fs_dio_end_io;
>  	bio->bi_private = dio;
>  
> +	if (write)
> +		f2fs_update_device_state(F2FS_I_SB(inode), inode->i_ino,
> +							blkaddr, blkcnt);
> +
>  	inc_page_counts(F2FS_I_SB(inode),
>  			write ? F2FS_DIO_WRITE : F2FS_DIO_READ, dio->blkcnt);
>  
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 7369f8087f64..f3ac3cbad2e3 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -607,6 +607,7 @@ struct extent_tree {
>  				F2FS_MAP_UNWRITTEN)
>  
>  struct f2fs_map_blocks {
> +	struct block_device *m_bdev;	/* for multi-device */
>  	block_t m_pblk;
>  	block_t m_lblk;
>  	unsigned int m_len;
> @@ -1712,12 +1713,15 @@ struct f2fs_sb_info {
>  
>  	/* For shrinker support */
>  	struct list_head s_list;
> +	struct mutex umount_mutex;
> +	unsigned int shrinker_run_no;
> +
> +	/* For multi devices */
>  	int s_ndevs;				/* number of devices */
>  	struct f2fs_dev_info *devs;		/* for device list */
>  	unsigned int dirty_device;		/* for checkpoint data flush */
>  	spinlock_t dev_lock;			/* protect dirty_device */
> -	struct mutex umount_mutex;
> -	unsigned int shrinker_run_no;
> +	bool aligned_blksize;			/* all devices has the same logical blksize */
>  
>  	/* For write statistics */
>  	u64 sectors_written_start;
> @@ -3527,6 +3531,8 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
>  			block_t old_blkaddr, block_t *new_blkaddr,
>  			struct f2fs_summary *sum, int type,
>  			struct f2fs_io_info *fio);
> +void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
> +					block_t blkaddr, unsigned int blkcnt);
>  void f2fs_wait_on_page_writeback(struct page *page,
>  			enum page_type type, bool ordered, bool locked);
>  void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
> @@ -4334,6 +4340,16 @@ static inline int allow_outplace_dio(struct inode *inode,
>  				!block_unaligned_IO(inode, iocb, iter));
>  }
>  
> +static inline bool f2fs_allow_multi_device_dio(struct f2fs_sb_info *sbi,
> +								int flag)
> +{
> +	if (!f2fs_is_multi_device(sbi))
> +		return false;
> +	if (flag != F2FS_GET_BLOCK_DIO)
> +		return false;
> +	return sbi->aligned_blksize;
> +}
> +
>  static inline bool f2fs_force_buffered_io(struct inode *inode,
>  				struct kiocb *iocb, struct iov_iter *iter)
>  {
> @@ -4342,7 +4358,9 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
>  
>  	if (f2fs_post_read_required(inode))
>  		return true;
> -	if (f2fs_is_multi_device(sbi))
> +
> +	/* disallow direct IO if any of devices has unaligned blksize */
> +	if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
>  		return true;
>  	/*
>  	 * for blkzoned device, fallback direct IO to buffered IO, so
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 15cc89eef28d..6fcfd234108a 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -3442,24 +3442,24 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
>  	up_read(&SM_I(sbi)->curseg_lock);
>  }
>  
> -static void update_device_state(struct f2fs_io_info *fio)
> +void f2fs_update_device_state(struct f2fs_sb_info *sbi, nid_t ino,
> +					block_t blkaddr, unsigned int blkcnt)
>  {
> -	struct f2fs_sb_info *sbi = fio->sbi;
> -	unsigned int devidx;
> -
>  	if (!f2fs_is_multi_device(sbi))
>  		return;
>  
> -	devidx = f2fs_target_device_index(sbi, fio->new_blkaddr);
> +	for (; blkcnt > 0; blkcnt--, blkaddr++) {
> +		unsigned int devidx = f2fs_target_device_index(sbi, blkaddr);
>  
> -	/* update device state for fsync */
> -	f2fs_set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO);
> +		/* update device state for fsync */
> +		f2fs_set_dirty_device(sbi, ino, devidx, FLUSH_INO);
>  
> -	/* update device state for checkpoint */
> -	if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) {
> -		spin_lock(&sbi->dev_lock);
> -		f2fs_set_bit(devidx, (char *)&sbi->dirty_device);
> -		spin_unlock(&sbi->dev_lock);
> +		/* update device state for checkpoint */
> +		if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) {
> +			spin_lock(&sbi->dev_lock);
> +			f2fs_set_bit(devidx, (char *)&sbi->dirty_device);
> +			spin_unlock(&sbi->dev_lock);
> +		}
>  	}
>  }
>  
> @@ -3486,7 +3486,7 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
>  		goto reallocate;
>  	}
>  
> -	update_device_state(fio);
> +	f2fs_update_device_state(fio->sbi, fio->ino, fio->new_blkaddr, 1);
>  
>  	if (keep_order)
>  		up_read(&fio->sbi->io_order_lock);
> @@ -3575,7 +3575,8 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
>  	else
>  		err = f2fs_submit_page_bio(fio);
>  	if (!err) {
> -		update_device_state(fio);
> +		f2fs_update_device_state(fio->sbi, fio->ino,
> +						fio->new_blkaddr, 1);
>  		f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE);
>  	}
>  
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 72eb9d70969f..dced7778d530 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -3646,6 +3646,7 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>  {
>  	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
>  	unsigned int max_devices = MAX_DEVICES;
> +	unsigned int logical_blksize;
>  	int i;
>  
>  	/* Initialize single device information */
> @@ -3666,6 +3667,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>  	if (!sbi->devs)
>  		return -ENOMEM;
>  
> +	logical_blksize = bdev_logical_block_size(sbi->sb->s_bdev);
> +	sbi->aligned_blksize = true;
> +
>  	for (i = 0; i < max_devices; i++) {
>  
>  		if (i > 0 && !RDEV(i).path[0])
> @@ -3702,6 +3706,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
>  		/* to release errored devices */
>  		sbi->s_ndevs = i + 1;
>  
> +		if (logical_blksize != bdev_logical_block_size(FDEV(i).bdev))
> +			sbi->aligned_blksize = false;
> +
>  #ifdef CONFIG_BLK_DEV_ZONED
>  		if (bdev_zoned_model(FDEV(i).bdev) == BLK_ZONED_HM &&
>  				!f2fs_sb_has_blkzoned(sbi)) {
> -- 
> 2.22.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] f2fs: multidevice: support direct IO
  2021-07-19 18:28 ` Jaegeuk Kim
@ 2021-07-20  1:25   ` Chao Yu
  0 siblings, 0 replies; 3+ messages in thread
From: Chao Yu @ 2021-07-20  1:25 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu

On 2021/7/20 2:28, Jaegeuk Kim wrote:
> On 07/19, Chao Yu wrote:
>> Commit 3c62be17d4f5 ("f2fs: support multiple devices") missed
>> to support direct IO for multiple device feature, this patch
>> adds to support the missing part of multidevice feature.
>>
>> In addition, for multiple device image, we should be aware of
>> any issued direct write IO rather than just buffered write IO,
>> so that fsync and syncfs can issue a preflush command to the
>> device where direct write IO goes, to persist user data for
>> posix compliant.
> 
> Is this aligned to Eric's iomap work?

Will rebase to it soon, when would you plan to queue that iomap serial?

Thanks,

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-07-20  1:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-19  8:47 [PATCH] f2fs: multidevice: support direct IO Chao Yu
2021-07-19 18:28 ` Jaegeuk Kim
2021-07-20  1:25   ` Chao Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).