From: Youling Tang <youling.tang@linux.dev>
To: Kent Overstreet <kent.overstreet@linux.dev>
Cc: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org,
youling.tang@linux.dev, Youling Tang <tangyouling@kylinos.cn>
Subject: [PATCH 3/3] bcachefs: Spilt bchfs_fallocate() into two functions
Date: Fri, 27 Jun 2025 09:21:04 +0800 [thread overview]
Message-ID: <20250627012104.222703-3-youling.tang@linux.dev> (raw)
In-Reply-To: <20250627012104.222703-1-youling.tang@linux.dev>
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
prev parent reply other threads:[~2025-06-27 1:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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=20250627012104.222703-3-youling.tang@linux.dev \
--to=youling.tang@linux.dev \
--cc=kent.overstreet@linux.dev \
--cc=linux-bcachefs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tangyouling@kylinos.cn \
/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.