diff options
author | Josef Bacik <josef@redhat.com> | 2011-07-18 13:21:38 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-07-20 20:47:58 -0400 |
commit | 06222e491e663dac939f04b125c9dc52126a75c4 (patch) | |
tree | 99636fd666c8148a5bf58ea4844263d4b3a36310 /fs/fuse | |
parent | c334b1138bd44bea578eab7971c59bd9212a1093 (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.c | 21 |
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) { |