aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-03-02 17:13:50 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-03-20 15:36:15 -0400
commitab4684d1560f8d77f6ce82bd3f1f82937070d397 (patch)
tree71da95fc7b956d6c69f9ecf5ef98a76b158c387f /fs/nfsd/nfs4proc.c
parent8f199b8262cb150d055d29ba31faf0128ace4714 (diff)
NFSD: Fix nfs4_verifier memory alignment
Clean up due to code review. The nfs4_verifier's data field is not guaranteed to be u32-aligned. Casting an array of chars to a u32 * is considered generally hazardous. We can fix most of this by using a __be32 array to generate the verifier's contents and then byte-copying it into the verifier field. However, there is one spot where there is a backwards compatibility constraint: the do_nfsd_create() call expects a verifier which is 32-bit aligned. Fix this spot by forcing the alignment of the create verifier in the nfsd4_open args structure. Also, sizeof(nfs4_verifer) is the size of the in-core verifier data structure, but NFS4_VERIFIER_SIZE is the number of octets in an XDR'd verifier. The two are not interchangeable, even if they happen to have the same value. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r--fs/nfsd/nfs4proc.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 3f7dbc410e3a..2a9036670b8f 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -489,14 +489,20 @@ nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
489 &access->ac_supported); 489 &access->ac_supported);
490} 490}
491 491
492static void gen_boot_verifier(nfs4_verifier *verifier)
493{
494 __be32 verf[2];
495
496 verf[0] = (__be32)nfssvc_boot.tv_sec;
497 verf[1] = (__be32)nfssvc_boot.tv_usec;
498 memcpy(verifier->data, verf, sizeof(verifier->data));
499}
500
492static __be32 501static __be32
493nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 502nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
494 struct nfsd4_commit *commit) 503 struct nfsd4_commit *commit)
495{ 504{
496 u32 *p = (u32 *)commit->co_verf.data; 505 gen_boot_verifier(&commit->co_verf);
497 *p++ = nfssvc_boot.tv_sec;
498 *p++ = nfssvc_boot.tv_usec;
499
500 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 506 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
501 commit->co_count); 507 commit->co_count);
502} 508}
@@ -873,7 +879,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
873{ 879{
874 stateid_t *stateid = &write->wr_stateid; 880 stateid_t *stateid = &write->wr_stateid;
875 struct file *filp = NULL; 881 struct file *filp = NULL;
876 u32 *p;
877 __be32 status = nfs_ok; 882 __be32 status = nfs_ok;
878 unsigned long cnt; 883 unsigned long cnt;
879 884
@@ -895,9 +900,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
895 900
896 cnt = write->wr_buflen; 901 cnt = write->wr_buflen;
897 write->wr_how_written = write->wr_stable_how; 902 write->wr_how_written = write->wr_stable_how;
898 p = (u32 *)write->wr_verifier.data; 903 gen_boot_verifier(&write->wr_verifier);
899 *p++ = nfssvc_boot.tv_sec;
900 *p++ = nfssvc_boot.tv_usec;
901 904
902 status = nfsd_write(rqstp, &cstate->current_fh, filp, 905 status = nfsd_write(rqstp, &cstate->current_fh, filp,
903 write->wr_offset, rqstp->rq_vec, write->wr_vlen, 906 write->wr_offset, rqstp->rq_vec, write->wr_vlen,