diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2007-11-29 01:21:59 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-29 18:24:54 +0100 |
commit | bcb4be809d2a804ff040d95db4a664113833e702 (patch) | |
tree | 11a3aad0dc7df29906e2b379d13f14ccf26c9b56 /fs/fuse/file.c | |
parent | memory hotplug x86_64: fix section mismatch in init_memory_mapping() (diff) | |
download | linux-bcb4be809d2a804ff040d95db4a664113833e702.tar.xz linux-bcb4be809d2a804ff040d95db4a664113833e702.zip |
fuse: fix reading past EOF
Currently reading a fuse file will stop at cached i_size and return
EOF, even though the file might have grown since the attributes were
last updated.
So detect if trying to read past EOF, and refresh the attributes
before continuing with the read.
Thanks to mpb for the report.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r-- | fs/fuse/file.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 535b37399009..474968fbb555 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -453,6 +453,25 @@ out: return err; } +static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + struct inode *inode = iocb->ki_filp->f_mapping->host; + + if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) { + int err; + /* + * If trying to read past EOF, make sure the i_size + * attribute is up-to-date. + */ + err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); + if (err) + return err; + } + + return generic_file_aio_read(iocb, iov, nr_segs, pos); +} + static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, struct inode *inode, loff_t pos, size_t count, int writepage) @@ -887,7 +906,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) static const struct file_operations fuse_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, - .aio_read = generic_file_aio_read, + .aio_read = fuse_file_aio_read, .write = do_sync_write, .aio_write = generic_file_aio_write, .mmap = fuse_file_mmap, |