From: Joanne Koong <joannelkoong@gmail.com>
To: miklos@szeredi.hu
Cc: jefflexu@linux.alibaba.com, luochunsheng@ustc.edu,
djwong@kernel.org, horst@birthelmer.de,
linux-fsdevel@vger.kernel.org
Subject: [PATCH v2 2/4] fuse: simplify logic in fuse_notify_store() and fuse_retrieve()
Date: Tue, 20 Jan 2026 14:44:47 -0800 [thread overview]
Message-ID: <20260120224449.1847176-3-joannelkoong@gmail.com> (raw)
In-Reply-To: <20260120224449.1847176-1-joannelkoong@gmail.com>
Simplify the folio parsing logic in fuse_notify_store() and
fuse_retrieve().
In particular, calculate the index by tracking pos, which allows us to
remove calculating nr_pages, and use "pos" in place of outarg's offset
field.
Suggested-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
fs/fuse/dev.c | 42 +++++++++++++++++-------------------------
1 file changed, 17 insertions(+), 25 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 7558ff337413..9cbd5b64d9c9 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1765,10 +1765,9 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
struct address_space *mapping;
u64 nodeid;
int err;
- pgoff_t index;
- unsigned int offset;
unsigned int num;
loff_t file_size;
+ loff_t pos;
loff_t end;
if (size < sizeof(outarg))
@@ -1785,7 +1784,8 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
return -EINVAL;
nodeid = outarg.nodeid;
- num = min(outarg.size, MAX_LFS_FILESIZE - outarg.offset);
+ pos = outarg.offset;
+ num = min(outarg.size, MAX_LFS_FILESIZE - pos);
down_read(&fc->killsb);
@@ -1795,10 +1795,8 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
goto out_up_killsb;
mapping = inode->i_mapping;
- index = outarg.offset >> PAGE_SHIFT;
- offset = outarg.offset & ~PAGE_MASK;
file_size = i_size_read(inode);
- end = outarg.offset + num;
+ end = pos + num;
if (end > file_size) {
file_size = end;
fuse_write_update_attr(inode, file_size, num);
@@ -1808,19 +1806,18 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
struct folio *folio;
unsigned int folio_offset;
unsigned int nr_bytes;
- unsigned int nr_pages;
+ pgoff_t index = pos >> PAGE_SHIFT;
folio = filemap_grab_folio(mapping, index);
err = PTR_ERR(folio);
if (IS_ERR(folio))
goto out_iput;
- folio_offset = ((index - folio->index) << PAGE_SHIFT) + offset;
- nr_bytes = min_t(unsigned, num, folio_size(folio) - folio_offset);
- nr_pages = (offset + nr_bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ folio_offset = offset_in_folio(folio, pos);
+ nr_bytes = min(num, folio_size(folio) - folio_offset);
err = fuse_copy_folio(cs, &folio, folio_offset, nr_bytes, 0);
- if (!folio_test_uptodate(folio) && !err && offset == 0 &&
+ if (!folio_test_uptodate(folio) && !err && folio_offset == 0 &&
(nr_bytes == folio_size(folio) || file_size == end)) {
folio_zero_segment(folio, nr_bytes, folio_size(folio));
folio_mark_uptodate(folio);
@@ -1831,9 +1828,8 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
if (err)
goto out_iput;
+ pos += nr_bytes;
num -= nr_bytes;
- offset = 0;
- index += nr_pages;
}
err = 0;
@@ -1865,7 +1861,6 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
{
int err;
struct address_space *mapping = inode->i_mapping;
- pgoff_t index;
loff_t file_size;
unsigned int num;
unsigned int offset;
@@ -1876,15 +1871,16 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
size_t args_size = sizeof(*ra);
struct fuse_args_pages *ap;
struct fuse_args *args;
+ loff_t pos = outarg->offset;
- offset = outarg->offset & ~PAGE_MASK;
+ offset = offset_in_page(pos);
file_size = i_size_read(inode);
num = min(outarg->size, fc->max_write);
- if (outarg->offset > file_size)
+ if (pos > file_size)
num = 0;
- else if (num > file_size - outarg->offset)
- num = file_size - outarg->offset;
+ else if (num > file_size - pos)
+ num = file_size - pos;
num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
num_pages = min(num_pages, fc->max_pages);
@@ -1907,31 +1903,27 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
args->in_pages = true;
args->end = fuse_retrieve_end;
- index = outarg->offset >> PAGE_SHIFT;
-
while (num && ap->num_folios < num_pages) {
struct folio *folio;
unsigned int folio_offset;
unsigned int nr_bytes;
- unsigned int nr_pages;
+ pgoff_t index = pos >> PAGE_SHIFT;
folio = filemap_get_folio(mapping, index);
if (IS_ERR(folio))
break;
- folio_offset = ((index - folio->index) << PAGE_SHIFT) + offset;
+ folio_offset = offset_in_folio(folio, pos);
nr_bytes = min(folio_size(folio) - folio_offset, num);
- nr_pages = (offset + nr_bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
ap->folios[ap->num_folios] = folio;
ap->descs[ap->num_folios].offset = folio_offset;
ap->descs[ap->num_folios].length = nr_bytes;
ap->num_folios++;
- offset = 0;
+ pos += nr_bytes;
num -= nr_bytes;
total_len += nr_bytes;
- index += nr_pages;
}
ra->inarg.offset = outarg->offset;
ra->inarg.size = total_len;
--
2.47.3
next prev parent reply other threads:[~2026-01-20 22:51 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-20 22:44 [PATCH v2 0/4] fuse: clean up offset and page count calculations Joanne Koong
2026-01-20 22:44 ` [PATCH v2 1/4] fuse: validate outarg offset and size in notify store/retrieve Joanne Koong
2026-01-21 0:03 ` Darrick J. Wong
2026-01-21 0:06 ` Darrick J. Wong
2026-01-29 19:45 ` Joanne Koong
2026-01-21 2:08 ` Jingbo Xu
2026-01-29 19:30 ` Joanne Koong
2026-01-30 2:48 ` Jingbo Xu
2026-01-20 22:44 ` Joanne Koong [this message]
2026-01-21 0:27 ` [PATCH v2 2/4] fuse: simplify logic in fuse_notify_store() and fuse_retrieve() Darrick J. Wong
2026-01-21 2:32 ` Jingbo Xu
2026-01-21 8:32 ` kernel test robot
2026-01-21 15:22 ` kernel test robot
2026-01-20 22:44 ` [PATCH v2 3/4] fuse: use DIV_ROUND_UP() for page count calculations Joanne Koong
2026-01-20 22:44 ` [PATCH v2 4/4] fuse: use offset_in_page() for page offset calculations Joanne Koong
2026-01-21 2:39 ` Jingbo Xu
2026-03-02 13:10 ` [PATCH v2 0/4] fuse: clean up offset and page count calculations Miklos Szeredi
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=20260120224449.1847176-3-joannelkoong@gmail.com \
--to=joannelkoong@gmail.com \
--cc=djwong@kernel.org \
--cc=horst@birthelmer.de \
--cc=jefflexu@linux.alibaba.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=luochunsheng@ustc.edu \
--cc=miklos@szeredi.hu \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox