aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-07-18 13:21:38 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 20:47:58 -0400
commit06222e491e663dac939f04b125c9dc52126a75c4 (patch)
tree99636fd666c8148a5bf58ea4844263d4b3a36310 /fs/fuse
parentc334b1138bd44bea578eab7971c59bd9212a1093 (diff)
fs: handle SEEK_HOLE/SEEK_DATA properly in all fs's that define their own llseek
This converts everybody to handle SEEK_HOLE/SEEK_DATA properly. In some cases we just return -EINVAL, in others we do the normal generic thing, and in others we're simply making sure that the properly due-dilligence is done. For example in NFS/CIFS we need to make sure the file size is update properly for the SEEK_HOLE and SEEK_DATA case, but since it calls the generic llseek stuff itself that is all we have to do. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/file.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 82a66466a24c..73b89df20851 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1600,15 +1600,32 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
1600 struct inode *inode = file->f_path.dentry->d_inode; 1600 struct inode *inode = file->f_path.dentry->d_inode;
1601 1601
1602 mutex_lock(&inode->i_mutex); 1602 mutex_lock(&inode->i_mutex);
1603 switch (origin) { 1603 if (origin != SEEK_CUR || origin != SEEK_SET) {
1604 case SEEK_END:
1605 retval = fuse_update_attributes(inode, NULL, file, NULL); 1604 retval = fuse_update_attributes(inode, NULL, file, NULL);
1606 if (retval) 1605 if (retval)
1607 goto exit; 1606 goto exit;
1607 }
1608
1609 switch (origin) {
1610 case SEEK_END:
1608 offset += i_size_read(inode); 1611 offset += i_size_read(inode);
1609 break; 1612 break;
1610 case SEEK_CUR: 1613 case SEEK_CUR:
1611 offset += file->f_pos; 1614 offset += file->f_pos;
1615 break;
1616 case SEEK_DATA:
1617 if (offset >= i_size_read(inode)) {
1618 retval = -ENXIO;
1619 goto exit;
1620 }
1621 break;
1622 case SEEK_HOLE:
1623 if (offset >= i_size_read(inode)) {
1624 retval = -ENXIO;
1625 goto exit;
1626 }
1627 offset = i_size_read(inode);
1628 break;
1612 } 1629 }
1613 retval = -EINVAL; 1630 retval = -EINVAL;
1614 if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) { 1631 if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {