mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
fuse: simplify logic in fuse_notify_store() and fuse_retrieve()
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> Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
65161470f9
commit
25307ca50b
|
|
@ -1767,10 +1767,9 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
|
||||||
struct address_space *mapping;
|
struct address_space *mapping;
|
||||||
u64 nodeid;
|
u64 nodeid;
|
||||||
int err;
|
int err;
|
||||||
pgoff_t index;
|
|
||||||
unsigned int offset;
|
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
loff_t file_size;
|
loff_t file_size;
|
||||||
|
loff_t pos;
|
||||||
loff_t end;
|
loff_t end;
|
||||||
|
|
||||||
if (size < sizeof(outarg))
|
if (size < sizeof(outarg))
|
||||||
|
|
@ -1787,7 +1786,8 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
nodeid = outarg.nodeid;
|
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);
|
down_read(&fc->killsb);
|
||||||
|
|
||||||
|
|
@ -1797,10 +1797,8 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
|
||||||
goto out_up_killsb;
|
goto out_up_killsb;
|
||||||
|
|
||||||
mapping = inode->i_mapping;
|
mapping = inode->i_mapping;
|
||||||
index = outarg.offset >> PAGE_SHIFT;
|
|
||||||
offset = outarg.offset & ~PAGE_MASK;
|
|
||||||
file_size = i_size_read(inode);
|
file_size = i_size_read(inode);
|
||||||
end = outarg.offset + num;
|
end = pos + num;
|
||||||
if (end > file_size) {
|
if (end > file_size) {
|
||||||
file_size = end;
|
file_size = end;
|
||||||
fuse_write_update_attr(inode, file_size, num);
|
fuse_write_update_attr(inode, file_size, num);
|
||||||
|
|
@ -1810,19 +1808,18 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
|
||||||
struct folio *folio;
|
struct folio *folio;
|
||||||
unsigned int folio_offset;
|
unsigned int folio_offset;
|
||||||
unsigned int nr_bytes;
|
unsigned int nr_bytes;
|
||||||
unsigned int nr_pages;
|
pgoff_t index = pos >> PAGE_SHIFT;
|
||||||
|
|
||||||
folio = filemap_grab_folio(mapping, index);
|
folio = filemap_grab_folio(mapping, index);
|
||||||
err = PTR_ERR(folio);
|
err = PTR_ERR(folio);
|
||||||
if (IS_ERR(folio))
|
if (IS_ERR(folio))
|
||||||
goto out_iput;
|
goto out_iput;
|
||||||
|
|
||||||
folio_offset = ((index - folio->index) << PAGE_SHIFT) + offset;
|
folio_offset = offset_in_folio(folio, pos);
|
||||||
nr_bytes = min(num, folio_size(folio) - folio_offset);
|
nr_bytes = min(num, folio_size(folio) - folio_offset);
|
||||||
nr_pages = (offset + nr_bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
||||||
|
|
||||||
err = fuse_copy_folio(cs, &folio, folio_offset, nr_bytes, 0);
|
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)) {
|
(nr_bytes == folio_size(folio) || file_size == end)) {
|
||||||
folio_zero_segment(folio, nr_bytes, folio_size(folio));
|
folio_zero_segment(folio, nr_bytes, folio_size(folio));
|
||||||
folio_mark_uptodate(folio);
|
folio_mark_uptodate(folio);
|
||||||
|
|
@ -1833,9 +1830,8 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
|
||||||
if (err)
|
if (err)
|
||||||
goto out_iput;
|
goto out_iput;
|
||||||
|
|
||||||
|
pos += nr_bytes;
|
||||||
num -= nr_bytes;
|
num -= nr_bytes;
|
||||||
offset = 0;
|
|
||||||
index += nr_pages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
@ -1867,7 +1863,6 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct address_space *mapping = inode->i_mapping;
|
struct address_space *mapping = inode->i_mapping;
|
||||||
pgoff_t index;
|
|
||||||
loff_t file_size;
|
loff_t file_size;
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
|
@ -1878,15 +1873,16 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
|
||||||
size_t args_size = sizeof(*ra);
|
size_t args_size = sizeof(*ra);
|
||||||
struct fuse_args_pages *ap;
|
struct fuse_args_pages *ap;
|
||||||
struct fuse_args *args;
|
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);
|
file_size = i_size_read(inode);
|
||||||
|
|
||||||
num = min(outarg->size, fc->max_write);
|
num = min(outarg->size, fc->max_write);
|
||||||
if (outarg->offset > file_size)
|
if (pos > file_size)
|
||||||
num = 0;
|
num = 0;
|
||||||
else if (num > file_size - outarg->offset)
|
else if (num > file_size - pos)
|
||||||
num = file_size - outarg->offset;
|
num = file_size - pos;
|
||||||
|
|
||||||
num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||||
num_pages = min(num_pages, fc->max_pages);
|
num_pages = min(num_pages, fc->max_pages);
|
||||||
|
|
@ -1909,31 +1905,27 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
|
||||||
args->in_pages = true;
|
args->in_pages = true;
|
||||||
args->end = fuse_retrieve_end;
|
args->end = fuse_retrieve_end;
|
||||||
|
|
||||||
index = outarg->offset >> PAGE_SHIFT;
|
|
||||||
|
|
||||||
while (num && ap->num_folios < num_pages) {
|
while (num && ap->num_folios < num_pages) {
|
||||||
struct folio *folio;
|
struct folio *folio;
|
||||||
unsigned int folio_offset;
|
unsigned int folio_offset;
|
||||||
unsigned int nr_bytes;
|
unsigned int nr_bytes;
|
||||||
unsigned int nr_pages;
|
pgoff_t index = pos >> PAGE_SHIFT;
|
||||||
|
|
||||||
folio = filemap_get_folio(mapping, index);
|
folio = filemap_get_folio(mapping, index);
|
||||||
if (IS_ERR(folio))
|
if (IS_ERR(folio))
|
||||||
break;
|
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_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->folios[ap->num_folios] = folio;
|
||||||
ap->descs[ap->num_folios].offset = folio_offset;
|
ap->descs[ap->num_folios].offset = folio_offset;
|
||||||
ap->descs[ap->num_folios].length = nr_bytes;
|
ap->descs[ap->num_folios].length = nr_bytes;
|
||||||
ap->num_folios++;
|
ap->num_folios++;
|
||||||
|
|
||||||
offset = 0;
|
pos += nr_bytes;
|
||||||
num -= nr_bytes;
|
num -= nr_bytes;
|
||||||
total_len += nr_bytes;
|
total_len += nr_bytes;
|
||||||
index += nr_pages;
|
|
||||||
}
|
}
|
||||||
ra->inarg.offset = outarg->offset;
|
ra->inarg.offset = outarg->offset;
|
||||||
ra->inarg.size = total_len;
|
ra->inarg.size = total_len;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user