Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1ac7e2fd35905f3d44df06568bca5f9d140369b3
Commit:     1ac7e2fd35905f3d44df06568bca5f9d140369b3
Parent:     6ee412689027dc7954453aed392ab5c7599c0f73
Author:     Trond Myklebust <[EMAIL PROTECTED]>
AuthorDate: Sun Jul 8 21:04:15 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 23:40:43 2007 -0400

    NFSv4: Clean up the callers of nfs4_open_recover_helper()
    
    Rely on nfs4_try_open_cached() when appropriate.
    
    Also fix an RCU violation in _nfs4_do_open_reclaim()
    
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/nfs4proc.c |   42 ++++++++++++++++++++----------------------
 1 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1de0766..3a2af80 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -602,6 +602,19 @@ static int nfs4_open_recover(struct nfs4_opendata 
*opendata, struct nfs4_state *
                if (newstate != state)
                        return -ESTALE;
        }
+       /*
+        * We may have performed cached opens for all three recoveries.
+        * Check if we need to update the current stateid.
+        */
+       if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0 &&
+           memcmp(state->stateid.data, state->open_stateid.data, 
sizeof(state->stateid.data)) != 0) {
+               spin_lock(&state->owner->so_lock);
+               spin_lock(&state->inode->i_lock);
+               if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
+                       memcpy(state->stateid.data, state->open_stateid.data, 
sizeof(state->stateid.data));
+               spin_unlock(&state->inode->i_lock);
+               spin_unlock(&state->owner->so_lock);
+       }
        return 0;
 }
 
@@ -611,26 +624,22 @@ static int nfs4_open_recover(struct nfs4_opendata 
*opendata, struct nfs4_state *
  */
 static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct 
nfs4_state *state)
 {
-       struct nfs_delegation *delegation = NFS_I(state->inode)->delegation;
+       struct nfs_delegation *delegation;
        struct nfs4_opendata *opendata;
        int delegation_type = 0;
        int status;
 
-       if (delegation != NULL) {
-               if (!(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
-                       memcpy(&state->stateid, &delegation->stateid,
-                                       sizeof(state->stateid));
-                       set_bit(NFS_DELEGATED_STATE, &state->flags);
-                       return 0;
-               }
-               delegation_type = delegation->type;
-       }
        opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
        if (opendata == NULL)
                return -ENOMEM;
        opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
        opendata->o_arg.fh = NFS_FH(state->inode);
        nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh);
+       rcu_read_lock();
+       delegation = rcu_dereference(NFS_I(state->inode)->delegation);
+       if (delegation != NULL && (delegation->flags & 
NFS_DELEGATION_NEED_RECLAIM) != 0)
+               delegation_type = delegation->flags;
+       rcu_read_unlock();
        opendata->o_arg.u.delegation_type = delegation_type;
        status = nfs4_open_recover(opendata, state);
        nfs4_opendata_put(opendata);
@@ -980,21 +989,10 @@ static int nfs4_recover_expired_lease(struct nfs_server 
*server)
  */
 static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state 
*state)
 {
-       struct inode *inode = state->inode;
-       struct nfs_delegation *delegation = NFS_I(inode)->delegation;
        struct nfs4_opendata *opendata;
-       int openflags = state->state & (FMODE_READ|FMODE_WRITE);
        int ret;
 
-       if (delegation != NULL && !(delegation->flags & 
NFS_DELEGATION_NEED_RECLAIM)) {
-               ret = _nfs4_do_access(inode, ctx->cred, openflags);
-               if (ret < 0)
-                       return ret;
-               memcpy(&state->stateid, &delegation->stateid, 
sizeof(state->stateid));
-               set_bit(NFS_DELEGATED_STATE, &state->flags);
-               return 0;
-       }
-       opendata = nfs4_opendata_alloc(&ctx->path, state->owner, openflags, 
NULL);
+       opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
        if (opendata == NULL)
                return -ENOMEM;
        ret = nfs4_open_recover(opendata, state);
-
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