summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZizhi Wo <wozizhi@huawei.com>2025-07-03 10:44:18 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-07-24 08:56:30 +0200
commit894780d6dd3ef4edc7583047dc210a60d7864c97 (patch)
tree72258f2951ae8ed448f5cb421c5e6808a4315f68
parentdc05051dd10d6284c94fb06899d34e56654c0f59 (diff)
cachefiles: Fix the incorrect return value in __cachefiles_write()
[ Upstream commit 6b89819b06d8d339da414f06ef3242f79508be5e ] In __cachefiles_write(), if the return value of the write operation > 0, it is set to 0. This makes it impossible to distinguish scenarios where a partial write has occurred, and will affect the outer calling functions: 1) cachefiles_write_complete() will call "term_func" such as netfs_write_subrequest_terminated(). When "ret" in __cachefiles_write() is used as the "transferred_or_error" of this function, it can not distinguish the amount of data written, makes the WARN meaningless. 2) cachefiles_ondemand_fd_write_iter() can only assume all writes were successful by default when "ret" is 0, and unconditionally return the full length specified by user space. Fix it by modifying "ret" to reflect the actual number of bytes written. Furthermore, returning a value greater than 0 from __cachefiles_write() does not affect other call paths, such as cachefiles_issue_write() and fscache_write(). Fixes: 047487c947e8 ("cachefiles: Implement the I/O routines") Signed-off-by: Zizhi Wo <wozizhi@huawei.com> Link: https://lore.kernel.org/20250703024418.2809353-1-wozizhi@huaweicloud.com Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--fs/cachefiles/io.c2
-rw-r--r--fs/cachefiles/ondemand.c4
2 files changed, 1 insertions, 5 deletions
diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
index 6a821a959b59..6c378b230de2 100644
--- a/fs/cachefiles/io.c
+++ b/fs/cachefiles/io.c
@@ -346,8 +346,6 @@ int __cachefiles_write(struct cachefiles_object *object,
default:
ki->was_async = false;
cachefiles_write_complete(&ki->iocb, ret);
- if (ret > 0)
- ret = 0;
break;
}
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c
index fe3de9ad57bf..00e1f2471b9e 100644
--- a/fs/cachefiles/ondemand.c
+++ b/fs/cachefiles/ondemand.c
@@ -83,10 +83,8 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
- if (!ret) {
- ret = len;
+ if (ret > 0)
kiocb->ki_pos += ret;
- }
out:
fput(file);