All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] bcachefs: Removes NULL pointer checks for filemap_lock_folio() return values
@ 2025-06-27  1:21 Youling Tang
  2025-06-27  1:21 ` [PATCH 2/3] bcachefs: Refactor the handling logic of fallocate mode in bch2_fallocate_dispatch() Youling Tang
  2025-06-27  1:21 ` [PATCH 3/3] bcachefs: Spilt bchfs_fallocate() into two functions Youling Tang
  0 siblings, 2 replies; 3+ messages in thread
From: Youling Tang @ 2025-06-27  1:21 UTC (permalink / raw)
  To: Kent Overstreet; +Cc: linux-bcachefs, linux-kernel, youling.tang, Youling Tang

From: Youling Tang <tangyouling@kylinos.cn>

__filemap_get_folio the return value cannot be NULL, so unnecessary checks
are removed.

Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
 fs/bcachefs/fs-io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index dc5f713e209c..74841b1dc8ca 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -289,7 +289,7 @@ static int __bch2_truncate_folio(struct bch_inode_info *inode,
 	u64 end_pos;
 
 	folio = filemap_lock_folio(mapping, index);
-	if (IS_ERR_OR_NULL(folio)) {
+	if (IS_ERR(folio)) {
 		/*
 		 * XXX: we're doing two index lookups when we end up reading the
 		 * folio
-- 
2.34.1


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

* [PATCH 2/3] bcachefs: Refactor the handling logic of fallocate mode  in bch2_fallocate_dispatch()
  2025-06-27  1:21 [PATCH 1/3] bcachefs: Removes NULL pointer checks for filemap_lock_folio() return values Youling Tang
@ 2025-06-27  1:21 ` Youling Tang
  2025-06-27  1:21 ` [PATCH 3/3] bcachefs: Spilt bchfs_fallocate() into two functions Youling Tang
  1 sibling, 0 replies; 3+ messages in thread
From: Youling Tang @ 2025-06-27  1:21 UTC (permalink / raw)
  To: Kent Overstreet; +Cc: linux-bcachefs, linux-kernel, youling.tang, Youling Tang

From: Youling Tang <tangyouling@kylinos.cn>

The mode parameter of the fallocate system call is divided into exclusive
mode (FALLOC_FL_MODE_MASK) and optional flag (FALLOC_FL_KEEP_SIZE).

Use FALLOC_FL_MODE_MASK and FALLOC_FL_ALLOCATE_RANGE makes the code more
readable.

Some of the logic has been handled in vfs_fallocate:
- FALLOC_FL_PUNCH_HOLE must exist simultaneously with FALLOC_FL_KEEP_SIZE.
- FALLOC_FL_COLLAPSE_RANGE and FALLOC_FL_INSERT_RANGE cannot exist
  simultaneously with FALLOC_FL_KEEP_SIZE.

Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
 fs/bcachefs/fs-io.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 74841b1dc8ca..69d3ddd4c6a1 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -814,6 +814,12 @@ static noinline long bchfs_fallocate(struct bch_inode_info *inode, int mode,
 	return ret ?: ret2;
 }
 
+#define BCH2_FALLOC_FL_SUPPORTED					\
+		(FALLOC_FL_KEEP_SIZE |					\
+		 FALLOC_FL_ALLOCATE_RANGE | FALLOC_FL_PUNCH_HOLE |	\
+		 FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE |	\
+		 FALLOC_FL_INSERT_RANGE)
+
 long bch2_fallocate_dispatch(struct file *file, int mode,
 			     loff_t offset, loff_t len)
 {
@@ -824,6 +830,9 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
 	if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_fallocate))
 		return -EROFS;
 
+	if (mode & ~BCH2_FALLOC_FL_SUPPORTED)
+		return bch2_err_class(bch_err_throw(c, unsupported_fallocate_mode));
+
 	inode_lock(&inode->v);
 	inode_dio_wait(&inode->v);
 	bch2_pagecache_block_get(inode);
@@ -832,16 +841,24 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
 	if (ret)
 		goto err;
 
-	if (!(mode & ~(FALLOC_FL_KEEP_SIZE|FALLOC_FL_ZERO_RANGE)))
+	switch (mode & FALLOC_FL_MODE_MASK) {
+	case FALLOC_FL_ALLOCATE_RANGE:
+	case FALLOC_FL_ZERO_RANGE:
 		ret = bchfs_fallocate(inode, mode, offset, len);
-	else if (mode == (FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE))
+		break;
+	case FALLOC_FL_PUNCH_HOLE:
 		ret = bchfs_fpunch(inode, offset, len);
-	else if (mode == FALLOC_FL_INSERT_RANGE)
+		break;
+	case FALLOC_FL_INSERT_RANGE:
 		ret = bchfs_fcollapse_finsert(inode, offset, len, true);
-	else if (mode == FALLOC_FL_COLLAPSE_RANGE)
+		break;
+	case FALLOC_FL_COLLAPSE_RANGE:
 		ret = bchfs_fcollapse_finsert(inode, offset, len, false);
-	else
+		break;
+	default:
 		ret = bch_err_throw(c, unsupported_fallocate_mode);
+		break;
+	}
 err:
 	bch2_pagecache_block_put(inode);
 	inode_unlock(&inode->v);
-- 
2.34.1


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

* [PATCH 3/3] bcachefs: Spilt bchfs_fallocate() into two functions
  2025-06-27  1:21 [PATCH 1/3] bcachefs: Removes NULL pointer checks for filemap_lock_folio() return values Youling Tang
  2025-06-27  1:21 ` [PATCH 2/3] bcachefs: Refactor the handling logic of fallocate mode in bch2_fallocate_dispatch() Youling Tang
@ 2025-06-27  1:21 ` Youling Tang
  1 sibling, 0 replies; 3+ messages in thread
From: Youling Tang @ 2025-06-27  1:21 UTC (permalink / raw)
  To: Kent Overstreet; +Cc: linux-bcachefs, linux-kernel, youling.tang, Youling Tang

From: Youling Tang <tangyouling@kylinos.cn>

Separating bchfs_fallocate() into two functions to handle
FALLOC_FL_ALLOCATE_RANGE and FALLOC_FL_ZERO_RANGE respectively makes the
code more readable.

Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
---
 fs/bcachefs/fs-io.c | 111 ++++++++++++++++++++++++++++++--------------
 1 file changed, 77 insertions(+), 34 deletions(-)

diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 69d3ddd4c6a1..430b59c7b7a3 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -627,7 +627,7 @@ static noinline long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
 	return ret;
 }
 
-static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
+static noinline int bchfs_fallocate(struct bch_inode_info *inode, int mode,
 			     u64 start_sector, u64 end_sector)
 {
 	struct bch_fs *c = inode->v.i_sb->s_fs_info;
@@ -757,59 +757,100 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
 	return ret;
 }
 
-static noinline long bchfs_fallocate(struct bch_inode_info *inode, int mode,
+static int bchfs_falloc_newsize(struct file *file, int mode, loff_t offset,
+				loff_t len, loff_t *new_size)
+{
+	struct inode *inode = file_inode(file);
+
+	if ((mode & FALLOC_FL_KEEP_SIZE) || offset + len <= i_size_read(inode))
+		return 0;
+	*new_size = offset + len;
+	return inode_newsize_ok(inode, *new_size);
+}
+
+static int bchfs_falloc_setsize(struct bch_fs *c, struct bch_inode_info *inode,
+				loff_t new_size)
+{
+	int ret;
+
+	spin_lock(&inode->v.i_lock);
+	i_size_write(&inode->v, new_size);
+	spin_unlock(&inode->v.i_lock);
+
+	mutex_lock(&inode->ei_update_lock);
+	ret = bch2_write_inode_size(c, inode, new_size, 0);
+	mutex_unlock(&inode->ei_update_lock);
+
+	return ret;
+}
+
+static noinline long bchfs_falloc_allocate_range(struct file *file, int mode,
 			    loff_t offset, loff_t len)
 {
+	struct bch_inode_info *inode = file_bch_inode(file);
 	struct bch_fs *c = inode->v.i_sb->s_fs_info;
 	u64 end		= offset + len;
+	loff_t new_size = 0;
 	u64 block_start	= round_down(offset,	block_bytes(c));
 	u64 block_end	= round_up(end,		block_bytes(c));
+	int ret;
+
+	ret = bchfs_falloc_newsize(file, mode, offset, len, &new_size);
+	if (ret)
+		return ret;
+
+	ret = bchfs_fallocate(inode, mode, block_start >> 9, block_end >> 9);
+	if (ret)
+		return ret;
+
+	if (mode & FALLOC_FL_KEEP_SIZE && end > inode->v.i_size)
+		new_size = inode->v.i_size;
+
+	if (new_size)
+		ret = bchfs_falloc_setsize(c, inode, new_size);
+
+	return ret;
+}
+
+static noinline long bchfs_falloc_zero_range(struct file *file, int mode,
+			    loff_t offset, loff_t len)
+{
+	struct bch_inode_info *inode = file_bch_inode(file);
+	struct bch_fs *c = inode->v.i_sb->s_fs_info;
+	u64 end		= offset + len;
+	loff_t new_size = 0;
+	u64 block_start	= round_up(offset,	block_bytes(c));
+	u64 block_end	= round_down(end,	block_bytes(c));
 	bool truncated_last_page = false;
 	int ret, ret2 = 0;
 
-	if (!(mode & FALLOC_FL_KEEP_SIZE) && end > inode->v.i_size) {
-		ret = inode_newsize_ok(&inode->v, end);
-		if (ret)
-			return ret;
-	}
-
-	if (mode & FALLOC_FL_ZERO_RANGE) {
-		ret = bch2_truncate_folios(inode, offset, end);
-		if (unlikely(ret < 0))
-			return ret;
+	ret = bchfs_falloc_newsize(file, mode, offset, len, &new_size);
+	if (ret)
+		return ret;
 
-		truncated_last_page = ret;
+	ret = bch2_truncate_folios(inode, offset, end);
+	if (unlikely(ret < 0))
+		return ret;
 
-		truncate_pagecache_range(&inode->v, offset, end - 1);
+	truncated_last_page = ret;
 
-		block_start	= round_up(offset,	block_bytes(c));
-		block_end	= round_down(end,	block_bytes(c));
-	}
+	truncate_pagecache_range(&inode->v, offset, end - 1);
 
-	ret = __bchfs_fallocate(inode, mode, block_start >> 9, block_end >> 9);
+	ret = bchfs_fallocate(inode, mode, block_start >> 9, block_end >> 9);
 
 	/*
 	 * On -ENOSPC in ZERO_RANGE mode, we still want to do the inode update,
 	 * so that the VFS cache i_size is consistent with the btree i_size:
 	 */
-	if (ret &&
-	    !(bch2_err_matches(ret, ENOSPC) && (mode & FALLOC_FL_ZERO_RANGE)))
+	if (ret && !(bch2_err_matches(ret, ENOSPC)))
 		return ret;
 
 	if (mode & FALLOC_FL_KEEP_SIZE && end > inode->v.i_size)
-		end = inode->v.i_size;
-
-	if (end >= inode->v.i_size &&
-	    (((mode & FALLOC_FL_ZERO_RANGE) && !truncated_last_page) ||
-	     !(mode & FALLOC_FL_KEEP_SIZE))) {
-		spin_lock(&inode->v.i_lock);
-		i_size_write(&inode->v, end);
-		spin_unlock(&inode->v.i_lock);
-
-		mutex_lock(&inode->ei_update_lock);
-		ret2 = bch2_write_inode_size(c, inode, end, 0);
-		mutex_unlock(&inode->ei_update_lock);
-	}
+		new_size = inode->v.i_size;
+
+	if (new_size &&
+	    ((!truncated_last_page) || !(mode & FALLOC_FL_KEEP_SIZE)))
+		ret2 = bchfs_falloc_setsize(c, inode, new_size);
 
 	return ret ?: ret2;
 }
@@ -843,8 +884,10 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
 
 	switch (mode & FALLOC_FL_MODE_MASK) {
 	case FALLOC_FL_ALLOCATE_RANGE:
+		ret = bchfs_falloc_allocate_range(file, mode, offset, len);
+		break;
 	case FALLOC_FL_ZERO_RANGE:
-		ret = bchfs_fallocate(inode, mode, offset, len);
+		ret = bchfs_falloc_zero_range(file, mode, offset, len);
 		break;
 	case FALLOC_FL_PUNCH_HOLE:
 		ret = bchfs_fpunch(inode, offset, len);
-- 
2.34.1


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

end of thread, other threads:[~2025-06-27  1:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-27  1:21 [PATCH 1/3] bcachefs: Removes NULL pointer checks for filemap_lock_folio() return values Youling Tang
2025-06-27  1:21 ` [PATCH 2/3] bcachefs: Refactor the handling logic of fallocate mode in bch2_fallocate_dispatch() Youling Tang
2025-06-27  1:21 ` [PATCH 3/3] bcachefs: Spilt bchfs_fallocate() into two functions Youling Tang

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.