aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2012-07-16 16:39:15 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-07-17 13:33:50 -0400
commitce4ef7c0a8a0594d7b9d088d73866a4389402a7e (patch)
tree2898effa24c9b74d27b17dd8219064524537af1e /fs/nfs/file.c
parent466bfe7f4a5bee4cdd73d3f6bd290173a8c75a40 (diff)
NFS: Split out NFS v4 file operations
This patch moves the NFS v4 file functions into a new file that is only compiled when CONFIG_NFS_V4 is enabled. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c151
1 files changed, 16 insertions, 135 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 76239178e959..70d124a61b98 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -35,7 +35,6 @@
35#include "internal.h" 35#include "internal.h"
36#include "iostat.h" 36#include "iostat.h"
37#include "fscache.h" 37#include "fscache.h"
38#include "pnfs.h"
39 38
40#define NFSDBG_FACILITY NFSDBG_FILE 39#define NFSDBG_FACILITY NFSDBG_FILE
41 40
@@ -46,7 +45,7 @@ static const struct vm_operations_struct nfs_file_vm_ops;
46# define IS_SWAPFILE(inode) (0) 45# define IS_SWAPFILE(inode) (0)
47#endif 46#endif
48 47
49static int nfs_check_flags(int flags) 48int nfs_check_flags(int flags)
50{ 49{
51 if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT)) 50 if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT))
52 return -EINVAL; 51 return -EINVAL;
@@ -75,7 +74,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
75 return res; 74 return res;
76} 75}
77 76
78static int 77int
79nfs_file_release(struct inode *inode, struct file *filp) 78nfs_file_release(struct inode *inode, struct file *filp)
80{ 79{
81 dprintk("NFS: release(%s/%s)\n", 80 dprintk("NFS: release(%s/%s)\n",
@@ -117,7 +116,7 @@ force_reval:
117 return __nfs_revalidate_inode(server, inode); 116 return __nfs_revalidate_inode(server, inode);
118} 117}
119 118
120static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) 119loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
121{ 120{
122 dprintk("NFS: llseek file(%s/%s, %lld, %d)\n", 121 dprintk("NFS: llseek file(%s/%s, %lld, %d)\n",
123 filp->f_path.dentry->d_parent->d_name.name, 122 filp->f_path.dentry->d_parent->d_name.name,
@@ -142,7 +141,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
142/* 141/*
143 * Flush all dirty pages, and check for write errors. 142 * Flush all dirty pages, and check for write errors.
144 */ 143 */
145static int 144int
146nfs_file_flush(struct file *file, fl_owner_t id) 145nfs_file_flush(struct file *file, fl_owner_t id)
147{ 146{
148 struct dentry *dentry = file->f_path.dentry; 147 struct dentry *dentry = file->f_path.dentry;
@@ -167,7 +166,7 @@ nfs_file_flush(struct file *file, fl_owner_t id)
167 return vfs_fsync(file, 0); 166 return vfs_fsync(file, 0);
168} 167}
169 168
170static ssize_t 169ssize_t
171nfs_file_read(struct kiocb *iocb, const struct iovec *iov, 170nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
172 unsigned long nr_segs, loff_t pos) 171 unsigned long nr_segs, loff_t pos)
173{ 172{
@@ -191,7 +190,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
191 return result; 190 return result;
192} 191}
193 192
194static ssize_t 193ssize_t
195nfs_file_splice_read(struct file *filp, loff_t *ppos, 194nfs_file_splice_read(struct file *filp, loff_t *ppos,
196 struct pipe_inode_info *pipe, size_t count, 195 struct pipe_inode_info *pipe, size_t count,
197 unsigned int flags) 196 unsigned int flags)
@@ -213,7 +212,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
213 return res; 212 return res;
214} 213}
215 214
216static int 215int
217nfs_file_mmap(struct file * file, struct vm_area_struct * vma) 216nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
218{ 217{
219 struct dentry *dentry = file->f_path.dentry; 218 struct dentry *dentry = file->f_path.dentry;
@@ -246,7 +245,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
246 * nfs_file_write() that a write error occurred, and hence cause it to 245 * nfs_file_write() that a write error occurred, and hence cause it to
247 * fall back to doing a synchronous write. 246 * fall back to doing a synchronous write.
248 */ 247 */
249static int 248int
250nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) 249nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
251{ 250{
252 struct dentry *dentry = file->f_path.dentry; 251 struct dentry *dentry = file->f_path.dentry;
@@ -561,8 +560,8 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
561 return 0; 560 return 0;
562} 561}
563 562
564static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, 563ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
565 unsigned long nr_segs, loff_t pos) 564 unsigned long nr_segs, loff_t pos)
566{ 565{
567 struct dentry * dentry = iocb->ki_filp->f_path.dentry; 566 struct dentry * dentry = iocb->ki_filp->f_path.dentry;
568 struct inode * inode = dentry->d_inode; 567 struct inode * inode = dentry->d_inode;
@@ -613,9 +612,9 @@ out_swapfile:
613 goto out; 612 goto out;
614} 613}
615 614
616static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, 615ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
617 struct file *filp, loff_t *ppos, 616 struct file *filp, loff_t *ppos,
618 size_t count, unsigned int flags) 617 size_t count, unsigned int flags)
619{ 618{
620 struct dentry *dentry = filp->f_path.dentry; 619 struct dentry *dentry = filp->f_path.dentry;
621 struct inode *inode = dentry->d_inode; 620 struct inode *inode = dentry->d_inode;
@@ -767,7 +766,7 @@ out:
767/* 766/*
768 * Lock a (portion of) a file 767 * Lock a (portion of) a file
769 */ 768 */
770static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) 769int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
771{ 770{
772 struct inode *inode = filp->f_mapping->host; 771 struct inode *inode = filp->f_mapping->host;
773 int ret = -ENOLCK; 772 int ret = -ENOLCK;
@@ -807,7 +806,7 @@ out_err:
807/* 806/*
808 * Lock a (portion of) a file 807 * Lock a (portion of) a file
809 */ 808 */
810static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) 809int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
811{ 810{
812 struct inode *inode = filp->f_mapping->host; 811 struct inode *inode = filp->f_mapping->host;
813 int is_local = 0; 812 int is_local = 0;
@@ -837,7 +836,7 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
837 * There is no protocol support for leases, so we have no way to implement 836 * There is no protocol support for leases, so we have no way to implement
838 * them correctly in the face of opens by other clients. 837 * them correctly in the face of opens by other clients.
839 */ 838 */
840static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) 839int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
841{ 840{
842 dprintk("NFS: setlease(%s/%s, arg=%ld)\n", 841 dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
843 file->f_path.dentry->d_parent->d_name.name, 842 file->f_path.dentry->d_parent->d_name.name,
@@ -863,121 +862,3 @@ const struct file_operations nfs_file_operations = {
863 .check_flags = nfs_check_flags, 862 .check_flags = nfs_check_flags,
864 .setlease = nfs_setlease, 863 .setlease = nfs_setlease,
865}; 864};
866
867#ifdef CONFIG_NFS_V4
868static int
869nfs4_file_open(struct inode *inode, struct file *filp)
870{
871 struct nfs_open_context *ctx;
872 struct dentry *dentry = filp->f_path.dentry;
873 struct dentry *parent = NULL;
874 struct inode *dir;
875 unsigned openflags = filp->f_flags;
876 struct iattr attr;
877 int err;
878
879 BUG_ON(inode != dentry->d_inode);
880 /*
881 * If no cached dentry exists or if it's negative, NFSv4 handled the
882 * opens in ->lookup() or ->create().
883 *
884 * We only get this far for a cached positive dentry. We skipped
885 * revalidation, so handle it here by dropping the dentry and returning
886 * -EOPENSTALE. The VFS will retry the lookup/create/open.
887 */
888
889 dprintk("NFS: open file(%s/%s)\n",
890 dentry->d_parent->d_name.name,
891 dentry->d_name.name);
892
893 if ((openflags & O_ACCMODE) == 3)
894 openflags--;
895
896 /* We can't create new files here */
897 openflags &= ~(O_CREAT|O_EXCL);
898
899 parent = dget_parent(dentry);
900 dir = parent->d_inode;
901
902 ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
903 err = PTR_ERR(ctx);
904 if (IS_ERR(ctx))
905 goto out;
906
907 attr.ia_valid = ATTR_OPEN;
908 if (openflags & O_TRUNC) {
909 attr.ia_valid |= ATTR_SIZE;
910 attr.ia_size = 0;
911 nfs_wb_all(inode);
912 }
913
914 inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr);
915 if (IS_ERR(inode)) {
916 err = PTR_ERR(inode);
917 switch (err) {
918 case -EPERM:
919 case -EACCES:
920 case -EDQUOT:
921 case -ENOSPC:
922 case -EROFS:
923 goto out_put_ctx;
924 default:
925 goto out_drop;
926 }
927 }
928 iput(inode);
929 if (inode != dentry->d_inode)
930 goto out_drop;
931
932 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
933 nfs_file_set_open_context(filp, ctx);
934 err = 0;
935
936out_put_ctx:
937 put_nfs_open_context(ctx);
938out:
939 dput(parent);
940 return err;
941
942out_drop:
943 d_drop(dentry);
944 err = -EOPENSTALE;
945 goto out_put_ctx;
946}
947
948static int
949nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
950{
951 int ret;
952 struct inode *inode = file->f_path.dentry->d_inode;
953
954 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
955 mutex_lock(&inode->i_mutex);
956 ret = nfs_file_fsync_commit(file, start, end, datasync);
957 if (!ret && !datasync)
958 /* application has asked for meta-data sync */
959 ret = pnfs_layoutcommit_inode(inode, true);
960 mutex_unlock(&inode->i_mutex);
961
962 return ret;
963}
964
965const struct file_operations nfs4_file_operations = {
966 .llseek = nfs_file_llseek,
967 .read = do_sync_read,
968 .write = do_sync_write,
969 .aio_read = nfs_file_read,
970 .aio_write = nfs_file_write,
971 .mmap = nfs_file_mmap,
972 .open = nfs4_file_open,
973 .flush = nfs_file_flush,
974 .release = nfs_file_release,
975 .fsync = nfs4_file_fsync,
976 .lock = nfs_lock,
977 .flock = nfs_flock,
978 .splice_read = nfs_file_splice_read,
979 .splice_write = nfs_file_splice_write,
980 .check_flags = nfs_check_flags,
981 .setlease = nfs_setlease,
982};
983#endif /* CONFIG_NFS_V4 */