From: Miklos Szeredi Fuse doesn't use i_mutex to protect setting i_size, and so generic_file_llseek() can be racy: it doesn't use i_size_read(). So do a fuse specific llseek method, which does use i_size_read(). Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) Index: linux/fs/fuse/file.c =================================================================== --- linux.orig/fs/fuse/file.c 2008-04-25 19:38:10.000000000 +0200 +++ linux/fs/fuse/file.c 2008-04-25 19:40:11.000000000 +0200 @@ -1425,8 +1425,33 @@ static sector_t fuse_bmap(struct address return err ? 0 : outarg.block; } +static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin) +{ + long long retval; + struct inode *inode = file->f_path.dentry->d_inode; + + mutex_lock(&inode->i_mutex); + switch (origin) { + case SEEK_END: + offset += i_size_read(inode); + break; + case SEEK_CUR: + offset += file->f_pos; + } + retval = -EINVAL; + if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) { + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_version = 0; + } + retval = offset; + } + mutex_unlock(&inode->i_mutex); + return retval; +} + static const struct file_operations fuse_file_operations = { - .llseek = generic_file_llseek, + .llseek = fuse_file_llseek, .read = do_sync_read, .aio_read = fuse_file_aio_read, .write = do_sync_write, @@ -1442,7 +1467,7 @@ static const struct file_operations fuse }; static const struct file_operations fuse_direct_io_file_operations = { - .llseek = generic_file_llseek, + .llseek = fuse_file_llseek, .read = fuse_direct_read, .write = fuse_direct_write, .open = fuse_open, -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/