Commit a92adc824ed5feaa2d4f7029f21170f574987aee
Committed by
Miklos Szeredi
1 parent
650b22b941
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>
Showing 1 changed file with 13 additions and 8 deletions Side-by-side Diff
fs/fuse/file.c
... | ... | @@ -671,6 +671,15 @@ |
671 | 671 | spin_unlock(&fc->lock); |
672 | 672 | } |
673 | 673 | |
674 | +static 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 | + | |
674 | 683 | static int fuse_readpage(struct file *file, struct page *page) |
675 | 684 | { |
676 | 685 | struct fuse_io_priv io = { .async = 0, .file = file }; |
677 | 686 | |
678 | 687 | |
... | ... | @@ -708,18 +717,18 @@ |
708 | 717 | req->page_descs[0].length = count; |
709 | 718 | num_read = fuse_send_read(req, &io, pos, count, NULL); |
710 | 719 | err = req->out.h.error; |
711 | - fuse_put_request(fc, req); | |
712 | 720 | |
713 | 721 | if (!err) { |
714 | 722 | /* |
715 | 723 | * Short read means EOF. If file size is larger, truncate it |
716 | 724 | */ |
717 | 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 | 728 | SetPageUptodate(page); |
721 | 729 | } |
722 | 730 | |
731 | + fuse_put_request(fc, req); | |
723 | 732 | fuse_invalidate_atime(inode); |
724 | 733 | out: |
725 | 734 | unlock_page(page); |
726 | 735 | |
... | ... | @@ -742,13 +751,9 @@ |
742 | 751 | /* |
743 | 752 | * Short read means EOF. If file size is larger, truncate it |
744 | 753 | */ |
745 | - if (!req->out.h.error && num_read < count) { | |
746 | - loff_t pos; | |
754 | + if (!req->out.h.error && num_read < count) | |
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 | 757 | fuse_invalidate_atime(inode); |
753 | 758 | } |
754 | 759 |