VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / nfs / file.c
index df23d4d..ee2addb 100644 (file)
 
 #define NFSDBG_FACILITY                NFSDBG_FILE
 
-static long nfs_file_fcntl(int fd, unsigned int cmd,
-                       unsigned long arg, struct file *filp);
 static int nfs_file_open(struct inode *, struct file *);
 static int nfs_file_release(struct inode *, struct file *);
 static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
 static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
-static ssize_t nfs_file_read(struct kiocb *, char *, size_t, loff_t);
-static ssize_t nfs_file_write(struct kiocb *, const char *, size_t, loff_t);
+static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
+static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t);
 static int  nfs_file_flush(struct file *);
 static int  nfs_fsync(struct file *, struct dentry *dentry, int datasync);
+static int nfs_check_flags(int flags);
 
 struct file_operations nfs_file_operations = {
        .llseek         = remote_llseek,
@@ -57,7 +56,7 @@ struct file_operations nfs_file_operations = {
        .fsync          = nfs_fsync,
        .lock           = nfs_lock,
        .sendfile       = nfs_file_sendfile,
-       .fcntl          = nfs_file_fcntl,
+       .check_flags    = nfs_check_flags,
 };
 
 struct inode_operations nfs_file_inode_operations = {
@@ -71,26 +70,12 @@ struct inode_operations nfs_file_inode_operations = {
 # define IS_SWAPFILE(inode)    (0)
 #endif
 
-#define nfs_invalid_flags      (O_APPEND | O_DIRECT)
-
-/*
- * Check for special cases that NFS doesn't support, and
- * pass the rest to the generic fcntl function.
- */
-static long
-nfs_file_fcntl(int fd, unsigned int cmd,
-               unsigned long arg, struct file *filp)
+static int nfs_check_flags(int flags)
 {
-       switch (cmd) {
-       case F_SETFL:
-               if ((filp->f_flags & nfs_invalid_flags) == nfs_invalid_flags)
-                       return -EINVAL;
-               break;
-       default:
-               break;
-       }
+       if (flags & (O_APPEND | O_DIRECT))
+               return -EINVAL;
 
-       return generic_file_fcntl(fd, cmd, arg, filp);
+       return 0;
 }
 
 /*
@@ -101,10 +86,11 @@ nfs_file_open(struct inode *inode, struct file *filp)
 {
        struct nfs_server *server = NFS_SERVER(inode);
        int (*open)(struct inode *, struct file *);
-       int res = 0;
+       int res;
 
-       if ((filp->f_flags & nfs_invalid_flags) == nfs_invalid_flags)
-               return -EINVAL;
+       res = nfs_check_flags(filp->f_flags);
+       if (!res)
+               return res;
 
        lock_kernel();
        /* Do NFSv4 open() call */
@@ -148,12 +134,17 @@ nfs_file_flush(struct file *file)
 }
 
 static ssize_t
-nfs_file_read(struct kiocb *iocb, char * buf, size_t count, loff_t pos)
+nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
 {
        struct dentry * dentry = iocb->ki_filp->f_dentry;
        struct inode * inode = dentry->d_inode;
        ssize_t result;
 
+#ifdef CONFIG_NFS_DIRECTIO
+       if (iocb->ki_filp->f_flags & O_DIRECT)
+               return nfs_file_direct_read(iocb, buf, count, pos);
+#endif
+
        dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
                (unsigned long) count, (unsigned long) pos);
@@ -262,12 +253,17 @@ struct address_space_operations nfs_file_aops = {
  * Write to a file (through the page cache).
  */
 static ssize_t
-nfs_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos)
+nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
 {
        struct dentry * dentry = iocb->ki_filp->f_dentry;
        struct inode * inode = dentry->d_inode;
        ssize_t result;
 
+#ifdef CONFIG_NFS_DIRECTIO
+       if (iocb->ki_filp->f_flags & O_DIRECT)
+               return nfs_file_direct_write(iocb, buf, count, pos);
+#endif
+
        dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
                inode->i_ino, (unsigned long) count, (unsigned long) pos);