Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6f2e64d3e1f661095e274c9d9d47e3f39a6cf1c0
Commit:     6f2e64d3e1f661095e274c9d9d47e3f39a6cf1c0
Parent:     275a5d24bf56b2d9dd4644c54a56366b89a028f1
Author:     Trond Myklebust <[EMAIL PROTECTED]>
AuthorDate: Fri Jul 6 10:53:21 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 23:40:48 2007 -0400

    NFSv4: Make the NFS state model work with the nosharedcache mount option
    
    Consider the case where the user has mounted the remote filesystem
    server:/foo on the two local directories /bar and /baz using the
    nosharedcache mount option. The files /bar/file and /baz/file are
    represented by different inodes in the local namespace, but refer to the
    same file /foo/file on the server.
    Consider the case where a process opens both /bar/file and /baz/file, then
    closes /bar/file: because the nfs4_state is not shared between /bar/file
    and /baz/file, the kernel will see that the nfs4_state for /bar/file is no
    longer referenced, so it will send off a CLOSE rpc call. Unless the
    open_owners differ, then that CLOSE call will invalidate the open state on
    /baz/file too.
    
    Conclusion: we cannot share open state owners between two different
    non-shared mount instances of the same filesystem.
    
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/nfs4_fs.h   |    1 +
 fs/nfs/nfs4state.c |   22 ++++++++++++++++++++--
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index dd1aa2b..6c028e7 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -83,6 +83,7 @@ struct nfs_unique_id {
 struct nfs4_state_owner {
        struct nfs_unique_id so_owner_id;
        struct nfs_client    *so_client;
+       struct nfs_server    *so_server;
        struct rb_node       so_client_node;
 
        struct rpc_cred      *so_cred;   /* Associated cred */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 523cc2c..e9662ba 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -156,8 +156,9 @@ static void nfs_free_unique_id(struct rb_root *root, struct 
nfs_unique_id *id)
 }
 
 static struct nfs4_state_owner *
-nfs4_find_state_owner(struct nfs_client *clp, struct rpc_cred *cred)
+nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred)
 {
+       struct nfs_client *clp = server->nfs_client;
        struct rb_node **p = &clp->cl_state_owners.rb_node,
                       *parent = NULL;
        struct nfs4_state_owner *sp, *res = NULL;
@@ -166,6 +167,14 @@ nfs4_find_state_owner(struct nfs_client *clp, struct 
rpc_cred *cred)
                parent = *p;
                sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
 
+               if (server < sp->so_server) {
+                       p = &parent->rb_left;
+                       continue;
+               }
+               if (server > sp->so_server) {
+                       p = &parent->rb_right;
+                       continue;
+               }
                if (cred < sp->so_cred)
                        p = &parent->rb_left;
                else if (cred > sp->so_cred)
@@ -190,6 +199,14 @@ nfs4_insert_state_owner(struct nfs_client *clp, struct 
nfs4_state_owner *new)
                parent = *p;
                sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
 
+               if (new->so_server < sp->so_server) {
+                       p = &parent->rb_left;
+                       continue;
+               }
+               if (new->so_server > sp->so_server) {
+                       p = &parent->rb_right;
+                       continue;
+               }
                if (new->so_cred < sp->so_cred)
                        p = &parent->rb_left;
                else if (new->so_cred > sp->so_cred)
@@ -260,7 +277,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct 
nfs_server *server, struct
        struct nfs4_state_owner *sp, *new;
 
        spin_lock(&clp->cl_lock);
-       sp = nfs4_find_state_owner(clp, cred);
+       sp = nfs4_find_state_owner(server, cred);
        spin_unlock(&clp->cl_lock);
        if (sp != NULL)
                return sp;
@@ -268,6 +285,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct 
nfs_server *server, struct
        if (new == NULL)
                return NULL;
        new->so_client = clp;
+       new->so_server = server;
        new->so_cred = cred;
        spin_lock(&clp->cl_lock);
        sp = nfs4_insert_state_owner(clp, new);
-
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