aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2010-07-29 15:16:59 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-07-29 16:37:12 -0400
commit02921914170e3b7fea1cd82dac9713685d2de5e2 (patch)
tree623710431d4416022594d1a2a473f3ca64bf7490 /fs/nfsd
parent21fb4016bd592409bc8f95737e365ac82413b795 (diff)
nfsd4: fix openmode checking on IO using lock stateid
It is legal to perform a write using the lock stateid that was originally associated with a read lock, or with a file that was originally opened for read, but has since been upgraded. So, when checking the openmode, check the mode associated with the open stateid from which the lock was derived. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d9c8232fc62f..b996a4badeb8 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2779,6 +2779,9 @@ __be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
2779{ 2779{
2780 __be32 status = nfserr_openmode; 2780 __be32 status = nfserr_openmode;
2781 2781
2782 /* For lock stateid's, we test the parent open, not the lock: */
2783 if (stp->st_openstp)
2784 stp = stp->st_openstp;
2782 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 2785 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
2783 goto out; 2786 goto out;
2784 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) 2787 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
@@ -3466,7 +3469,6 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3466 stp->st_stateid.si_fileid = fp->fi_id; 3469 stp->st_stateid.si_fileid = fp->fi_id;
3467 stp->st_stateid.si_generation = 0; 3470 stp->st_stateid.si_generation = 0;
3468 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */ 3471 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
3469 stp->st_access_bmap = open_stp->st_access_bmap;
3470 stp->st_deny_bmap = open_stp->st_deny_bmap; 3472 stp->st_deny_bmap = open_stp->st_deny_bmap;
3471 stp->st_openstp = open_stp; 3473 stp->st_openstp = open_stp;
3472 3474