diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2012-07-16 16:39:15 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-07-17 13:33:50 -0400 |
commit | ce4ef7c0a8a0594d7b9d088d73866a4389402a7e (patch) | |
tree | 2898effa24c9b74d27b17dd8219064524537af1e /fs/nfs/file.c | |
parent | 466bfe7f4a5bee4cdd73d3f6bd290173a8c75a40 (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.c | 151 |
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 | ||
49 | static int nfs_check_flags(int flags) | 48 | int 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 | ||
78 | static int | 77 | int |
79 | nfs_file_release(struct inode *inode, struct file *filp) | 78 | nfs_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 | ||
120 | static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) | 119 | loff_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 | */ |
145 | static int | 144 | int |
146 | nfs_file_flush(struct file *file, fl_owner_t id) | 145 | nfs_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 | ||
170 | static ssize_t | 169 | ssize_t |
171 | nfs_file_read(struct kiocb *iocb, const struct iovec *iov, | 170 | nfs_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 | ||
194 | static ssize_t | 193 | ssize_t |
195 | nfs_file_splice_read(struct file *filp, loff_t *ppos, | 194 | nfs_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 | ||
216 | static int | 215 | int |
217 | nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | 216 | nfs_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 | */ |
249 | static int | 248 | int |
250 | nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) | 249 | nfs_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 | ||
564 | static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, | 563 | ssize_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 | ||
616 | static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, | 615 | ssize_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 | */ |
770 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | 769 | int 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 | */ |
810 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | 809 | int 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 | */ |
840 | static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) | 839 | int 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 | ||
868 | static int | ||
869 | nfs4_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 | |||
936 | out_put_ctx: | ||
937 | put_nfs_open_context(ctx); | ||
938 | out: | ||
939 | dput(parent); | ||
940 | return err; | ||
941 | |||
942 | out_drop: | ||
943 | d_drop(dentry); | ||
944 | err = -EOPENSTALE; | ||
945 | goto out_put_ctx; | ||
946 | } | ||
947 | |||
948 | static int | ||
949 | nfs4_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 | |||
965 | const 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 */ | ||