diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-11-04 15:33:38 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-11-04 15:33:38 -0500 |
commit | d530838bfa507d67b40d13b00d9cbd7a46a47e78 (patch) | |
tree | f4b2be26c0a7b9ed3233a2be016b7e97427f8705 /fs/nfs/nfs4state.c | |
parent | 4cecb76ff86db46d2823550256c828b6597f418e (diff) |
NFSv4: Fix problem with OPEN_DOWNGRADE
RFC 3530 states that for OPEN_DOWNGRADE "The share_access and share_deny
bits specified must be exactly equal to the union of the share_access and
share_deny bits specified for some subset of the OPENs in effect for
current openowner on the current file.
Setattr is currently violating the NFSv4 rules for OPEN_DOWNGRADE in that
it may cause a downgrade from OPEN4_SHARE_ACCESS_BOTH to
OPEN4_SHARE_ACCESS_WRITE despite the fact that there exists no open file
with O_WRONLY access mode.
Fix the problem by replacing nfs4_find_state() with a modified version of
nfs_find_open_context().
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 33 |
1 files changed, 0 insertions, 33 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 959374d833a7..81d964bfd8a7 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -384,28 +384,6 @@ nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode) | |||
384 | } | 384 | } |
385 | 385 | ||
386 | static struct nfs4_state * | 386 | static struct nfs4_state * |
387 | __nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode) | ||
388 | { | ||
389 | struct nfs_inode *nfsi = NFS_I(inode); | ||
390 | struct nfs4_state *state; | ||
391 | |||
392 | mode &= (FMODE_READ|FMODE_WRITE); | ||
393 | list_for_each_entry(state, &nfsi->open_states, inode_states) { | ||
394 | if (state->owner->so_cred != cred) | ||
395 | continue; | ||
396 | if ((state->state & mode) != mode) | ||
397 | continue; | ||
398 | atomic_inc(&state->count); | ||
399 | if (mode & FMODE_READ) | ||
400 | state->nreaders++; | ||
401 | if (mode & FMODE_WRITE) | ||
402 | state->nwriters++; | ||
403 | return state; | ||
404 | } | ||
405 | return NULL; | ||
406 | } | ||
407 | |||
408 | static struct nfs4_state * | ||
409 | __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) | 387 | __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) |
410 | { | 388 | { |
411 | struct nfs_inode *nfsi = NFS_I(inode); | 389 | struct nfs_inode *nfsi = NFS_I(inode); |
@@ -423,17 +401,6 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) | |||
423 | return NULL; | 401 | return NULL; |
424 | } | 402 | } |
425 | 403 | ||
426 | struct nfs4_state * | ||
427 | nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode) | ||
428 | { | ||
429 | struct nfs4_state *state; | ||
430 | |||
431 | spin_lock(&inode->i_lock); | ||
432 | state = __nfs4_find_state(inode, cred, mode); | ||
433 | spin_unlock(&inode->i_lock); | ||
434 | return state; | ||
435 | } | ||
436 | |||
437 | static void | 404 | static void |
438 | nfs4_free_open_state(struct nfs4_state *state) | 405 | nfs4_free_open_state(struct nfs4_state *state) |
439 | { | 406 | { |