[Virtio-fs] [PATCH 5/9] fuse: do not write whole page while page straddles i_size

Liu Bo bo.liu at linux.alibaba.com
Tue Apr 16 18:03:18 UTC 2019


From: Xiaoguang Wang <xiaoguang.wang at linux.alibaba.com>

If page straddles i_size and we write the whole page, the fuse
user-space filesystem may extend file size, it will confuse users.

Before this patch:
xfs_io -t -f \
        -c "truncate 5120" \
        -c "pwrite -S 0x58 0 5120"      \
        -c "mmap -rw 0 5120"            \
        -c "mwrite -S 0x59 2048 3072" \
        -c "close"      \
        testfile
testfile's length will be 8192 bytes, with this patch, testfile's
length will be 5120 bytes.

Reviewed-by: Joseph Qi <joseph.qi at linux.alibaba.com>
Signed-off-by: Xiaoguang Wang <xiaoguang.wang at linux.alibaba.com>
---
 fs/fuse/file.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index bb45acc..c6090f5 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2293,6 +2293,8 @@ static int fuse_writepages_fill(struct page *page,
 	struct page *tmp_page;
 	bool is_writeback;
 	int err;
+	loff_t size;
+	unsigned int len;
 
 	if (!data->ff) {
 		err = -EIO;
@@ -2364,7 +2366,12 @@ static int fuse_writepages_fill(struct page *page,
 	copy_highpage(tmp_page, page);
 	req->pages[req->num_pages] = tmp_page;
 	req->page_descs[req->num_pages].offset = 0;
-	req->page_descs[req->num_pages].length = PAGE_SIZE;
+	size = i_size_read(inode);
+	if (page->index == size >> PAGE_SHIFT)
+		len = size & ~PAGE_MASK;
+	else
+		len = PAGE_SIZE;
+	req->page_descs[req->num_pages].length = len;
 
 	inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
 	inc_node_page_state(tmp_page, NR_WRITEBACK_TEMP);
-- 
1.8.3.1




More information about the Virtio-fs mailing list