diff options
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5e0dc528a0e8..cdeb3cfd6f32 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -1013,6 +1013,49 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
1013 | return status; | 1013 | return status; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | static __be32 | ||
1017 | nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
1018 | struct nfsd4_seek *seek) | ||
1019 | { | ||
1020 | int whence; | ||
1021 | __be32 status; | ||
1022 | struct file *file; | ||
1023 | |||
1024 | status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate, | ||
1025 | &seek->seek_stateid, | ||
1026 | RD_STATE, &file); | ||
1027 | if (status) { | ||
1028 | dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); | ||
1029 | return status; | ||
1030 | } | ||
1031 | |||
1032 | switch (seek->seek_whence) { | ||
1033 | case NFS4_CONTENT_DATA: | ||
1034 | whence = SEEK_DATA; | ||
1035 | break; | ||
1036 | case NFS4_CONTENT_HOLE: | ||
1037 | whence = SEEK_HOLE; | ||
1038 | break; | ||
1039 | default: | ||
1040 | status = nfserr_union_notsupp; | ||
1041 | goto out; | ||
1042 | } | ||
1043 | |||
1044 | /* | ||
1045 | * Note: This call does change file->f_pos, but nothing in NFSD | ||
1046 | * should ever file->f_pos. | ||
1047 | */ | ||
1048 | seek->seek_pos = vfs_llseek(file, seek->seek_offset, whence); | ||
1049 | if (seek->seek_pos < 0) | ||
1050 | status = nfserrno(seek->seek_pos); | ||
1051 | else if (seek->seek_pos >= i_size_read(file_inode(file))) | ||
1052 | seek->seek_eof = true; | ||
1053 | |||
1054 | out: | ||
1055 | fput(file); | ||
1056 | return status; | ||
1057 | } | ||
1058 | |||
1016 | /* This routine never returns NFS_OK! If there are no other errors, it | 1059 | /* This routine never returns NFS_OK! If there are no other errors, it |
1017 | * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the | 1060 | * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the |
1018 | * attributes matched. VERIFY is implemented by mapping NFSERR_SAME | 1061 | * attributes matched. VERIFY is implemented by mapping NFSERR_SAME |
@@ -1881,6 +1924,12 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1881 | .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid, | 1924 | .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid, |
1882 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, | 1925 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, |
1883 | }, | 1926 | }, |
1927 | |||
1928 | /* NFSv4.2 operations */ | ||
1929 | [OP_SEEK] = { | ||
1930 | .op_func = (nfsd4op_func)nfsd4_seek, | ||
1931 | .op_name = "OP_SEEK", | ||
1932 | }, | ||
1884 | }; | 1933 | }; |
1885 | 1934 | ||
1886 | int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op) | 1935 | int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op) |