]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfs/nfs4state.c
Pull bugzilla-9683 into release branch
[linux-2.6-omap-h63xx.git] / fs / nfs / nfs4state.c
index 523cc2cbb5e1b4b5d145de85d31bf03fc4cbabca..5a39c6f78acf9394960885a1b774392d84019629 100644 (file)
@@ -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);
@@ -323,8 +341,6 @@ nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode)
                else
                        list_move_tail(&state->open_states, &state->owner->so_states);
        }
-       if (mode == 0)
-               list_del_init(&state->inode_states);
        state->state = mode;
 }
 
@@ -397,8 +413,7 @@ void nfs4_put_open_state(struct nfs4_state *state)
        if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
                return;
        spin_lock(&inode->i_lock);
-       if (!list_empty(&state->inode_states))
-               list_del(&state->inode_states);
+       list_del(&state->inode_states);
        list_del(&state->open_states);
        spin_unlock(&inode->i_lock);
        spin_unlock(&owner->so_lock);
@@ -410,7 +425,7 @@ void nfs4_put_open_state(struct nfs4_state *state)
 /*
  * Close the current file.
  */
-void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mode, int wait)
 {
        struct nfs4_state_owner *owner = state->owner;
        int call_close = 0;
@@ -451,7 +466,17 @@ void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
                nfs4_put_open_state(state);
                nfs4_put_state_owner(owner);
        } else
-               nfs4_do_close(path, state);
+               nfs4_do_close(path, state, wait);
+}
+
+void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+       __nfs4_close(path, state, mode, 0);
+}
+
+void nfs4_close_sync(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+       __nfs4_close(path, state, mode, 1);
 }
 
 /*
@@ -484,7 +509,10 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
        lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
        if (lsp == NULL)
                return NULL;
-       lsp->ls_seqid.sequence = &state->owner->so_sequence;
+       rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue");
+       spin_lock_init(&lsp->ls_sequence.lock);
+       INIT_LIST_HEAD(&lsp->ls_sequence.list);
+       lsp->ls_seqid.sequence = &lsp->ls_sequence;
        atomic_set(&lsp->ls_count, 1);
        lsp->ls_owner = fl_owner;
        spin_lock(&clp->cl_lock);
@@ -759,7 +787,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
        for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
                if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
                        continue;
-               if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state)
+               if (nfs_file_open_context(fl->fl_file)->state != state)
                        continue;
                status = ops->recover_lock(state, fl);
                if (status >= 0)