nfsd4: fix openmode checking on IO using lock stateid
authorJ. Bruce Fields <bfields@redhat.com>
Thu, 29 Jul 2010 19:16:59 +0000 (15:16 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 29 Jul 2010 20:37:12 +0000 (16:37 -0400)
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>
fs/nfsd/nfs4state.c

index d9c8232fc62f47c2423f5015ce3eb8120f8ddd96..b996a4badeb8af772dafcb512c6f59bd6f70bb35 100644 (file)
@@ -2779,6 +2779,9 @@ __be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
 {
         __be32 status = nfserr_openmode;
 
+       /* For lock stateid's, we test the parent open, not the lock: */
+       if (stp->st_openstp)
+               stp = stp->st_openstp;
        if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
                 goto out;
        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
        stp->st_stateid.si_fileid = fp->fi_id;
        stp->st_stateid.si_generation = 0;
        stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
-       stp->st_access_bmap = open_stp->st_access_bmap;
        stp->st_deny_bmap = open_stp->st_deny_bmap;
        stp->st_openstp = open_stp;