aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2013-10-10 09:10:16 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2014-04-02 09:38:47 -0400
commita92adc824ed5feaa2d4f7029f21170f574987aee (patch)
treec9eff424e5bcdf453915d7c6aed709d0d0fb24eb /fs/fuse
parent650b22b941fa03590c4a3671e79ec2c96ea59e9a (diff)
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: Maxim Patlasov <MPatlasov@parallels.com> Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/file.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 2489aca4d1a6..592d7b48e421 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -671,6 +671,15 @@ static void fuse_read_update_size(struct inode *inode, loff_t size,
671 spin_unlock(&fc->lock); 671 spin_unlock(&fc->lock);
672} 672}
673 673
674static void fuse_short_read(struct fuse_req *req, struct inode *inode,
675 u64 attr_ver)
676{
677 size_t num_read = req->out.args[0].size;
678
679 loff_t pos = page_offset(req->pages[0]) + num_read;
680 fuse_read_update_size(inode, pos, attr_ver);
681}
682
674static int fuse_readpage(struct file *file, struct page *page) 683static int fuse_readpage(struct file *file, struct page *page)
675{ 684{
676 struct fuse_io_priv io = { .async = 0, .file = file }; 685 struct fuse_io_priv io = { .async = 0, .file = file };
@@ -708,18 +717,18 @@ static int fuse_readpage(struct file *file, struct page *page)
708 req->page_descs[0].length = count; 717 req->page_descs[0].length = count;
709 num_read = fuse_send_read(req, &io, pos, count, NULL); 718 num_read = fuse_send_read(req, &io, pos, count, NULL);
710 err = req->out.h.error; 719 err = req->out.h.error;
711 fuse_put_request(fc, req);
712 720
713 if (!err) { 721 if (!err) {
714 /* 722 /*
715 * Short read means EOF. If file size is larger, truncate it 723 * Short read means EOF. If file size is larger, truncate it
716 */ 724 */
717 if (num_read < count) 725 if (num_read < count)
718 fuse_read_update_size(inode, pos + num_read, attr_ver); 726 fuse_short_read(req, inode, attr_ver);
719 727
720 SetPageUptodate(page); 728 SetPageUptodate(page);
721 } 729 }
722 730
731 fuse_put_request(fc, req);
723 fuse_invalidate_atime(inode); 732 fuse_invalidate_atime(inode);
724 out: 733 out:
725 unlock_page(page); 734 unlock_page(page);
@@ -742,13 +751,9 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
742 /* 751 /*
743 * Short read means EOF. If file size is larger, truncate it 752 * Short read means EOF. If file size is larger, truncate it
744 */ 753 */
745 if (!req->out.h.error && num_read < count) { 754 if (!req->out.h.error && num_read < count)
746 loff_t pos; 755 fuse_short_read(req, inode, req->misc.read.attr_ver);
747 756
748 pos = page_offset(req->pages[0]) + num_read;
749 fuse_read_update_size(inode, pos,
750 req->misc.read.attr_ver);
751 }
752 fuse_invalidate_atime(inode); 757 fuse_invalidate_atime(inode);
753 } 758 }
754 759