Skip to contentSkip to conversation

f2fs: revert segment allocation for direct IO

PATCH In review Jaegeuk Kim 2 participants 5 messages Nov 11, 2016 – Nov 25, 2016

Subsystems (2)
lore
Share & tools
lore

Jaegeuk Kim

author maintainer
#0 lore raw

PATCH 1/2 f2fs: revert segment allocation for direct IO

Now we don't need to be too much careful about storage alignment for dio, since its speed becomes quite fast and we'd better avoid any misalignment first.

Revert: 38aa0889b250 (f2fs: align direct_io'ed data to section)

---
 fs/f2fs/data.c    |  6 +-----
 fs/f2fs/f2fs.h    |  1 -
 fs/f2fs/segment.c | 36 +++++++++---------------------------
 3 files changed, 10 insertions(+), 33 deletions(-)
fs/f2fs/data.c +1 -5
index 47ded0c..ca53da5 100644
@@ -588,7 +588,6 @@ static int __allocate_data_block(struct dnode_of_data *dn)
 	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
 	struct f2fs_summary sum;
 	struct node_info ni;
-	int seg = CURSEG_WARM_DATA;
 	pgoff_t fofs;
 	blkcnt_t count = 1;
 
@@ -606,11 +605,8 @@ static int __allocate_data_block(struct dnode_of_data *dn)
 	get_node_info(sbi, dn->nid, &ni);
 	set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
 
-	if (dn->ofs_in_node == 0 && dn->inode_page == dn->node_page)
-		seg = CURSEG_DIRECT_IO;
-
 	allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
-								&sum, seg);
+						&sum, CURSEG_WARM_DATA);
 	set_data_blkaddr(dn);
 
 	/* update i_size */
fs/f2fs/f2fs.h +0 -1
index a6e2ede..0496e82 100644
@@ -591,7 +591,6 @@ enum {
 	CURSEG_WARM_NODE,	/* direct node blocks of normal files */
 	CURSEG_COLD_NODE,	/* indirect node blocks */
 	NO_CHECK_TYPE,
-	CURSEG_DIRECT_IO,	/* to use for the direct IO path */
 };
 
 struct flush_cmd {
fs/f2fs/segment.c +9 -27
index 7fb7dd3..4cc589a 100644
@@ -1346,25 +1346,21 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
 	stat_inc_seg_type(sbi, curseg);
 }
 
-static void __allocate_new_segments(struct f2fs_sb_info *sbi, int type)
-{
-	struct curseg_info *curseg = CURSEG_I(sbi, type);
-	unsigned int old_segno;
-
-	old_segno = curseg->segno;
-	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
-	locate_dirty_segment(sbi, old_segno);
-}
-
 void allocate_new_segments(struct f2fs_sb_info *sbi)
 {
+	struct curseg_info *curseg;
+	unsigned int old_segno;
 	int i;
 
 	if (test_opt(sbi, LFS))
 		return;
 
-	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
-		__allocate_new_segments(sbi, i);
+	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
+		curseg = CURSEG_I(sbi, i);
+		old_segno = curseg->segno;
+		SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
+		locate_dirty_segment(sbi, old_segno);
+	}
 }
 
 static const struct segment_allocation default_salloc_ops = {
@@ -1498,25 +1494,11 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 		struct f2fs_summary *sum, int type)
 {
 	struct sit_info *sit_i = SIT_I(sbi);
-	struct curseg_info *curseg;
-	bool direct_io = (type == CURSEG_DIRECT_IO);
-
-	if (direct_io) {
-		if (sbi->active_logs <= 4)
-			type = CURSEG_HOT_DATA;
-		else
-			type = CURSEG_WARM_DATA;
-	}
-	curseg = CURSEG_I(sbi, type);
+	struct curseg_info *curseg = CURSEG_I(sbi, type);
 
 	mutex_lock(&curseg->curseg_mutex);
 	mutex_lock(&sit_i->sentry_lock);
 
-	/* direct_io'ed data is aligned to the segment for better performance */
-	if (direct_io && curseg->next_blkoff &&
-				!has_not_enough_free_secs(sbi, 0, 0))
-		__allocate_new_segments(sbi, type);
-
 	*new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
 
 	/*
Signature · 9 lines
2.8.3


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
author maintainer
#1 lore raw

PATCH 2/2 f2fs: allow dio read for LFS mode

We can allow dio reads for LFS mode, while doing buffered writes for dio writes.

---
 fs/f2fs/data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/data.c +1 -1
index ca53da5..996b9ae 100644
@@ -1732,7 +1732,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
 	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
 		return 0;
-	if (test_opt(F2FS_I_SB(inode), LFS))
+	if (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS))
 		return 0;
 
 	trace_f2fs_direct_IO_enter(inode, offset, count, rw);
Signature · 9 lines
2.8.3


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
maintainer Reviewed-by on v1 2/2
#2 lore raw

Re: [f2fs-dev] [PATCH 2/2] f2fs: allow dio read for LFS mode

Quoted 12 lines · Jaegeuk Kim

We can allow dio reads for LFS mode, while doing buffered writes for dio writes.

---
 fs/f2fs/data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/data.c +0 -0
index ca53da5..996b9ae 100644

fs/f2fs/data.c static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) · line 1735

Quoted 5 lines
fs/f2fs/data.c +1 -1
@@ -1732,7 +1732,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
 	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
 		return 0;
-	if (test_opt(F2FS_I_SB(inode), LFS))
+	if (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS))

For LFS mode, we must disallow any IPU in main area including direct write, instead of both direct read and write, so this patch relieves the restriction?

IIUC, please add:

Thanks,

fs/f2fs/data.c static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) · line 1738

Quoted 4 lines
fs/f2fs/data.c +0 -0
 		return 0;
 
 	trace_f2fs_direct_IO_enter(inode, offset, count, rw);

------------------------------------------------------------------------------

author maintainer
#3 lore raw

Re: [f2fs-dev] [PATCH 2/2] f2fs: allow dio read for LFS mode

Quoted 14 lines · Chao Yu
Quoted 13 lines · Jaegeuk Kim

We can allow dio reads for LFS mode, while doing buffered writes for dio writes.

---
 fs/f2fs/data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/data.c +0 -0
index ca53da5..996b9ae 100644
@@ -1732,7 +1732,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
Quoted 7 lines

fs/f2fs/data.c static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) · line 1735

Quoted 4 lines
fs/f2fs/data.c +1 -1
 	if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
 		return 0;
-	if (test_opt(F2FS_I_SB(inode), LFS))
+	if (rw == WRITE && test_opt(F2FS_I_SB(inode), LFS))

For LFS mode, we must disallow any IPU in main area including direct write, instead of both direct read and write, so this patch relieves the restriction?

Yup.

Quoted 11 lines

IIUC, please add:

Thanks,

Quoted 4 lines
fs/f2fs/data.c +0 -0
 		return 0;
 
 	trace_f2fs_direct_IO_enter(inode, offset, count, rw);
maintainer Reviewed-by on v1 1/2
#4 lore raw
In reply to Jaegeuk Kim
Quoted 6 lines · Jaegeuk Kim

Now we don't need to be too much careful about storage alignment for dio, since its speed becomes quite fast and we'd better avoid any misalignment first.

Revert: 38aa0889b250 (f2fs: align direct_io'ed data to section)

Thanks,

Quoted 109 lines
---
 fs/f2fs/data.c    |  6 +-----
 fs/f2fs/f2fs.h    |  1 -
 fs/f2fs/segment.c | 36 +++++++++---------------------------
 3 files changed, 10 insertions(+), 33 deletions(-)
fs/f2fs/data.c +1 -5
index 47ded0c..ca53da5 100644
@@ -588,7 +588,6 @@ static int __allocate_data_block(struct dnode_of_data *dn)
 	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
 	struct f2fs_summary sum;
 	struct node_info ni;
-	int seg = CURSEG_WARM_DATA;
 	pgoff_t fofs;
 	blkcnt_t count = 1;
 
@@ -606,11 +605,8 @@ static int __allocate_data_block(struct dnode_of_data *dn)
 	get_node_info(sbi, dn->nid, &ni);
 	set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
 
-	if (dn->ofs_in_node == 0 && dn->inode_page == dn->node_page)
-		seg = CURSEG_DIRECT_IO;
-
 	allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
-								&sum, seg);
+						&sum, CURSEG_WARM_DATA);
 	set_data_blkaddr(dn);
 
 	/* update i_size */
fs/f2fs/f2fs.h +0 -1
index a6e2ede..0496e82 100644
@@ -591,7 +591,6 @@ enum {
 	CURSEG_WARM_NODE,	/* direct node blocks of normal files */
 	CURSEG_COLD_NODE,	/* indirect node blocks */
 	NO_CHECK_TYPE,
-	CURSEG_DIRECT_IO,	/* to use for the direct IO path */
 };
 
 struct flush_cmd {
fs/f2fs/segment.c +9 -27
index 7fb7dd3..4cc589a 100644
@@ -1346,25 +1346,21 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
 	stat_inc_seg_type(sbi, curseg);
 }
 
-static void __allocate_new_segments(struct f2fs_sb_info *sbi, int type)
-{
-	struct curseg_info *curseg = CURSEG_I(sbi, type);
-	unsigned int old_segno;
-
-	old_segno = curseg->segno;
-	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
-	locate_dirty_segment(sbi, old_segno);
-}
-
 void allocate_new_segments(struct f2fs_sb_info *sbi)
 {
+	struct curseg_info *curseg;
+	unsigned int old_segno;
 	int i;
 
 	if (test_opt(sbi, LFS))
 		return;
 
-	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
-		__allocate_new_segments(sbi, i);
+	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
+		curseg = CURSEG_I(sbi, i);
+		old_segno = curseg->segno;
+		SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
+		locate_dirty_segment(sbi, old_segno);
+	}
 }
 
 static const struct segment_allocation default_salloc_ops = {
@@ -1498,25 +1494,11 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 		struct f2fs_summary *sum, int type)
 {
 	struct sit_info *sit_i = SIT_I(sbi);
-	struct curseg_info *curseg;
-	bool direct_io = (type == CURSEG_DIRECT_IO);
-
-	if (direct_io) {
-		if (sbi->active_logs <= 4)
-			type = CURSEG_HOT_DATA;
-		else
-			type = CURSEG_WARM_DATA;
-	}
-	curseg = CURSEG_I(sbi, type);
+	struct curseg_info *curseg = CURSEG_I(sbi, type);
 
 	mutex_lock(&curseg->curseg_mutex);
 	mutex_lock(&sit_i->sentry_lock);
 
-	/* direct_io'ed data is aligned to the segment for better performance */
-	if (direct_io && curseg->next_blkoff &&
-				!has_not_enough_free_secs(sbi, 0, 0))
-		__allocate_new_segments(sbi, type);
-
 	*new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
 
 	/*