aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/gfs2/ops_file.c4
-rw-r--r--fs/ncpfs/file.c12
-rw-r--r--fs/nfs/file.c6
-rw-r--r--fs/read_write.c38
-rw-r--r--fs/smbfs/file.c11
-rw-r--r--include/linux/fs.h3
7 files changed, 42 insertions, 34 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 427a7c695896..aeff0fe5b6b9 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -581,7 +581,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
581 if (retval < 0) 581 if (retval < 0)
582 return (loff_t)retval; 582 return (loff_t)retval;
583 } 583 }
584 return remote_llseek(file, offset, origin); 584 return generic_file_llseek_unlocked(file, offset, origin);
585} 585}
586 586
587struct file_system_type cifs_fs_type = { 587struct file_system_type cifs_fs_type = {
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index e1b7d525a066..24dd59450088 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -62,11 +62,11 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
62 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, 62 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
63 &i_gh); 63 &i_gh);
64 if (!error) { 64 if (!error) {
65 error = remote_llseek(file, offset, origin); 65 error = generic_file_llseek_unlocked(file, offset, origin);
66 gfs2_glock_dq_uninit(&i_gh); 66 gfs2_glock_dq_uninit(&i_gh);
67 } 67 }
68 } else 68 } else
69 error = remote_llseek(file, offset, origin); 69 error = generic_file_llseek_unlocked(file, offset, origin);
70 70
71 return error; 71 return error;
72} 72}
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 2b145de45b39..6a7d901f1936 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/smp_lock.h>
21 22
22#include <linux/ncp_fs.h> 23#include <linux/ncp_fs.h>
23#include "ncplib_kernel.h" 24#include "ncplib_kernel.h"
@@ -281,9 +282,18 @@ static int ncp_release(struct inode *inode, struct file *file) {
281 return 0; 282 return 0;
282} 283}
283 284
285static loff_t ncp_remote_llseek(struct file *file, loff_t offset, int origin)
286{
287 loff_t ret;
288 lock_kernel();
289 ret = generic_file_llseek_unlocked(file, offset, origin);
290 unlock_kernel();
291 return ret;
292}
293
284const struct file_operations ncp_file_operations = 294const struct file_operations ncp_file_operations =
285{ 295{
286 .llseek = remote_llseek, 296 .llseek = ncp_remote_llseek,
287 .read = ncp_file_read, 297 .read = ncp_file_read,
288 .write = ncp_file_write, 298 .write = ncp_file_write,
289 .ioctl = ncp_ioctl, 299 .ioctl = ncp_ioctl,
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 3536b01164f9..a34eb78989f5 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -170,6 +170,7 @@ force_reval:
170 170
171static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) 171static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
172{ 172{
173 loff_t loff;
173 /* origin == SEEK_END => we must revalidate the cached file length */ 174 /* origin == SEEK_END => we must revalidate the cached file length */
174 if (origin == SEEK_END) { 175 if (origin == SEEK_END) {
175 struct inode *inode = filp->f_mapping->host; 176 struct inode *inode = filp->f_mapping->host;
@@ -177,7 +178,10 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
177 if (retval < 0) 178 if (retval < 0)
178 return (loff_t)retval; 179 return (loff_t)retval;
179 } 180 }
180 return remote_llseek(filp, offset, origin); 181 lock_kernel(); /* BKL needed? */
182 loff = generic_file_llseek_unlocked(filp, offset, origin);
183 unlock_kernel();
184 return loff;
181} 185}
182 186
183/* 187/*
diff --git a/fs/read_write.c b/fs/read_write.c
index f0d1240a5c69..9ba495d5a29b 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -31,12 +31,12 @@ const struct file_operations generic_ro_fops = {
31 31
32EXPORT_SYMBOL(generic_ro_fops); 32EXPORT_SYMBOL(generic_ro_fops);
33 33
34loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) 34loff_t
35generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
35{ 36{
36 loff_t retval; 37 loff_t retval;
37 struct inode *inode = file->f_mapping->host; 38 struct inode *inode = file->f_mapping->host;
38 39
39 mutex_lock(&inode->i_mutex);
40 switch (origin) { 40 switch (origin) {
41 case SEEK_END: 41 case SEEK_END:
42 offset += inode->i_size; 42 offset += inode->i_size;
@@ -46,42 +46,26 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
46 } 46 }
47 retval = -EINVAL; 47 retval = -EINVAL;
48 if (offset>=0 && offset<=inode->i_sb->s_maxbytes) { 48 if (offset>=0 && offset<=inode->i_sb->s_maxbytes) {
49 /* Special lock needed here? */
49 if (offset != file->f_pos) { 50 if (offset != file->f_pos) {
50 file->f_pos = offset; 51 file->f_pos = offset;
51 file->f_version = 0; 52 file->f_version = 0;
52 } 53 }
53 retval = offset; 54 retval = offset;
54 } 55 }
55 mutex_unlock(&inode->i_mutex);
56 return retval; 56 return retval;
57} 57}
58EXPORT_SYMBOL(generic_file_llseek_unlocked);
58 59
59EXPORT_SYMBOL(generic_file_llseek); 60loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
60
61loff_t remote_llseek(struct file *file, loff_t offset, int origin)
62{ 61{
63 loff_t retval; 62 loff_t n;
64 63 mutex_lock(&file->f_dentry->d_inode->i_mutex);
65 lock_kernel(); 64 n = generic_file_llseek_unlocked(file, offset, origin);
66 switch (origin) { 65 mutex_unlock(&file->f_dentry->d_inode->i_mutex);
67 case SEEK_END: 66 return n;
68 offset += i_size_read(file->f_path.dentry->d_inode);
69 break;
70 case SEEK_CUR:
71 offset += file->f_pos;
72 }
73 retval = -EINVAL;
74 if (offset>=0 && offset<=file->f_path.dentry->d_inode->i_sb->s_maxbytes) {
75 if (offset != file->f_pos) {
76 file->f_pos = offset;
77 file->f_version = 0;
78 }
79 retval = offset;
80 }
81 unlock_kernel();
82 return retval;
83} 67}
84EXPORT_SYMBOL(remote_llseek); 68EXPORT_SYMBOL(generic_file_llseek);
85 69
86loff_t no_llseek(struct file *file, loff_t offset, int origin) 70loff_t no_llseek(struct file *file, loff_t offset, int origin)
87{ 71{
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index efbe29af3d7a..2294783320cb 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -422,9 +422,18 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
422 return error; 422 return error;
423} 423}
424 424
425static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin)
426{
427 loff_t ret;
428 lock_kernel();
429 ret = generic_file_llseek_unlocked(file, offset, origin);
430 unlock_kernel();
431 return ret;
432}
433
425const struct file_operations smb_file_operations = 434const struct file_operations smb_file_operations =
426{ 435{
427 .llseek = remote_llseek, 436 .llseek = smb_remote_llseek,
428 .read = do_sync_read, 437 .read = do_sync_read,
429 .aio_read = smb_file_aio_read, 438 .aio_read = smb_file_aio_read,
430 .write = do_sync_write, 439 .write = do_sync_write,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f413085f748e..b158e5161bca 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1871,7 +1871,8 @@ extern void
1871file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); 1871file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
1872extern loff_t no_llseek(struct file *file, loff_t offset, int origin); 1872extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
1873extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin); 1873extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
1874extern loff_t remote_llseek(struct file *file, loff_t offset, int origin); 1874extern loff_t generic_file_llseek_unlocked(struct file *file, loff_t offset,
1875 int origin);
1875extern int generic_file_open(struct inode * inode, struct file * filp); 1876extern int generic_file_open(struct inode * inode, struct file * filp);
1876extern int nonseekable_open(struct inode * inode, struct file * filp); 1877extern int nonseekable_open(struct inode * inode, struct file * filp);
1877 1878