diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-03 01:28:53 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-03 20:41:21 -0400 |
commit | d87a8ade95288f28c729e076cd74929f3f199b6c (patch) | |
tree | 700a10f87def9db1c9657f2f7a61286bc06c8d03 /fs | |
parent | 60adfc50de3855628dea8f8896a65f471f51301c (diff) |
nfsd41: access_valid
For nfs41, the open share flags are used also for
delegation "wants" and "signals". Check that they are valid.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 20 |
2 files changed, 16 insertions, 5 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 3fdcca53212a..db208dd8fdca 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -910,6 +910,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
910 | resp->tag = args->tag; | 910 | resp->tag = args->tag; |
911 | resp->opcnt = 0; | 911 | resp->opcnt = 0; |
912 | resp->rqstp = rqstp; | 912 | resp->rqstp = rqstp; |
913 | resp->cstate.minorversion = args->minorversion; | ||
913 | resp->cstate.replay_owner = NULL; | 914 | resp->cstate.replay_owner = NULL; |
914 | fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); | 915 | fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); |
915 | fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); | 916 | fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d227f85b5ed2..374aaf3808e8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1943,11 +1943,21 @@ find_file(struct inode *ino) | |||
1943 | return NULL; | 1943 | return NULL; |
1944 | } | 1944 | } |
1945 | 1945 | ||
1946 | static inline int access_valid(u32 x) | 1946 | static inline int access_valid(u32 x, u32 minorversion) |
1947 | { | 1947 | { |
1948 | if (x < NFS4_SHARE_ACCESS_READ) | 1948 | if ((x & NFS4_SHARE_ACCESS_MASK) < NFS4_SHARE_ACCESS_READ) |
1949 | return 0; | 1949 | return 0; |
1950 | if (x > NFS4_SHARE_ACCESS_BOTH) | 1950 | if ((x & NFS4_SHARE_ACCESS_MASK) > NFS4_SHARE_ACCESS_BOTH) |
1951 | return 0; | ||
1952 | x &= ~NFS4_SHARE_ACCESS_MASK; | ||
1953 | if (minorversion && x) { | ||
1954 | if ((x & NFS4_SHARE_WANT_MASK) > NFS4_SHARE_WANT_CANCEL) | ||
1955 | return 0; | ||
1956 | if ((x & NFS4_SHARE_WHEN_MASK) > NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED) | ||
1957 | return 0; | ||
1958 | x &= ~(NFS4_SHARE_WANT_MASK | NFS4_SHARE_WHEN_MASK); | ||
1959 | } | ||
1960 | if (x) | ||
1951 | return 0; | 1961 | return 0; |
1952 | return 1; | 1962 | return 1; |
1953 | } | 1963 | } |
@@ -2495,7 +2505,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
2495 | __be32 status; | 2505 | __be32 status; |
2496 | 2506 | ||
2497 | status = nfserr_inval; | 2507 | status = nfserr_inval; |
2498 | if (!access_valid(open->op_share_access) | 2508 | if (!access_valid(open->op_share_access, resp->cstate.minorversion) |
2499 | || !deny_valid(open->op_share_deny)) | 2509 | || !deny_valid(open->op_share_deny)) |
2500 | goto out; | 2510 | goto out; |
2501 | /* | 2511 | /* |
@@ -3104,7 +3114,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, | |||
3104 | (int)cstate->current_fh.fh_dentry->d_name.len, | 3114 | (int)cstate->current_fh.fh_dentry->d_name.len, |
3105 | cstate->current_fh.fh_dentry->d_name.name); | 3115 | cstate->current_fh.fh_dentry->d_name.name); |
3106 | 3116 | ||
3107 | if (!access_valid(od->od_share_access) | 3117 | if (!access_valid(od->od_share_access, cstate->minorversion) |
3108 | || !deny_valid(od->od_share_deny)) | 3118 | || !deny_valid(od->od_share_deny)) |
3109 | return nfserr_inval; | 3119 | return nfserr_inval; |
3110 | 3120 | ||