summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/ncpfs/file.c2
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/read_write.c25
-rw-r--r--fs/smbfs/file.c2
-rw-r--r--include/linux/fs.h1
-rw-r--r--kernel/ksyms.c1
6 files changed, 30 insertions, 3 deletions
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 1f70ec451ce7..fbd2c3137dd4 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -281,7 +281,7 @@ static int ncp_release(struct inode *inode, struct file *file) {
struct file_operations ncp_file_operations =
{
- llseek: generic_file_llseek,
+ llseek: remote_llseek,
read: ncp_file_read,
write: ncp_file_write,
ioctl: ncp_ioctl,
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 1d5e7dbde28a..d25cb4968931 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -41,7 +41,7 @@ static int nfs_file_flush(struct file *);
static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
struct file_operations nfs_file_operations = {
- llseek: generic_file_llseek,
+ llseek: remote_llseek,
read: nfs_file_read,
write: nfs_file_write,
mmap: nfs_file_mmap,
diff --git a/fs/read_write.c b/fs/read_write.c
index 31cee2a6aa4e..ce5230669579 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -51,6 +51,31 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
return retval;
}
+loff_t remote_llseek(struct file *file, loff_t offset, int origin)
+{
+ long long retval;
+
+ lock_kernel();
+ switch (origin) {
+ case 2:
+ offset += file->f_dentry->d_inode->i_size;
+ break;
+ case 1:
+ offset += file->f_pos;
+ }
+ retval = -EINVAL;
+ if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_reada = 0;
+ file->f_version = ++event;
+ }
+ retval = offset;
+ }
+ unlock_kernel();
+ return retval;
+}
+
loff_t no_llseek(struct file *file, loff_t offset, int origin)
{
return -ESPIPE;
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index b3feaa56924a..39badd71692f 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -381,7 +381,7 @@ smb_file_permission(struct inode *inode, int mask)
struct file_operations smb_file_operations =
{
- llseek: generic_file_llseek,
+ llseek: remote_llseek,
read: smb_file_read,
write: smb_file_write,
ioctl: smb_ioctl,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 461566f52c16..f4699a15157d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1461,6 +1461,7 @@ extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *)
extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
+extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
extern int generic_file_open(struct inode * inode, struct file * filp);
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index c271a8e6f6fc..73db2a0b2678 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -251,6 +251,7 @@ EXPORT_SYMBOL(vfs_rename);
EXPORT_SYMBOL(vfs_statfs);
EXPORT_SYMBOL(generic_read_dir);
EXPORT_SYMBOL(generic_file_llseek);
+EXPORT_SYMBOL(remote_llseek);
EXPORT_SYMBOL(no_llseek);
EXPORT_SYMBOL(__pollwait);
EXPORT_SYMBOL(poll_freewait);