aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4_fs.h42
-rw-r--r--fs/nfs/nfs4proc.c111
-rw-r--r--fs/nfs/nfs4state.c145
-rw-r--r--fs/nfs/nfs4xdr.c43
4 files changed, 265 insertions, 76 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ec1a22d7b876..6ac6708484f5 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -93,6 +93,35 @@ struct nfs4_client {
93}; 93};
94 94
95/* 95/*
96 * struct rpc_sequence ensures that RPC calls are sent in the exact
97 * order that they appear on the list.
98 */
99struct rpc_sequence {
100 struct rpc_wait_queue wait; /* RPC call delay queue */
101 spinlock_t lock; /* Protects the list */
102 struct list_head list; /* Defines sequence of RPC calls */
103};
104
105#define NFS_SEQID_CONFIRMED 1
106struct nfs_seqid_counter {
107 struct rpc_sequence *sequence;
108 int flags;
109 u32 counter;
110};
111
112struct nfs_seqid {
113 struct list_head list;
114 struct nfs_seqid_counter *sequence;
115 struct rpc_task *task;
116};
117
118static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
119{
120 if (seqid_mutating_err(-status))
121 seqid->flags |= NFS_SEQID_CONFIRMED;
122}
123
124/*
96 * NFS4 state_owners and lock_owners are simply labels for ordered 125 * NFS4 state_owners and lock_owners are simply labels for ordered
97 * sequences of RPC calls. Their sole purpose is to provide once-only 126 * sequences of RPC calls. Their sole purpose is to provide once-only
98 * semantics by allowing the server to identify replayed requests. 127 * semantics by allowing the server to identify replayed requests.
@@ -106,12 +135,13 @@ struct nfs4_state_owner {
106 struct nfs4_client *so_client; 135 struct nfs4_client *so_client;
107 u32 so_id; /* 32-bit identifier, unique */ 136 u32 so_id; /* 32-bit identifier, unique */
108 struct semaphore so_sema; 137 struct semaphore so_sema;
109 u32 so_seqid; /* protected by so_sema */
110 atomic_t so_count; 138 atomic_t so_count;
111 139
112 struct rpc_cred *so_cred; /* Associated cred */ 140 struct rpc_cred *so_cred; /* Associated cred */
113 struct list_head so_states; 141 struct list_head so_states;
114 struct list_head so_delegations; 142 struct list_head so_delegations;
143 struct nfs_seqid_counter so_seqid;
144 struct rpc_sequence so_sequence;
115}; 145};
116 146
117/* 147/*
@@ -132,7 +162,7 @@ struct nfs4_lock_state {
132 fl_owner_t ls_owner; /* POSIX lock owner */ 162 fl_owner_t ls_owner; /* POSIX lock owner */
133#define NFS_LOCK_INITIALIZED 1 163#define NFS_LOCK_INITIALIZED 1
134 int ls_flags; 164 int ls_flags;
135 u32 ls_seqid; 165 struct nfs_seqid_counter ls_seqid;
136 u32 ls_id; 166 u32 ls_id;
137 nfs4_stateid ls_stateid; 167 nfs4_stateid ls_stateid;
138 atomic_t ls_count; 168 atomic_t ls_count;
@@ -224,12 +254,16 @@ extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state
224extern void nfs4_put_open_state(struct nfs4_state *); 254extern void nfs4_put_open_state(struct nfs4_state *);
225extern void nfs4_close_state(struct nfs4_state *, mode_t); 255extern void nfs4_close_state(struct nfs4_state *, mode_t);
226extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode); 256extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
227extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
228extern void nfs4_schedule_state_recovery(struct nfs4_client *); 257extern void nfs4_schedule_state_recovery(struct nfs4_client *);
229extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 258extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
230extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
231extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 259extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
232 260
261extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
262extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
263extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
264extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
265extern void nfs_free_seqid(struct nfs_seqid *seqid);
266
233extern const nfs4_stateid zero_stateid; 267extern const nfs4_stateid zero_stateid;
234 268
235/* nfs4xdr.c */ 269/* nfs4xdr.c */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9701ca8c9428..9ba89e7cdd28 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -218,7 +218,6 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
218 struct nfs_delegation *delegation = NFS_I(inode)->delegation; 218 struct nfs_delegation *delegation = NFS_I(inode)->delegation;
219 struct nfs_openargs o_arg = { 219 struct nfs_openargs o_arg = {
220 .fh = NFS_FH(inode), 220 .fh = NFS_FH(inode),
221 .seqid = sp->so_seqid,
222 .id = sp->so_id, 221 .id = sp->so_id,
223 .open_flags = state->state, 222 .open_flags = state->state,
224 .clientid = server->nfs4_state->cl_clientid, 223 .clientid = server->nfs4_state->cl_clientid,
@@ -245,8 +244,13 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
245 } 244 }
246 o_arg.u.delegation_type = delegation->type; 245 o_arg.u.delegation_type = delegation->type;
247 } 246 }
247 o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
248 if (o_arg.seqid == NULL)
249 return -ENOMEM;
248 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 250 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
249 nfs4_increment_seqid(status, sp); 251 /* Confirm the sequence as being established */
252 nfs_confirm_seqid(&sp->so_seqid, status);
253 nfs_increment_open_seqid(status, o_arg.seqid);
250 if (status == 0) { 254 if (status == 0) {
251 memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid)); 255 memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
252 if (o_res.delegation_type != 0) { 256 if (o_res.delegation_type != 0) {
@@ -256,6 +260,7 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
256 nfs_async_inode_return_delegation(inode, &o_res.stateid); 260 nfs_async_inode_return_delegation(inode, &o_res.stateid);
257 } 261 }
258 } 262 }
263 nfs_free_seqid(o_arg.seqid);
259 clear_bit(NFS_DELEGATED_STATE, &state->flags); 264 clear_bit(NFS_DELEGATED_STATE, &state->flags);
260 /* Ensure we update the inode attributes */ 265 /* Ensure we update the inode attributes */
261 NFS_CACHEINV(inode); 266 NFS_CACHEINV(inode);
@@ -307,16 +312,20 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state
307 goto out; 312 goto out;
308 if (state->state == 0) 313 if (state->state == 0)
309 goto out; 314 goto out;
310 arg.seqid = sp->so_seqid; 315 arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
316 status = -ENOMEM;
317 if (arg.seqid == NULL)
318 goto out;
311 arg.open_flags = state->state; 319 arg.open_flags = state->state;
312 memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data)); 320 memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data));
313 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 321 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
314 nfs4_increment_seqid(status, sp); 322 nfs_increment_open_seqid(status, arg.seqid);
315 if (status >= 0) { 323 if (status >= 0) {
316 memcpy(state->stateid.data, res.stateid.data, 324 memcpy(state->stateid.data, res.stateid.data,
317 sizeof(state->stateid.data)); 325 sizeof(state->stateid.data));
318 clear_bit(NFS_DELEGATED_STATE, &state->flags); 326 clear_bit(NFS_DELEGATED_STATE, &state->flags);
319 } 327 }
328 nfs_free_seqid(arg.seqid);
320out: 329out:
321 up(&sp->so_sema); 330 up(&sp->so_sema);
322 dput(parent); 331 dput(parent);
@@ -345,11 +354,11 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
345 return err; 354 return err;
346} 355}
347 356
348static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid) 357static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid)
349{ 358{
350 struct nfs_open_confirmargs arg = { 359 struct nfs_open_confirmargs arg = {
351 .fh = fh, 360 .fh = fh,
352 .seqid = sp->so_seqid, 361 .seqid = seqid,
353 .stateid = *stateid, 362 .stateid = *stateid,
354 }; 363 };
355 struct nfs_open_confirmres res; 364 struct nfs_open_confirmres res;
@@ -362,7 +371,9 @@ static inline int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nf
362 int status; 371 int status;
363 372
364 status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR); 373 status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR);
365 nfs4_increment_seqid(status, sp); 374 /* Confirm the sequence as being established */
375 nfs_confirm_seqid(&sp->so_seqid, status);
376 nfs_increment_open_seqid(status, seqid);
366 if (status >= 0) 377 if (status >= 0)
367 memcpy(stateid, &res.stateid, sizeof(*stateid)); 378 memcpy(stateid, &res.stateid, sizeof(*stateid));
368 return status; 379 return status;
@@ -380,21 +391,21 @@ static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner *sp, stru
380 int status; 391 int status;
381 392
382 /* Update sequence id. The caller must serialize! */ 393 /* Update sequence id. The caller must serialize! */
383 o_arg->seqid = sp->so_seqid;
384 o_arg->id = sp->so_id; 394 o_arg->id = sp->so_id;
385 o_arg->clientid = sp->so_client->cl_clientid; 395 o_arg->clientid = sp->so_client->cl_clientid;
386 396
387 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 397 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
388 nfs4_increment_seqid(status, sp); 398 nfs_increment_open_seqid(status, o_arg->seqid);
389 if (status != 0) 399 if (status != 0)
390 goto out; 400 goto out;
391 update_changeattr(dir, &o_res->cinfo); 401 update_changeattr(dir, &o_res->cinfo);
392 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 402 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
393 status = _nfs4_proc_open_confirm(server->client, &o_res->fh, 403 status = _nfs4_proc_open_confirm(server->client, &o_res->fh,
394 sp, &o_res->stateid); 404 sp, &o_res->stateid, o_arg->seqid);
395 if (status != 0) 405 if (status != 0)
396 goto out; 406 goto out;
397 } 407 }
408 nfs_confirm_seqid(&sp->so_seqid, 0);
398 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) 409 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
399 status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); 410 status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
400out: 411out:
@@ -465,6 +476,10 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
465 set_bit(NFS_DELEGATED_STATE, &state->flags); 476 set_bit(NFS_DELEGATED_STATE, &state->flags);
466 goto out; 477 goto out;
467 } 478 }
479 o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
480 status = -ENOMEM;
481 if (o_arg.seqid == NULL)
482 goto out;
468 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res); 483 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
469 if (status != 0) 484 if (status != 0)
470 goto out_nodeleg; 485 goto out_nodeleg;
@@ -490,6 +505,7 @@ static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
490 nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res); 505 nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res);
491 } 506 }
492out_nodeleg: 507out_nodeleg:
508 nfs_free_seqid(o_arg.seqid);
493 clear_bit(NFS_DELEGATED_STATE, &state->flags); 509 clear_bit(NFS_DELEGATED_STATE, &state->flags);
494out: 510out:
495 dput(parent); 511 dput(parent);
@@ -667,6 +683,9 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
667 /* Serialization for the sequence id */ 683 /* Serialization for the sequence id */
668 down(&sp->so_sema); 684 down(&sp->so_sema);
669 685
686 o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
687 if (o_arg.seqid == NULL)
688 return -ENOMEM;
670 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res); 689 status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
671 if (status != 0) 690 if (status != 0)
672 goto out_err; 691 goto out_err;
@@ -681,6 +700,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
681 update_open_stateid(state, &o_res.stateid, flags); 700 update_open_stateid(state, &o_res.stateid, flags);
682 if (o_res.delegation_type != 0) 701 if (o_res.delegation_type != 0)
683 nfs_inode_set_delegation(inode, cred, &o_res); 702 nfs_inode_set_delegation(inode, cred, &o_res);
703 nfs_free_seqid(o_arg.seqid);
684 up(&sp->so_sema); 704 up(&sp->so_sema);
685 nfs4_put_state_owner(sp); 705 nfs4_put_state_owner(sp);
686 up_read(&clp->cl_sem); 706 up_read(&clp->cl_sem);
@@ -690,6 +710,7 @@ out_err:
690 if (sp != NULL) { 710 if (sp != NULL) {
691 if (state != NULL) 711 if (state != NULL)
692 nfs4_put_open_state(state); 712 nfs4_put_open_state(state);
713 nfs_free_seqid(o_arg.seqid);
693 up(&sp->so_sema); 714 up(&sp->so_sema);
694 nfs4_put_state_owner(sp); 715 nfs4_put_state_owner(sp);
695 } 716 }
@@ -718,7 +739,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
718 * It is actually a sign of a bug on the client or on the server. 739 * It is actually a sign of a bug on the client or on the server.
719 * 740 *
720 * If we receive a BAD_SEQID error in the particular case of 741 * If we receive a BAD_SEQID error in the particular case of
721 * doing an OPEN, we assume that nfs4_increment_seqid() will 742 * doing an OPEN, we assume that nfs_increment_open_seqid() will
722 * have unhashed the old state_owner for us, and that we can 743 * have unhashed the old state_owner for us, and that we can
723 * therefore safely retry using a new one. We should still warn 744 * therefore safely retry using a new one. We should still warn
724 * the user though... 745 * the user though...
@@ -799,7 +820,7 @@ static void nfs4_close_done(struct rpc_task *task)
799 /* hmm. we are done with the inode, and in the process of freeing 820 /* hmm. we are done with the inode, and in the process of freeing
800 * the state_owner. we keep this around to process errors 821 * the state_owner. we keep this around to process errors
801 */ 822 */
802 nfs4_increment_seqid(task->tk_status, sp); 823 nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
803 switch (task->tk_status) { 824 switch (task->tk_status) {
804 case 0: 825 case 0:
805 memcpy(&state->stateid, &calldata->res.stateid, 826 memcpy(&state->stateid, &calldata->res.stateid,
@@ -818,6 +839,7 @@ static void nfs4_close_done(struct rpc_task *task)
818 } 839 }
819 state->state = calldata->arg.open_flags; 840 state->state = calldata->arg.open_flags;
820 nfs4_put_open_state(state); 841 nfs4_put_open_state(state);
842 nfs_free_seqid(calldata->arg.seqid);
821 up(&sp->so_sema); 843 up(&sp->so_sema);
822 nfs4_put_state_owner(sp); 844 nfs4_put_state_owner(sp);
823 up_read(&server->nfs4_state->cl_sem); 845 up_read(&server->nfs4_state->cl_sem);
@@ -865,7 +887,11 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode)
865 calldata->state = state; 887 calldata->state = state;
866 calldata->arg.fh = NFS_FH(inode); 888 calldata->arg.fh = NFS_FH(inode);
867 /* Serialization for the sequence id */ 889 /* Serialization for the sequence id */
868 calldata->arg.seqid = state->owner->so_seqid; 890 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
891 if (calldata->arg.seqid == NULL) {
892 kfree(calldata);
893 return -ENOMEM;
894 }
869 calldata->arg.open_flags = mode; 895 calldata->arg.open_flags = mode;
870 memcpy(&calldata->arg.stateid, &state->stateid, 896 memcpy(&calldata->arg.stateid, &state->stateid,
871 sizeof(calldata->arg.stateid)); 897 sizeof(calldata->arg.stateid));
@@ -2729,15 +2755,19 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock
2729 /* We might have lost the locks! */ 2755 /* We might have lost the locks! */
2730 if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) 2756 if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
2731 goto out; 2757 goto out;
2732 luargs.seqid = lsp->ls_seqid; 2758 luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid);
2733 memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid)); 2759 status = -ENOMEM;
2760 if (luargs.seqid == NULL)
2761 goto out;
2762 memcpy(luargs.stateid.data, lsp->ls_stateid.data, sizeof(luargs.stateid.data));
2734 arg.u.locku = &luargs; 2763 arg.u.locku = &luargs;
2735 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 2764 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
2736 nfs4_increment_lock_seqid(status, lsp); 2765 nfs_increment_lock_seqid(status, luargs.seqid);
2737 2766
2738 if (status == 0) 2767 if (status == 0)
2739 memcpy(&lsp->ls_stateid, &res.u.stateid, 2768 memcpy(lsp->ls_stateid.data, res.u.stateid.data,
2740 sizeof(lsp->ls_stateid)); 2769 sizeof(lsp->ls_stateid.data));
2770 nfs_free_seqid(luargs.seqid);
2741out: 2771out:
2742 up(&state->lock_sema); 2772 up(&state->lock_sema);
2743 if (status == 0) 2773 if (status == 0)
@@ -2783,9 +2813,13 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
2783 .reclaim = reclaim, 2813 .reclaim = reclaim,
2784 .new_lock_owner = 0, 2814 .new_lock_owner = 0,
2785 }; 2815 };
2786 int status; 2816 struct nfs_seqid *lock_seqid;
2817 int status = -ENOMEM;
2787 2818
2788 if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) { 2819 lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
2820 if (lock_seqid == NULL)
2821 return -ENOMEM;
2822 if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
2789 struct nfs4_state_owner *owner = state->owner; 2823 struct nfs4_state_owner *owner = state->owner;
2790 struct nfs_open_to_lock otl = { 2824 struct nfs_open_to_lock otl = {
2791 .lock_owner = { 2825 .lock_owner = {
@@ -2793,39 +2827,40 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
2793 }, 2827 },
2794 }; 2828 };
2795 2829
2796 otl.lock_seqid = lsp->ls_seqid; 2830 otl.lock_seqid = lock_seqid;
2797 otl.lock_owner.id = lsp->ls_id; 2831 otl.lock_owner.id = lsp->ls_id;
2798 memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid)); 2832 memcpy(&otl.open_stateid, &state->stateid, sizeof(otl.open_stateid));
2799 largs.u.open_lock = &otl; 2833 largs.u.open_lock = &otl;
2800 largs.new_lock_owner = 1; 2834 largs.new_lock_owner = 1;
2801 arg.u.lock = &largs; 2835 arg.u.lock = &largs;
2802 down(&owner->so_sema); 2836 down(&owner->so_sema);
2803 otl.open_seqid = owner->so_seqid; 2837 otl.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
2804 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 2838 if (otl.open_seqid != NULL) {
2805 /* increment open_owner seqid on success, and 2839 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
2806 * seqid mutating errors */ 2840 /* increment seqid on success, and seqid mutating errors */
2807 nfs4_increment_seqid(status, owner); 2841 nfs_increment_open_seqid(status, otl.open_seqid);
2808 up(&owner->so_sema); 2842 nfs_free_seqid(otl.open_seqid);
2809 if (status == 0) {
2810 lsp->ls_flags |= NFS_LOCK_INITIALIZED;
2811 lsp->ls_seqid++;
2812 } 2843 }
2844 up(&owner->so_sema);
2845 if (status == 0)
2846 nfs_confirm_seqid(&lsp->ls_seqid, 0);
2813 } else { 2847 } else {
2814 struct nfs_exist_lock el = { 2848 struct nfs_exist_lock el;
2815 .seqid = lsp->ls_seqid,
2816 };
2817 memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid)); 2849 memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
2818 largs.u.exist_lock = ⪙ 2850 largs.u.exist_lock = ⪙
2819 arg.u.lock = &largs; 2851 arg.u.lock = &largs;
2852 el.seqid = lock_seqid;
2820 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 2853 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
2821 /* increment seqid on success, and * seqid mutating errors*/
2822 nfs4_increment_lock_seqid(status, lsp);
2823 } 2854 }
2855 /* increment seqid on success, and seqid mutating errors*/
2856 nfs_increment_lock_seqid(status, lock_seqid);
2824 /* save the returned stateid. */ 2857 /* save the returned stateid. */
2825 if (status == 0) 2858 if (status == 0) {
2826 memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid)); 2859 memcpy(lsp->ls_stateid.data, res.u.stateid.data, sizeof(lsp->ls_stateid.data));
2827 else if (status == -NFS4ERR_DENIED) 2860 lsp->ls_flags |= NFS_LOCK_INITIALIZED;
2861 } else if (status == -NFS4ERR_DENIED)
2828 status = -EAGAIN; 2862 status = -EAGAIN;
2863 nfs_free_seqid(lock_seqid);
2829 return status; 2864 return status;
2830} 2865}
2831 2866
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index afe587d82f1e..f535c219cf3a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -264,13 +264,16 @@ nfs4_alloc_state_owner(void)
264{ 264{
265 struct nfs4_state_owner *sp; 265 struct nfs4_state_owner *sp;
266 266
267 sp = kmalloc(sizeof(*sp),GFP_KERNEL); 267 sp = kzalloc(sizeof(*sp),GFP_KERNEL);
268 if (!sp) 268 if (!sp)
269 return NULL; 269 return NULL;
270 init_MUTEX(&sp->so_sema); 270 init_MUTEX(&sp->so_sema);
271 sp->so_seqid = 0; /* arbitrary */
272 INIT_LIST_HEAD(&sp->so_states); 271 INIT_LIST_HEAD(&sp->so_states);
273 INIT_LIST_HEAD(&sp->so_delegations); 272 INIT_LIST_HEAD(&sp->so_delegations);
273 rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
274 sp->so_seqid.sequence = &sp->so_sequence;
275 spin_lock_init(&sp->so_sequence.lock);
276 INIT_LIST_HEAD(&sp->so_sequence.list);
274 atomic_set(&sp->so_count, 1); 277 atomic_set(&sp->so_count, 1);
275 return sp; 278 return sp;
276} 279}
@@ -553,12 +556,10 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
553 struct nfs4_lock_state *lsp; 556 struct nfs4_lock_state *lsp;
554 struct nfs4_client *clp = state->owner->so_client; 557 struct nfs4_client *clp = state->owner->so_client;
555 558
556 lsp = kmalloc(sizeof(*lsp), GFP_KERNEL); 559 lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
557 if (lsp == NULL) 560 if (lsp == NULL)
558 return NULL; 561 return NULL;
559 lsp->ls_flags = 0; 562 lsp->ls_seqid.sequence = &state->owner->so_sequence;
560 lsp->ls_seqid = 0; /* arbitrary */
561 memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data));
562 atomic_set(&lsp->ls_count, 1); 563 atomic_set(&lsp->ls_count, 1);
563 lsp->ls_owner = fl_owner; 564 lsp->ls_owner = fl_owner;
564 spin_lock(&clp->cl_lock); 565 spin_lock(&clp->cl_lock);
@@ -673,29 +674,102 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
673 nfs4_put_lock_state(lsp); 674 nfs4_put_lock_state(lsp);
674} 675}
675 676
676/* 677struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
677* Called with state->lock_sema and clp->cl_sem held. 678{
678*/ 679 struct rpc_sequence *sequence = counter->sequence;
679void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp) 680 struct nfs_seqid *new;
681
682 new = kmalloc(sizeof(*new), GFP_KERNEL);
683 if (new != NULL) {
684 new->sequence = counter;
685 new->task = NULL;
686 spin_lock(&sequence->lock);
687 list_add_tail(&new->list, &sequence->list);
688 spin_unlock(&sequence->lock);
689 }
690 return new;
691}
692
693void nfs_free_seqid(struct nfs_seqid *seqid)
680{ 694{
681 if (status == NFS_OK || seqid_mutating_err(-status)) 695 struct rpc_sequence *sequence = seqid->sequence->sequence;
682 lsp->ls_seqid++; 696 struct rpc_task *next = NULL;
697
698 spin_lock(&sequence->lock);
699 list_del(&seqid->list);
700 if (!list_empty(&sequence->list)) {
701 next = list_entry(sequence->list.next, struct nfs_seqid, list)->task;
702 if (next)
703 rpc_wake_up_task(next);
704 }
705 spin_unlock(&sequence->lock);
706 kfree(seqid);
683} 707}
684 708
685/* 709/*
686* Called with sp->so_sema and clp->cl_sem held. 710 * Called with sp->so_sema and clp->cl_sem held.
687* 711 *
688* Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or 712 * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
689* failed with a seqid incrementing error - 713 * failed with a seqid incrementing error -
690* see comments nfs_fs.h:seqid_mutating_error() 714 * see comments nfs_fs.h:seqid_mutating_error()
691*/ 715 */
692void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp) 716static inline void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
693{ 717{
694 if (status == NFS_OK || seqid_mutating_err(-status)) 718 switch (status) {
695 sp->so_seqid++; 719 case 0:
696 /* If the server returns BAD_SEQID, unhash state_owner here */ 720 break;
697 if (status == -NFS4ERR_BAD_SEQID) 721 case -NFS4ERR_BAD_SEQID:
722 case -NFS4ERR_STALE_CLIENTID:
723 case -NFS4ERR_STALE_STATEID:
724 case -NFS4ERR_BAD_STATEID:
725 case -NFS4ERR_BADXDR:
726 case -NFS4ERR_RESOURCE:
727 case -NFS4ERR_NOFILEHANDLE:
728 /* Non-seqid mutating errors */
729 return;
730 };
731 /*
732 * Note: no locking needed as we are guaranteed to be first
733 * on the sequence list
734 */
735 seqid->sequence->counter++;
736}
737
738void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
739{
740 if (status == -NFS4ERR_BAD_SEQID) {
741 struct nfs4_state_owner *sp = container_of(seqid->sequence,
742 struct nfs4_state_owner, so_seqid);
698 nfs4_drop_state_owner(sp); 743 nfs4_drop_state_owner(sp);
744 }
745 return nfs_increment_seqid(status, seqid);
746}
747
748/*
749 * Called with ls->lock_sema and clp->cl_sem held.
750 *
751 * Increment the seqid if the LOCK/LOCKU succeeded, or
752 * failed with a seqid incrementing error -
753 * see comments nfs_fs.h:seqid_mutating_error()
754 */
755void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
756{
757 return nfs_increment_seqid(status, seqid);
758}
759
760int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
761{
762 struct rpc_sequence *sequence = seqid->sequence->sequence;
763 int status = 0;
764
765 spin_lock(&sequence->lock);
766 if (sequence->list.next != &seqid->list) {
767 seqid->task = task;
768 rpc_sleep_on(&sequence->wait, task, NULL, NULL);
769 status = -EAGAIN;
770 }
771 spin_unlock(&sequence->lock);
772 return status;
699} 773}
700 774
701static int reclaimer(void *); 775static int reclaimer(void *);
@@ -791,8 +865,6 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n
791 if (state->state == 0) 865 if (state->state == 0)
792 continue; 866 continue;
793 status = ops->recover_open(sp, state); 867 status = ops->recover_open(sp, state);
794 list_for_each_entry(lock, &state->lock_states, ls_locks)
795 lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
796 if (status >= 0) { 868 if (status >= 0) {
797 status = nfs4_reclaim_locks(ops, state); 869 status = nfs4_reclaim_locks(ops, state);
798 if (status < 0) 870 if (status < 0)
@@ -831,6 +903,26 @@ out_err:
831 return status; 903 return status;
832} 904}
833 905
906static void nfs4_state_mark_reclaim(struct nfs4_client *clp)
907{
908 struct nfs4_state_owner *sp;
909 struct nfs4_state *state;
910 struct nfs4_lock_state *lock;
911
912 /* Reset all sequence ids to zero */
913 list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
914 sp->so_seqid.counter = 0;
915 sp->so_seqid.flags = 0;
916 list_for_each_entry(state, &sp->so_states, open_states) {
917 list_for_each_entry(lock, &state->lock_states, ls_locks) {
918 lock->ls_seqid.counter = 0;
919 lock->ls_seqid.flags = 0;
920 lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
921 }
922 }
923 }
924}
925
834static int reclaimer(void *ptr) 926static int reclaimer(void *ptr)
835{ 927{
836 struct reclaimer_args *args = (struct reclaimer_args *)ptr; 928 struct reclaimer_args *args = (struct reclaimer_args *)ptr;
@@ -864,6 +956,7 @@ restart_loop:
864 default: 956 default:
865 ops = &nfs4_network_partition_recovery_ops; 957 ops = &nfs4_network_partition_recovery_ops;
866 }; 958 };
959 nfs4_state_mark_reclaim(clp);
867 status = __nfs4_init_client(clp); 960 status = __nfs4_init_client(clp);
868 if (status) 961 if (status)
869 goto out_error; 962 goto out_error;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6c564ef9489e..fcd28a29a2f8 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -604,7 +604,7 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
604 604
605 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 605 RESERVE_SPACE(8+sizeof(arg->stateid.data));
606 WRITE32(OP_CLOSE); 606 WRITE32(OP_CLOSE);
607 WRITE32(arg->seqid); 607 WRITE32(arg->seqid->sequence->counter);
608 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 608 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
609 609
610 return 0; 610 return 0;
@@ -732,9 +732,9 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
732 struct nfs_open_to_lock *ol = opargs->u.open_lock; 732 struct nfs_open_to_lock *ol = opargs->u.open_lock;
733 733
734 RESERVE_SPACE(40); 734 RESERVE_SPACE(40);
735 WRITE32(ol->open_seqid); 735 WRITE32(ol->open_seqid->sequence->counter);
736 WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid)); 736 WRITEMEM(&ol->open_stateid, sizeof(ol->open_stateid));
737 WRITE32(ol->lock_seqid); 737 WRITE32(ol->lock_seqid->sequence->counter);
738 WRITE64(ol->lock_owner.clientid); 738 WRITE64(ol->lock_owner.clientid);
739 WRITE32(4); 739 WRITE32(4);
740 WRITE32(ol->lock_owner.id); 740 WRITE32(ol->lock_owner.id);
@@ -744,7 +744,7 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
744 744
745 RESERVE_SPACE(20); 745 RESERVE_SPACE(20);
746 WRITEMEM(&el->stateid, sizeof(el->stateid)); 746 WRITEMEM(&el->stateid, sizeof(el->stateid));
747 WRITE32(el->seqid); 747 WRITE32(el->seqid->sequence->counter);
748 } 748 }
749 749
750 return 0; 750 return 0;
@@ -775,7 +775,7 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
775 RESERVE_SPACE(44); 775 RESERVE_SPACE(44);
776 WRITE32(OP_LOCKU); 776 WRITE32(OP_LOCKU);
777 WRITE32(arg->type); 777 WRITE32(arg->type);
778 WRITE32(opargs->seqid); 778 WRITE32(opargs->seqid->sequence->counter);
779 WRITEMEM(&opargs->stateid, sizeof(opargs->stateid)); 779 WRITEMEM(&opargs->stateid, sizeof(opargs->stateid));
780 WRITE64(arg->offset); 780 WRITE64(arg->offset);
781 WRITE64(arg->length); 781 WRITE64(arg->length);
@@ -826,7 +826,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
826 */ 826 */
827 RESERVE_SPACE(8); 827 RESERVE_SPACE(8);
828 WRITE32(OP_OPEN); 828 WRITE32(OP_OPEN);
829 WRITE32(arg->seqid); 829 WRITE32(arg->seqid->sequence->counter);
830 encode_share_access(xdr, arg->open_flags); 830 encode_share_access(xdr, arg->open_flags);
831 RESERVE_SPACE(16); 831 RESERVE_SPACE(16);
832 WRITE64(arg->clientid); 832 WRITE64(arg->clientid);
@@ -941,7 +941,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
941 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 941 RESERVE_SPACE(8+sizeof(arg->stateid.data));
942 WRITE32(OP_OPEN_CONFIRM); 942 WRITE32(OP_OPEN_CONFIRM);
943 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 943 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
944 WRITE32(arg->seqid); 944 WRITE32(arg->seqid->sequence->counter);
945 945
946 return 0; 946 return 0;
947} 947}
@@ -953,7 +953,7 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
953 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 953 RESERVE_SPACE(8+sizeof(arg->stateid.data));
954 WRITE32(OP_OPEN_DOWNGRADE); 954 WRITE32(OP_OPEN_DOWNGRADE);
955 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 955 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
956 WRITE32(arg->seqid); 956 WRITE32(arg->seqid->sequence->counter);
957 encode_share_access(xdr, arg->open_flags); 957 encode_share_access(xdr, arg->open_flags);
958 return 0; 958 return 0;
959} 959}
@@ -1416,6 +1416,9 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_clos
1416 }; 1416 };
1417 int status; 1417 int status;
1418 1418
1419 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1420 if (status != 0)
1421 goto out;
1419 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1422 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1420 encode_compound_hdr(&xdr, &hdr); 1423 encode_compound_hdr(&xdr, &hdr);
1421 status = encode_putfh(&xdr, args->fh); 1424 status = encode_putfh(&xdr, args->fh);
@@ -1437,6 +1440,9 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
1437 }; 1440 };
1438 int status; 1441 int status;
1439 1442
1443 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1444 if (status != 0)
1445 goto out;
1440 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1446 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1441 encode_compound_hdr(&xdr, &hdr); 1447 encode_compound_hdr(&xdr, &hdr);
1442 status = encode_putfh(&xdr, args->fh); 1448 status = encode_putfh(&xdr, args->fh);
@@ -1464,6 +1470,9 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
1464 }; 1470 };
1465 int status; 1471 int status;
1466 1472
1473 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1474 if (status != 0)
1475 goto out;
1467 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1476 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1468 encode_compound_hdr(&xdr, &hdr); 1477 encode_compound_hdr(&xdr, &hdr);
1469 status = encode_putfh(&xdr, args->fh); 1478 status = encode_putfh(&xdr, args->fh);
@@ -1485,6 +1494,9 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf
1485 }; 1494 };
1486 int status; 1495 int status;
1487 1496
1497 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1498 if (status != 0)
1499 goto out;
1488 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1500 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1489 encode_compound_hdr(&xdr, &hdr); 1501 encode_compound_hdr(&xdr, &hdr);
1490 status = encode_putfh(&xdr, args->fh); 1502 status = encode_putfh(&xdr, args->fh);
@@ -1506,6 +1518,9 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
1506 }; 1518 };
1507 int status; 1519 int status;
1508 1520
1521 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1522 if (status != 0)
1523 goto out;
1509 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1524 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1510 encode_compound_hdr(&xdr, &hdr); 1525 encode_compound_hdr(&xdr, &hdr);
1511 status = encode_putfh(&xdr, args->fh); 1526 status = encode_putfh(&xdr, args->fh);
@@ -1525,8 +1540,17 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
1525 struct compound_hdr hdr = { 1540 struct compound_hdr hdr = {
1526 .nops = 2, 1541 .nops = 2,
1527 }; 1542 };
1543 struct nfs_lock_opargs *opargs = args->u.lock;
1544 struct nfs_seqid *seqid;
1528 int status; 1545 int status;
1529 1546
1547 if (opargs->new_lock_owner)
1548 seqid = opargs->u.open_lock->lock_seqid;
1549 else
1550 seqid = opargs->u.exist_lock->seqid;
1551 status = nfs_wait_on_sequence(seqid, req->rq_task);
1552 if (status != 0)
1553 goto out;
1530 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1554 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1531 encode_compound_hdr(&xdr, &hdr); 1555 encode_compound_hdr(&xdr, &hdr);
1532 status = encode_putfh(&xdr, args->fh); 1556 status = encode_putfh(&xdr, args->fh);
@@ -1569,6 +1593,9 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lock
1569 }; 1593 };
1570 int status; 1594 int status;
1571 1595
1596 status = nfs_wait_on_sequence(args->u.locku->seqid, req->rq_task);
1597 if (status != 0)
1598 goto out;
1572 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1599 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1573 encode_compound_hdr(&xdr, &hdr); 1600 encode_compound_hdr(&xdr, &hdr);
1574 status = encode_putfh(&xdr, args->fh); 1601 status = encode_putfh(&xdr, args->fh);