diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2006-01-18 20:43:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:20:27 -0500 |
commit | 6c26d08f02f829a833d393c3f1b196538a9ec2c4 (patch) | |
tree | 6425e263f072a73db7ced341c4df9507ae46ccef /fs/nfsd | |
parent | fb553c0f17444e090db951b96df4d2d71b4f4b6b (diff) |
[PATCH] nfsd4: fix open_downgrade
Bad bookkeeping of the share reservations when handling open upgrades was
causing open downgrade to fail.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4state.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 7167dcf8e1fe..82c36ccd8b5c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1609,26 +1609,26 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta | |||
1609 | { | 1609 | { |
1610 | struct file *filp = stp->st_vfs_file; | 1610 | struct file *filp = stp->st_vfs_file; |
1611 | struct inode *inode = filp->f_dentry->d_inode; | 1611 | struct inode *inode = filp->f_dentry->d_inode; |
1612 | unsigned int share_access; | 1612 | unsigned int share_access, new_writer; |
1613 | int status; | 1613 | int status; |
1614 | 1614 | ||
1615 | set_access(&share_access, stp->st_access_bmap); | 1615 | set_access(&share_access, stp->st_access_bmap); |
1616 | share_access = ~share_access; | 1616 | new_writer = (~share_access) & open->op_share_access |
1617 | share_access &= open->op_share_access; | 1617 | & NFS4_SHARE_ACCESS_WRITE; |
1618 | |||
1619 | if (!(share_access & NFS4_SHARE_ACCESS_WRITE)) | ||
1620 | return nfsd4_truncate(rqstp, cur_fh, open); | ||
1621 | 1618 | ||
1622 | status = get_write_access(inode); | 1619 | if (new_writer) { |
1623 | if (status) | 1620 | status = get_write_access(inode); |
1624 | return nfserrno(status); | 1621 | if (status) |
1622 | return nfserrno(status); | ||
1623 | } | ||
1625 | status = nfsd4_truncate(rqstp, cur_fh, open); | 1624 | status = nfsd4_truncate(rqstp, cur_fh, open); |
1626 | if (status) { | 1625 | if (status) { |
1627 | put_write_access(inode); | 1626 | if (new_writer) |
1627 | put_write_access(inode); | ||
1628 | return status; | 1628 | return status; |
1629 | } | 1629 | } |
1630 | /* remember the open */ | 1630 | /* remember the open */ |
1631 | filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ; | 1631 | filp->f_mode |= open->op_share_access; |
1632 | set_bit(open->op_share_access, &stp->st_access_bmap); | 1632 | set_bit(open->op_share_access, &stp->st_access_bmap); |
1633 | set_bit(open->op_share_deny, &stp->st_deny_bmap); | 1633 | set_bit(open->op_share_deny, &stp->st_deny_bmap); |
1634 | 1634 | ||