Commit a92adc82 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Miklos Szeredi

fuse: Prepare to handle short reads

A helper which gets called when read reports less bytes than was requested.
See patch "trust kernel i_size only" for details.
Signed-off-by: default avatarMaxim Patlasov <MPatlasov@parallels.com>
Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent 650b22b9
...@@ -671,6 +671,15 @@ static void fuse_read_update_size(struct inode *inode, loff_t size, ...@@ -671,6 +671,15 @@ static void fuse_read_update_size(struct inode *inode, loff_t size,
spin_unlock(&fc->lock); spin_unlock(&fc->lock);
} }
static void fuse_short_read(struct fuse_req *req, struct inode *inode,
u64 attr_ver)
{
size_t num_read = req->out.args[0].size;
loff_t pos = page_offset(req->pages[0]) + num_read;
fuse_read_update_size(inode, pos, attr_ver);
}
static int fuse_readpage(struct file *file, struct page *page) static int fuse_readpage(struct file *file, struct page *page)
{ {
struct fuse_io_priv io = { .async = 0, .file = file }; struct fuse_io_priv io = { .async = 0, .file = file };
...@@ -708,18 +717,18 @@ static int fuse_readpage(struct file *file, struct page *page) ...@@ -708,18 +717,18 @@ static int fuse_readpage(struct file *file, struct page *page)
req->page_descs[0].length = count; req->page_descs[0].length = count;
num_read = fuse_send_read(req, &io, pos, count, NULL); num_read = fuse_send_read(req, &io, pos, count, NULL);
err = req->out.h.error; err = req->out.h.error;
fuse_put_request(fc, req);
if (!err) { if (!err) {
/* /*
* Short read means EOF. If file size is larger, truncate it * Short read means EOF. If file size is larger, truncate it
*/ */
if (num_read < count) if (num_read < count)
fuse_read_update_size(inode, pos + num_read, attr_ver); fuse_short_read(req, inode, attr_ver);
SetPageUptodate(page); SetPageUptodate(page);
} }
fuse_put_request(fc, req);
fuse_invalidate_atime(inode); fuse_invalidate_atime(inode);
out: out:
unlock_page(page); unlock_page(page);
...@@ -742,13 +751,9 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) ...@@ -742,13 +751,9 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
/* /*
* Short read means EOF. If file size is larger, truncate it * Short read means EOF. If file size is larger, truncate it
*/ */
if (!req->out.h.error && num_read < count) { if (!req->out.h.error && num_read < count)
loff_t pos; fuse_short_read(req, inode, req->misc.read.attr_ver);
pos = page_offset(req->pages[0]) + num_read;
fuse_read_update_size(inode, pos,
req->misc.read.attr_ver);
}
fuse_invalidate_atime(inode); fuse_invalidate_atime(inode);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment