if (retval < 0)
                        return (loff_t)retval;
        }
-       return remote_llseek(file, offset, origin);
+       return generic_file_llseek_unlocked(file, offset, origin);
 }
 
 struct file_system_type cifs_fs_type = {
 
                error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
                                           &i_gh);
                if (!error) {
-                       error = remote_llseek(file, offset, origin);
+                       error = generic_file_llseek_unlocked(file, offset, origin);
                        gfs2_glock_dq_uninit(&i_gh);
                }
        } else
-               error = remote_llseek(file, offset, origin);
+               error = generic_file_llseek_unlocked(file, offset, origin);
 
        return error;
 }
 
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
        return 0;
 }
 
+static loff_t ncp_remote_llseek(struct file *file, loff_t offset, int origin)
+{
+       loff_t ret;
+       lock_kernel();
+       ret = generic_file_llseek_unlocked(file, offset, origin);
+       unlock_kernel();
+       return ret;
+}
+
 const struct file_operations ncp_file_operations =
 {
-       .llseek         = remote_llseek,
+       .llseek         = ncp_remote_llseek,
        .read           = ncp_file_read,
        .write          = ncp_file_write,
        .ioctl          = ncp_ioctl,
 
 
 static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
 {
+       loff_t loff;
        /* origin == SEEK_END => we must revalidate the cached file length */
        if (origin == SEEK_END) {
                struct inode *inode = filp->f_mapping->host;
                if (retval < 0)
                        return (loff_t)retval;
        }
-       return remote_llseek(filp, offset, origin);
+       lock_kernel();  /* BKL needed? */
+       loff = generic_file_llseek_unlocked(filp, offset, origin);
+       unlock_kernel();
+       return loff;
 }
 
 /*
 
 
 EXPORT_SYMBOL(generic_ro_fops);
 
-loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
+loff_t
+generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
 {
        loff_t retval;
        struct inode *inode = file->f_mapping->host;
 
-       mutex_lock(&inode->i_mutex);
        switch (origin) {
                case SEEK_END:
                        offset += inode->i_size;
        }
        retval = -EINVAL;
        if (offset>=0 && offset<=inode->i_sb->s_maxbytes) {
+               /* Special lock needed here? */
                if (offset != file->f_pos) {
                        file->f_pos = offset;
                        file->f_version = 0;
                }
                retval = offset;
        }
-       mutex_unlock(&inode->i_mutex);
        return retval;
 }
+EXPORT_SYMBOL(generic_file_llseek_unlocked);
 
-EXPORT_SYMBOL(generic_file_llseek);
-
-loff_t remote_llseek(struct file *file, loff_t offset, int origin)
+loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
 {
-       loff_t retval;
-
-       lock_kernel();
-       switch (origin) {
-               case SEEK_END:
-                       offset += i_size_read(file->f_path.dentry->d_inode);
-                       break;
-               case SEEK_CUR:
-                       offset += file->f_pos;
-       }
-       retval = -EINVAL;
-       if (offset>=0 && offset<=file->f_path.dentry->d_inode->i_sb->s_maxbytes) {
-               if (offset != file->f_pos) {
-                       file->f_pos = offset;
-                       file->f_version = 0;
-               }
-               retval = offset;
-       }
-       unlock_kernel();
-       return retval;
+       loff_t n;
+       mutex_lock(&file->f_dentry->d_inode->i_mutex);
+       n = generic_file_llseek_unlocked(file, offset, origin);
+       mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+       return n;
 }
-EXPORT_SYMBOL(remote_llseek);
+EXPORT_SYMBOL(generic_file_llseek);
 
 loff_t no_llseek(struct file *file, loff_t offset, int origin)
 {
 
        return error;
 }
 
+static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin)
+{
+       loff_t ret;
+       lock_kernel();
+       ret = generic_file_llseek_unlocked(file, offset, origin);
+       unlock_kernel();
+       return ret;
+}
+
 const struct file_operations smb_file_operations =
 {
-       .llseek         = remote_llseek,
+       .llseek         = smb_remote_llseek,
        .read           = do_sync_read,
        .aio_read       = smb_file_aio_read,
        .write          = do_sync_write,
 
 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
 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 loff_t generic_file_llseek_unlocked(struct file *file, loff_t offset,
+                       int origin);
 extern int generic_file_open(struct inode * inode, struct file * filp);
 extern int nonseekable_open(struct inode * inode, struct file * filp);