Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=45328c354e8ae16b67cb3adb72ab57459f9e5fd6
Commit:     45328c354e8ae16b67cb3adb72ab57459f9e5fd6
Parent:     ba683031fae115d61c6b5f4c675cc27f6e9576d2
Author:     Trond Myklebust <[EMAIL PROTECTED]>
AuthorDate: Thu Jul 26 17:47:34 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Aug 7 15:13:19 2007 -0400

    NFS: Fix NFSv4 open stateid regressions
    
    Do not allow cached open for O_RDONLY or O_WRONLY unless the file has been
    previously opened in these modes.
    
    Also Fix the calculation of the mode in nfs4_close_prepare. We should only
    issue an OPEN_DOWNGRADE if we're sure that we will still be holding the
    correct open modes. This may not be the case if we've been doing delegated
    opens.
    
    Finally, there is no need to adjust the open mode bit flags in
    nfs4_close_done(): that has already been done in nfs4_close_prepare().
    
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/nfs4proc.c |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6ca2795..62b3ae2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -332,11 +332,9 @@ static int can_open_cached(struct nfs4_state *state, int 
mode)
        switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) {
                case FMODE_READ:
                        ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0;
-                       ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
                        break;
                case FMODE_WRITE:
                        ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0;
-                       ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
                        break;
                case FMODE_READ|FMODE_WRITE:
                        ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
@@ -1260,7 +1258,7 @@ static void nfs4_close_done(struct rpc_task *task, void 
*data)
        nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
        switch (task->tk_status) {
                case 0:
-                       nfs_set_open_stateid(state, &calldata->res.stateid, 
calldata->arg.open_flags);
+                       nfs_set_open_stateid(state, &calldata->res.stateid, 0);
                        renew_lease(server, calldata->timestamp);
                        break;
                case -NFS4ERR_STALE_STATEID:
@@ -1286,23 +1284,19 @@ static void nfs4_close_prepare(struct rpc_task *task, 
void *data)
                .rpc_cred = state->owner->so_cred,
        };
        int clear_rd, clear_wr, clear_rdwr;
-       int mode;
 
        if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
                return;
 
-       mode = FMODE_READ|FMODE_WRITE;
        clear_rd = clear_wr = clear_rdwr = 0;
        spin_lock(&state->owner->so_lock);
        /* Calculate the change in open mode */
        if (state->n_rdwr == 0) {
                if (state->n_rdonly == 0) {
-                       mode &= ~FMODE_READ;
                        clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, 
&state->flags);
                        clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, 
&state->flags);
                }
                if (state->n_wronly == 0) {
-                       mode &= ~FMODE_WRITE;
                        clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, 
&state->flags);
                        clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, 
&state->flags);
                }
@@ -1314,9 +1308,13 @@ static void nfs4_close_prepare(struct rpc_task *task, 
void *data)
                return;
        }
        nfs_fattr_init(calldata->res.fattr);
-       if (mode != 0)
+       if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) {
                msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
-       calldata->arg.open_flags = mode;
+               calldata->arg.open_flags = FMODE_READ;
+       } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) {
+               msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
+               calldata->arg.open_flags = FMODE_WRITE;
+       }
        calldata->timestamp = jiffies;
        rpc_call_setup(task, &msg, 0);
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to