hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/nfs/nfs4state.c
....@@ -49,6 +49,7 @@
4949 #include <linux/workqueue.h>
5050 #include <linux/bitops.h>
5151 #include <linux/jiffies.h>
52
+#include <linux/sched/mm.h>
5253
5354 #include <linux/sunrpc/clnt.h>
5455
....@@ -60,10 +61,13 @@
6061 #include "nfs4session.h"
6162 #include "pnfs.h"
6263 #include "netns.h"
64
+#include "nfs4trace.h"
6365
6466 #define NFSDBG_FACILITY NFSDBG_STATE
6567
6668 #define OPENOWNER_POOL_SIZE 8
69
+
70
+static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp);
6771
6872 const nfs4_stateid zero_stateid = {
6973 { .data = { 0 } },
....@@ -87,7 +91,26 @@
8791
8892 static DEFINE_MUTEX(nfs_clid_init_mutex);
8993
90
-int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
94
+static int nfs4_setup_state_renewal(struct nfs_client *clp)
95
+{
96
+ int status;
97
+ struct nfs_fsinfo fsinfo;
98
+
99
+ if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) {
100
+ nfs4_schedule_state_renewal(clp);
101
+ return 0;
102
+ }
103
+
104
+ status = nfs4_proc_get_lease_time(clp, &fsinfo);
105
+ if (status == 0) {
106
+ nfs4_set_lease_period(clp, fsinfo.lease_time * HZ);
107
+ nfs4_schedule_state_renewal(clp);
108
+ }
109
+
110
+ return status;
111
+}
112
+
113
+int nfs4_init_clientid(struct nfs_client *clp, const struct cred *cred)
91114 {
92115 struct nfs4_setclientid_res clid = {
93116 .clientid = clp->cl_clientid,
....@@ -114,7 +137,7 @@
114137 if (status != 0)
115138 goto out;
116139 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
117
- nfs4_schedule_state_renewal(clp);
140
+ nfs4_setup_state_renewal(clp);
118141 out:
119142 return status;
120143 }
....@@ -134,7 +157,7 @@
134157 */
135158 int nfs40_discover_server_trunking(struct nfs_client *clp,
136159 struct nfs_client **result,
137
- struct rpc_cred *cred)
160
+ const struct cred *cred)
138161 {
139162 struct nfs4_setclientid_res clid = {
140163 .clientid = clp->cl_clientid,
....@@ -168,32 +191,23 @@
168191 return status;
169192 }
170193
171
-struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
194
+const struct cred *nfs4_get_machine_cred(struct nfs_client *clp)
172195 {
173
- struct rpc_cred *cred = NULL;
174
-
175
- if (clp->cl_machine_cred != NULL)
176
- cred = get_rpccred(clp->cl_machine_cred);
177
- return cred;
196
+ return get_cred(rpc_machine_cred());
178197 }
179198
180199 static void nfs4_root_machine_cred(struct nfs_client *clp)
181200 {
182
- struct rpc_cred *cred, *new;
183201
184
- new = rpc_lookup_machine_cred(NULL);
185
- spin_lock(&clp->cl_lock);
186
- cred = clp->cl_machine_cred;
187
- clp->cl_machine_cred = new;
188
- spin_unlock(&clp->cl_lock);
189
- if (cred != NULL)
190
- put_rpccred(cred);
202
+ /* Force root creds instead of machine */
203
+ clp->cl_principal = NULL;
204
+ clp->cl_rpcclient->cl_principal = NULL;
191205 }
192206
193
-static struct rpc_cred *
207
+static const struct cred *
194208 nfs4_get_renew_cred_server_locked(struct nfs_server *server)
195209 {
196
- struct rpc_cred *cred = NULL;
210
+ const struct cred *cred = NULL;
197211 struct nfs4_state_owner *sp;
198212 struct rb_node *pos;
199213
....@@ -203,29 +217,30 @@
203217 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
204218 if (list_empty(&sp->so_states))
205219 continue;
206
- cred = get_rpccred(sp->so_cred);
220
+ cred = get_cred(sp->so_cred);
207221 break;
208222 }
209223 return cred;
210224 }
211225
212226 /**
213
- * nfs4_get_renew_cred_locked - Acquire credential for a renew operation
227
+ * nfs4_get_renew_cred - Acquire credential for a renew operation
214228 * @clp: client state handle
215229 *
216230 * Returns an rpc_cred with reference count bumped, or NULL.
217231 * Caller must hold clp->cl_lock.
218232 */
219
-struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
233
+const struct cred *nfs4_get_renew_cred(struct nfs_client *clp)
220234 {
221
- struct rpc_cred *cred = NULL;
235
+ const struct cred *cred = NULL;
222236 struct nfs_server *server;
223237
224238 /* Use machine credentials if available */
225
- cred = nfs4_get_machine_cred_locked(clp);
239
+ cred = nfs4_get_machine_cred(clp);
226240 if (cred != NULL)
227241 goto out;
228242
243
+ spin_lock(&clp->cl_lock);
229244 rcu_read_lock();
230245 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
231246 cred = nfs4_get_renew_cred_server_locked(server);
....@@ -233,6 +248,7 @@
233248 break;
234249 }
235250 rcu_read_unlock();
251
+ spin_unlock(&clp->cl_lock);
236252
237253 out:
238254 return cred;
....@@ -293,37 +309,16 @@
293309
294310 #if defined(CONFIG_NFS_V4_1)
295311
296
-static int nfs41_setup_state_renewal(struct nfs_client *clp)
297
-{
298
- int status;
299
- struct nfs_fsinfo fsinfo;
300
- unsigned long now;
301
-
302
- if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) {
303
- nfs4_schedule_state_renewal(clp);
304
- return 0;
305
- }
306
-
307
- now = jiffies;
308
- status = nfs4_proc_get_lease_time(clp, &fsinfo);
309
- if (status == 0) {
310
- nfs4_set_lease_period(clp, fsinfo.lease_time * HZ, now);
311
- nfs4_schedule_state_renewal(clp);
312
- }
313
-
314
- return status;
315
-}
316
-
317312 static void nfs41_finish_session_reset(struct nfs_client *clp)
318313 {
319314 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
320315 clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
321316 /* create_session negotiated new slot table */
322317 clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
323
- nfs41_setup_state_renewal(clp);
318
+ nfs4_setup_state_renewal(clp);
324319 }
325320
326
-int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
321
+int nfs41_init_clientid(struct nfs_client *clp, const struct cred *cred)
327322 {
328323 int status;
329324
....@@ -337,6 +332,8 @@
337332 status = nfs4_proc_create_session(clp, cred);
338333 if (status != 0)
339334 goto out;
335
+ if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R))
336
+ nfs4_state_start_reclaim_reboot(clp);
340337 nfs41_finish_session_reset(clp);
341338 nfs_mark_client_ready(clp, NFS_CS_READY);
342339 out:
....@@ -358,7 +355,7 @@
358355 */
359356 int nfs41_discover_server_trunking(struct nfs_client *clp,
360357 struct nfs_client **result,
361
- struct rpc_cred *cred)
358
+ const struct cred *cred)
362359 {
363360 int status;
364361
....@@ -396,32 +393,32 @@
396393 * nfs4_get_clid_cred - Acquire credential for a setclientid operation
397394 * @clp: client state handle
398395 *
399
- * Returns an rpc_cred with reference count bumped, or NULL.
396
+ * Returns a cred with reference count bumped, or NULL.
400397 */
401
-struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp)
398
+const struct cred *nfs4_get_clid_cred(struct nfs_client *clp)
402399 {
403
- struct rpc_cred *cred;
400
+ const struct cred *cred;
404401
405
- spin_lock(&clp->cl_lock);
406
- cred = nfs4_get_machine_cred_locked(clp);
407
- spin_unlock(&clp->cl_lock);
402
+ cred = nfs4_get_machine_cred(clp);
408403 return cred;
409404 }
410405
411406 static struct nfs4_state_owner *
412
-nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
407
+nfs4_find_state_owner_locked(struct nfs_server *server, const struct cred *cred)
413408 {
414409 struct rb_node **p = &server->state_owners.rb_node,
415410 *parent = NULL;
416411 struct nfs4_state_owner *sp;
412
+ int cmp;
417413
418414 while (*p != NULL) {
419415 parent = *p;
420416 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
417
+ cmp = cred_fscmp(cred, sp->so_cred);
421418
422
- if (cred < sp->so_cred)
419
+ if (cmp < 0)
423420 p = &parent->rb_left;
424
- else if (cred > sp->so_cred)
421
+ else if (cmp > 0)
425422 p = &parent->rb_right;
426423 else {
427424 if (!list_empty(&sp->so_lru))
....@@ -440,14 +437,16 @@
440437 struct rb_node **p = &server->state_owners.rb_node,
441438 *parent = NULL;
442439 struct nfs4_state_owner *sp;
440
+ int cmp;
443441
444442 while (*p != NULL) {
445443 parent = *p;
446444 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
445
+ cmp = cred_fscmp(new->so_cred, sp->so_cred);
447446
448
- if (new->so_cred < sp->so_cred)
447
+ if (cmp < 0)
449448 p = &parent->rb_left;
450
- else if (new->so_cred > sp->so_cred)
449
+ else if (cmp > 0)
451450 p = &parent->rb_right;
452451 else {
453452 if (!list_empty(&sp->so_lru))
....@@ -494,7 +493,7 @@
494493 */
495494 static struct nfs4_state_owner *
496495 nfs4_alloc_state_owner(struct nfs_server *server,
497
- struct rpc_cred *cred,
496
+ const struct cred *cred,
498497 gfp_t gfp_flags)
499498 {
500499 struct nfs4_state_owner *sp;
....@@ -509,13 +508,13 @@
509508 return NULL;
510509 }
511510 sp->so_server = server;
512
- sp->so_cred = get_rpccred(cred);
511
+ sp->so_cred = get_cred(cred);
513512 spin_lock_init(&sp->so_lock);
514513 INIT_LIST_HEAD(&sp->so_states);
515514 nfs4_init_seqid_counter(&sp->so_seqid);
516515 atomic_set(&sp->so_count, 1);
517516 INIT_LIST_HEAD(&sp->so_lru);
518
- seqcount_init(&sp->so_reclaim_seqcount);
517
+ seqcount_spinlock_init(&sp->so_reclaim_seqcount, &sp->so_lock);
519518 mutex_init(&sp->so_delegreturn_mutex);
520519 return sp;
521520 }
....@@ -538,7 +537,7 @@
538537 static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
539538 {
540539 nfs4_destroy_seqid_counter(&sp->so_seqid);
541
- put_rpccred(sp->so_cred);
540
+ put_cred(sp->so_cred);
542541 ida_simple_remove(&sp->so_server->openowner_id, sp->so_seqid.owner_id);
543542 kfree(sp);
544543 }
....@@ -572,11 +571,12 @@
572571 * nfs4_get_state_owner - Look up a state owner given a credential
573572 * @server: nfs_server to search
574573 * @cred: RPC credential to match
574
+ * @gfp_flags: allocation mode
575575 *
576576 * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL.
577577 */
578578 struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
579
- struct rpc_cred *cred,
579
+ const struct cred *cred,
580580 gfp_t gfp_flags)
581581 {
582582 struct nfs_client *clp = server->nfs_client;
....@@ -674,7 +674,7 @@
674674 state = kzalloc(sizeof(*state), GFP_NOFS);
675675 if (!state)
676676 return NULL;
677
- atomic_set(&state->count, 1);
677
+ refcount_set(&state->count, 1);
678678 INIT_LIST_HEAD(&state->lock_states);
679679 spin_lock_init(&state->state_lock);
680680 seqlock_init(&state->seqlock);
....@@ -703,12 +703,12 @@
703703 struct nfs_inode *nfsi = NFS_I(inode);
704704 struct nfs4_state *state;
705705
706
- list_for_each_entry(state, &nfsi->open_states, inode_states) {
706
+ list_for_each_entry_rcu(state, &nfsi->open_states, inode_states) {
707707 if (state->owner != owner)
708708 continue;
709709 if (!nfs4_valid_open_stateid(state))
710710 continue;
711
- if (atomic_inc_not_zero(&state->count))
711
+ if (refcount_inc_not_zero(&state->count))
712712 return state;
713713 }
714714 return NULL;
....@@ -717,7 +717,7 @@
717717 static void
718718 nfs4_free_open_state(struct nfs4_state *state)
719719 {
720
- kfree(state);
720
+ kfree_rcu(state, rcu_head);
721721 }
722722
723723 struct nfs4_state *
....@@ -726,9 +726,9 @@
726726 struct nfs4_state *state, *new;
727727 struct nfs_inode *nfsi = NFS_I(inode);
728728
729
- spin_lock(&inode->i_lock);
729
+ rcu_read_lock();
730730 state = __nfs4_find_state_byowner(inode, owner);
731
- spin_unlock(&inode->i_lock);
731
+ rcu_read_unlock();
732732 if (state)
733733 goto out;
734734 new = nfs4_alloc_open_state();
....@@ -739,9 +739,9 @@
739739 state = new;
740740 state->owner = owner;
741741 atomic_inc(&owner->so_count);
742
- list_add(&state->inode_states, &nfsi->open_states);
743742 ihold(inode);
744743 state->inode = inode;
744
+ list_add_rcu(&state->inode_states, &nfsi->open_states);
745745 spin_unlock(&inode->i_lock);
746746 /* Note: The reclaim code dictates that we add stateless
747747 * and read-only stateids to the end of the list */
....@@ -762,13 +762,14 @@
762762 struct inode *inode = state->inode;
763763 struct nfs4_state_owner *owner = state->owner;
764764
765
- if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
765
+ if (!refcount_dec_and_lock(&state->count, &owner->so_lock))
766766 return;
767767 spin_lock(&inode->i_lock);
768
- list_del(&state->inode_states);
768
+ list_del_rcu(&state->inode_states);
769769 list_del(&state->open_states);
770770 spin_unlock(&inode->i_lock);
771771 spin_unlock(&owner->so_lock);
772
+ nfs4_inode_return_delegation_on_close(inode);
772773 iput(inode);
773774 nfs4_free_open_state(state);
774775 nfs4_put_state_owner(owner);
....@@ -1019,22 +1020,6 @@
10191020 return ret;
10201021 }
10211022
1022
-bool nfs4_refresh_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
1023
-{
1024
- bool ret;
1025
- int seq;
1026
-
1027
- do {
1028
- ret = false;
1029
- seq = read_seqbegin(&state->seqlock);
1030
- if (nfs4_state_match_open_stateid_other(state, dst)) {
1031
- dst->seqid = state->open_stateid.seqid;
1032
- ret = true;
1033
- }
1034
- } while (read_seqretry(&state->seqlock, seq));
1035
- return ret;
1036
-}
1037
-
10381023 bool nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
10391024 {
10401025 bool ret;
....@@ -1060,7 +1045,7 @@
10601045 */
10611046 int nfs4_select_rw_stateid(struct nfs4_state *state,
10621047 fmode_t fmode, const struct nfs_lock_context *l_ctx,
1063
- nfs4_stateid *dst, struct rpc_cred **cred)
1048
+ nfs4_stateid *dst, const struct cred **cred)
10641049 {
10651050 int ret;
10661051
....@@ -1083,8 +1068,7 @@
10831068 * choose to use.
10841069 */
10851070 goto out;
1086
- nfs4_copy_open_stateid(dst, state);
1087
- ret = 0;
1071
+ ret = nfs4_copy_open_stateid(dst, state) ? 0 : -EAGAIN;
10881072 out:
10891073 if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41))
10901074 dst->seqid = 0;
....@@ -1155,7 +1139,7 @@
11551139 case -NFS4ERR_MOVED:
11561140 /* Non-seqid mutating errors */
11571141 return;
1158
- };
1142
+ }
11591143 /*
11601144 * Note: no locking needed as we are guaranteed to be first
11611145 * on the sequence list
....@@ -1228,10 +1212,23 @@
12281212 {
12291213 struct task_struct *task;
12301214 char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1];
1215
+ struct rpc_clnt *clnt = clp->cl_rpcclient;
1216
+ bool swapon = false;
12311217
12321218 set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
1219
+
1220
+ if (atomic_read(&clnt->cl_swapper)) {
1221
+ swapon = !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE,
1222
+ &clp->cl_state);
1223
+ if (!swapon) {
1224
+ wake_up_var(&clp->cl_state);
1225
+ return;
1226
+ }
1227
+ }
1228
+
12331229 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
12341230 return;
1231
+
12351232 __module_get(THIS_MODULE);
12361233 refcount_inc(&clp->cl_count);
12371234
....@@ -1246,6 +1243,10 @@
12461243 if (IS_ERR(task)) {
12471244 printk(KERN_ERR "%s: kthread_run: %ld\n",
12481245 __func__, PTR_ERR(task));
1246
+ if (!nfs_client_init_is_complete(clp))
1247
+ nfs_mark_client_ready(clp, PTR_ERR(task));
1248
+ if (swapon)
1249
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
12491250 nfs4_clear_state_manager_bit(clp);
12501251 nfs_put_client(clp);
12511252 module_put(THIS_MODULE);
....@@ -1428,7 +1429,7 @@
14281429 list_for_each_entry(pos, &state->lock_states, ls_locks) {
14291430 if (!test_bit(NFS_LOCK_INITIALIZED, &pos->ls_flags))
14301431 continue;
1431
- if (nfs4_stateid_match_other(&pos->ls_stateid, stateid))
1432
+ if (nfs4_stateid_match_or_older(&pos->ls_stateid, stateid))
14321433 return pos;
14331434 }
14341435 return NULL;
....@@ -1457,17 +1458,18 @@
14571458 struct nfs4_state *state;
14581459 bool found = false;
14591460
1460
- spin_lock(&inode->i_lock);
1461
- list_for_each_entry(ctx, &nfsi->open_files, list) {
1461
+ rcu_read_lock();
1462
+ list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
14621463 state = ctx->state;
14631464 if (state == NULL)
14641465 continue;
1465
- if (nfs4_stateid_match_other(&state->stateid, stateid) &&
1466
+ if (nfs4_stateid_match_or_older(&state->stateid, stateid) &&
14661467 nfs4_state_mark_reclaim_nograce(clp, state)) {
14671468 found = true;
14681469 continue;
14691470 }
1470
- if (nfs4_stateid_match_other(&state->open_stateid, stateid) &&
1471
+ if (test_bit(NFS_OPEN_STATE, &state->flags) &&
1472
+ nfs4_stateid_match_or_older(&state->open_stateid, stateid) &&
14711473 nfs4_state_mark_reclaim_nograce(clp, state)) {
14721474 found = true;
14731475 continue;
....@@ -1476,32 +1478,34 @@
14761478 nfs4_state_mark_reclaim_nograce(clp, state))
14771479 found = true;
14781480 }
1479
- spin_unlock(&inode->i_lock);
1481
+ rcu_read_unlock();
14801482
14811483 nfs_inode_find_delegation_state_and_recover(inode, stateid);
14821484 if (found)
14831485 nfs4_schedule_state_manager(clp);
14841486 }
14851487
1486
-static void nfs4_state_mark_open_context_bad(struct nfs4_state *state)
1488
+static void nfs4_state_mark_open_context_bad(struct nfs4_state *state, int err)
14871489 {
14881490 struct inode *inode = state->inode;
14891491 struct nfs_inode *nfsi = NFS_I(inode);
14901492 struct nfs_open_context *ctx;
14911493
1492
- spin_lock(&inode->i_lock);
1493
- list_for_each_entry(ctx, &nfsi->open_files, list) {
1494
+ rcu_read_lock();
1495
+ list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
14941496 if (ctx->state != state)
14951497 continue;
14961498 set_bit(NFS_CONTEXT_BAD, &ctx->flags);
1499
+ pr_warn("NFSv4: state recovery failed for open file %pd2, "
1500
+ "error = %d\n", ctx->dentry, err);
14971501 }
1498
- spin_unlock(&inode->i_lock);
1502
+ rcu_read_unlock();
14991503 }
15001504
15011505 static void nfs4_state_mark_recovery_failed(struct nfs4_state *state, int error)
15021506 {
15031507 set_bit(NFS_STATE_RECOVERY_FAILED, &state->flags);
1504
- nfs4_state_mark_open_context_bad(state);
1508
+ nfs4_state_mark_open_context_bad(state, error);
15051509 }
15061510
15071511
....@@ -1532,6 +1536,7 @@
15321536 switch (status) {
15331537 case 0:
15341538 break;
1539
+ case -ETIMEDOUT:
15351540 case -ESTALE:
15361541 case -NFS4ERR_ADMIN_REVOKED:
15371542 case -NFS4ERR_STALE_STATEID:
....@@ -1547,7 +1552,7 @@
15471552 default:
15481553 pr_err("NFS: %s: unhandled error %d\n",
15491554 __func__, status);
1550
- /* Fall through */
1555
+ fallthrough;
15511556 case -ENOMEM:
15521557 case -NFS4ERR_DENIED:
15531558 case -NFS4ERR_RECLAIM_BAD:
....@@ -1569,11 +1574,84 @@
15691574 return status;
15701575 }
15711576
1577
+#ifdef CONFIG_NFS_V4_2
1578
+static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state *state)
1579
+{
1580
+ struct nfs4_copy_state *copy;
1581
+
1582
+ if (!test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
1583
+ !test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags))
1584
+ return;
1585
+
1586
+ spin_lock(&sp->so_server->nfs_client->cl_lock);
1587
+ list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
1588
+ if ((test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags) &&
1589
+ !nfs4_stateid_match_other(&state->stateid,
1590
+ &copy->parent_dst_state->stateid)))
1591
+ continue;
1592
+ copy->flags = 1;
1593
+ if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
1594
+ &state->flags)) {
1595
+ clear_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags);
1596
+ complete(&copy->completion);
1597
+ }
1598
+ }
1599
+ list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) {
1600
+ if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) &&
1601
+ !nfs4_stateid_match_other(&state->stateid,
1602
+ &copy->parent_src_state->stateid)))
1603
+ continue;
1604
+ copy->flags = 1;
1605
+ if (test_and_clear_bit(NFS_CLNT_DST_SSC_COPY_STATE,
1606
+ &state->flags))
1607
+ complete(&copy->completion);
1608
+ }
1609
+ spin_unlock(&sp->so_server->nfs_client->cl_lock);
1610
+}
1611
+#else /* !CONFIG_NFS_V4_2 */
1612
+static inline void nfs42_complete_copies(struct nfs4_state_owner *sp,
1613
+ struct nfs4_state *state)
1614
+{
1615
+}
1616
+#endif /* CONFIG_NFS_V4_2 */
1617
+
1618
+static int __nfs4_reclaim_open_state(struct nfs4_state_owner *sp, struct nfs4_state *state,
1619
+ const struct nfs4_state_recovery_ops *ops)
1620
+{
1621
+ struct nfs4_lock_state *lock;
1622
+ int status;
1623
+
1624
+ status = ops->recover_open(sp, state);
1625
+ if (status < 0)
1626
+ return status;
1627
+
1628
+ status = nfs4_reclaim_locks(state, ops);
1629
+ if (status < 0)
1630
+ return status;
1631
+
1632
+ if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {
1633
+ spin_lock(&state->state_lock);
1634
+ list_for_each_entry(lock, &state->lock_states, ls_locks) {
1635
+ trace_nfs4_state_lock_reclaim(state, lock);
1636
+ if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
1637
+ pr_warn_ratelimited("NFS: %s: Lock reclaim failed!\n", __func__);
1638
+ }
1639
+ spin_unlock(&state->state_lock);
1640
+ }
1641
+
1642
+ nfs42_complete_copies(sp, state);
1643
+ clear_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags);
1644
+ return status;
1645
+}
1646
+
15721647 static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs4_state_recovery_ops *ops)
15731648 {
15741649 struct nfs4_state *state;
1575
- struct nfs4_lock_state *lock;
1650
+ unsigned int loop = 0;
15761651 int status = 0;
1652
+#ifdef CONFIG_NFS_V4_2
1653
+ bool found_ssc_copy_state = false;
1654
+#endif /* CONFIG_NFS_V4_2 */
15771655
15781656 /* Note: we rely on the sp->so_states list being ordered
15791657 * so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
....@@ -1593,79 +1671,60 @@
15931671 continue;
15941672 if (state->state == 0)
15951673 continue;
1596
- atomic_inc(&state->count);
1597
- spin_unlock(&sp->so_lock);
1598
- status = ops->recover_open(sp, state);
1599
- if (status >= 0) {
1600
- status = nfs4_reclaim_locks(state, ops);
1601
- if (status >= 0) {
1602
- if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {
1603
- spin_lock(&state->state_lock);
1604
- list_for_each_entry(lock, &state->lock_states, ls_locks) {
1605
- if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
1606
- pr_warn_ratelimited("NFS: "
1607
- "%s: Lock reclaim "
1608
- "failed!\n", __func__);
1609
- }
1610
- spin_unlock(&state->state_lock);
1611
- }
1612
- clear_bit(NFS_STATE_RECLAIM_NOGRACE,
1613
- &state->flags);
16141674 #ifdef CONFIG_NFS_V4_2
1615
- if (test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags)) {
1616
- struct nfs4_copy_state *copy;
1617
-
1618
- spin_lock(&sp->so_server->nfs_client->cl_lock);
1619
- list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
1620
- if (memcmp(&state->stateid.other, &copy->parent_state->stateid.other, NFS4_STATEID_SIZE))
1621
- continue;
1622
- copy->flags = 1;
1623
- complete(&copy->completion);
1624
- printk("AGLO: server rebooted waking up the copy\n");
1625
- break;
1626
- }
1627
- spin_unlock(&sp->so_server->nfs_client->cl_lock);
1628
- }
1629
-#endif /* CONFIG_NFS_V4_2 */
1630
- nfs4_put_open_state(state);
1631
- spin_lock(&sp->so_lock);
1632
- goto restart;
1633
- }
1675
+ if (test_bit(NFS_SRV_SSC_COPY_STATE, &state->flags)) {
1676
+ nfs4_state_mark_recovery_failed(state, -EIO);
1677
+ found_ssc_copy_state = true;
1678
+ continue;
16341679 }
1680
+#endif /* CONFIG_NFS_V4_2 */
1681
+ refcount_inc(&state->count);
1682
+ spin_unlock(&sp->so_lock);
1683
+ status = __nfs4_reclaim_open_state(sp, state, ops);
1684
+
16351685 switch (status) {
1636
- default:
1637
- printk(KERN_ERR "NFS: %s: unhandled error %d\n",
1638
- __func__, status);
1639
- /* Fall through */
1640
- case -ENOENT:
1641
- case -ENOMEM:
1642
- case -EACCES:
1643
- case -EROFS:
1644
- case -EIO:
1645
- case -ESTALE:
1646
- /* Open state on this file cannot be recovered */
1647
- nfs4_state_mark_recovery_failed(state, status);
1686
+ default:
1687
+ if (status >= 0) {
1688
+ loop = 0;
16481689 break;
1649
- case -EAGAIN:
1650
- ssleep(1);
1651
- /* Fall through */
1652
- case -NFS4ERR_ADMIN_REVOKED:
1653
- case -NFS4ERR_STALE_STATEID:
1654
- case -NFS4ERR_OLD_STATEID:
1655
- case -NFS4ERR_BAD_STATEID:
1656
- case -NFS4ERR_RECLAIM_BAD:
1657
- case -NFS4ERR_RECLAIM_CONFLICT:
1658
- nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
1690
+ }
1691
+ printk(KERN_ERR "NFS: %s: unhandled error %d\n", __func__, status);
1692
+ fallthrough;
1693
+ case -ENOENT:
1694
+ case -ENOMEM:
1695
+ case -EACCES:
1696
+ case -EROFS:
1697
+ case -EIO:
1698
+ case -ESTALE:
1699
+ /* Open state on this file cannot be recovered */
1700
+ nfs4_state_mark_recovery_failed(state, status);
1701
+ break;
1702
+ case -EAGAIN:
1703
+ ssleep(1);
1704
+ if (loop++ < 10) {
1705
+ set_bit(ops->state_flag_bit, &state->flags);
16591706 break;
1660
- case -NFS4ERR_EXPIRED:
1661
- case -NFS4ERR_NO_GRACE:
1662
- nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
1663
- case -NFS4ERR_STALE_CLIENTID:
1664
- case -NFS4ERR_BADSESSION:
1665
- case -NFS4ERR_BADSLOT:
1666
- case -NFS4ERR_BAD_HIGH_SLOT:
1667
- case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1668
- goto out_err;
1707
+ }
1708
+ fallthrough;
1709
+ case -NFS4ERR_ADMIN_REVOKED:
1710
+ case -NFS4ERR_STALE_STATEID:
1711
+ case -NFS4ERR_OLD_STATEID:
1712
+ case -NFS4ERR_BAD_STATEID:
1713
+ case -NFS4ERR_RECLAIM_BAD:
1714
+ case -NFS4ERR_RECLAIM_CONFLICT:
1715
+ nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
1716
+ break;
1717
+ case -NFS4ERR_EXPIRED:
1718
+ case -NFS4ERR_NO_GRACE:
1719
+ nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
1720
+ fallthrough;
1721
+ case -NFS4ERR_STALE_CLIENTID:
1722
+ case -NFS4ERR_BADSESSION:
1723
+ case -NFS4ERR_BADSLOT:
1724
+ case -NFS4ERR_BAD_HIGH_SLOT:
1725
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1726
+ case -ETIMEDOUT:
1727
+ goto out_err;
16691728 }
16701729 nfs4_put_open_state(state);
16711730 spin_lock(&sp->so_lock);
....@@ -1673,6 +1732,10 @@
16731732 }
16741733 raw_write_seqcount_end(&sp->so_reclaim_seqcount);
16751734 spin_unlock(&sp->so_lock);
1735
+#ifdef CONFIG_NFS_V4_2
1736
+ if (found_ssc_copy_state)
1737
+ return -EIO;
1738
+#endif /* CONFIG_NFS_V4_2 */
16761739 return 0;
16771740 out_err:
16781741 nfs4_put_open_state(state);
....@@ -1735,6 +1798,7 @@
17351798
17361799 static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
17371800 {
1801
+ set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
17381802 /* Mark all delegations for reclaim */
17391803 nfs_delegation_mark_reclaim(clp);
17401804 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
....@@ -1742,7 +1806,7 @@
17421806
17431807 static int nfs4_reclaim_complete(struct nfs_client *clp,
17441808 const struct nfs4_state_recovery_ops *ops,
1745
- struct rpc_cred *cred)
1809
+ const struct cred *cred)
17461810 {
17471811 /* Notify the server we're done reclaiming our state */
17481812 if (ops->reclaim_complete)
....@@ -1793,7 +1857,7 @@
17931857 static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
17941858 {
17951859 const struct nfs4_state_recovery_ops *ops;
1796
- struct rpc_cred *cred;
1860
+ const struct cred *cred;
17971861 int err;
17981862
17991863 if (!nfs4_state_clear_reclaim_reboot(clp))
....@@ -1801,7 +1865,7 @@
18011865 ops = clp->cl_mvops->reboot_recovery_ops;
18021866 cred = nfs4_get_clid_cred(clp);
18031867 err = nfs4_reclaim_complete(clp, ops, cred);
1804
- put_rpccred(cred);
1868
+ put_cred(cred);
18051869 if (err == -NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
18061870 set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
18071871 }
....@@ -1815,38 +1879,38 @@
18151879 static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
18161880 {
18171881 switch (error) {
1818
- case 0:
1819
- break;
1820
- case -NFS4ERR_CB_PATH_DOWN:
1821
- nfs40_handle_cb_pathdown(clp);
1822
- break;
1823
- case -NFS4ERR_NO_GRACE:
1824
- nfs4_state_end_reclaim_reboot(clp);
1825
- break;
1826
- case -NFS4ERR_STALE_CLIENTID:
1827
- set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1828
- nfs4_state_start_reclaim_reboot(clp);
1829
- break;
1830
- case -NFS4ERR_EXPIRED:
1831
- set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1832
- nfs4_state_start_reclaim_nograce(clp);
1833
- break;
1834
- case -NFS4ERR_BADSESSION:
1835
- case -NFS4ERR_BADSLOT:
1836
- case -NFS4ERR_BAD_HIGH_SLOT:
1837
- case -NFS4ERR_DEADSESSION:
1838
- case -NFS4ERR_SEQ_FALSE_RETRY:
1839
- case -NFS4ERR_SEQ_MISORDERED:
1840
- set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
1841
- /* Zero session reset errors */
1842
- break;
1843
- case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1844
- set_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
1845
- break;
1846
- default:
1847
- dprintk("%s: failed to handle error %d for server %s\n",
1848
- __func__, error, clp->cl_hostname);
1849
- return error;
1882
+ case 0:
1883
+ break;
1884
+ case -NFS4ERR_CB_PATH_DOWN:
1885
+ nfs40_handle_cb_pathdown(clp);
1886
+ break;
1887
+ case -NFS4ERR_NO_GRACE:
1888
+ nfs4_state_end_reclaim_reboot(clp);
1889
+ break;
1890
+ case -NFS4ERR_STALE_CLIENTID:
1891
+ set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1892
+ nfs4_state_start_reclaim_reboot(clp);
1893
+ break;
1894
+ case -NFS4ERR_EXPIRED:
1895
+ set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1896
+ nfs4_state_start_reclaim_nograce(clp);
1897
+ break;
1898
+ case -NFS4ERR_BADSESSION:
1899
+ case -NFS4ERR_BADSLOT:
1900
+ case -NFS4ERR_BAD_HIGH_SLOT:
1901
+ case -NFS4ERR_DEADSESSION:
1902
+ case -NFS4ERR_SEQ_FALSE_RETRY:
1903
+ case -NFS4ERR_SEQ_MISORDERED:
1904
+ set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
1905
+ /* Zero session reset errors */
1906
+ break;
1907
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1908
+ set_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
1909
+ break;
1910
+ default:
1911
+ dprintk("%s: failed to handle error %d for server %s\n",
1912
+ __func__, error, clp->cl_hostname);
1913
+ return error;
18501914 }
18511915 dprintk("%s: handled error %d for server %s\n", __func__, error,
18521916 clp->cl_hostname);
....@@ -1899,7 +1963,7 @@
18991963
19001964 static int nfs4_check_lease(struct nfs_client *clp)
19011965 {
1902
- struct rpc_cred *cred;
1966
+ const struct cred *cred;
19031967 const struct nfs4_state_maintenance_ops *ops =
19041968 clp->cl_mvops->state_renewal_ops;
19051969 int status;
....@@ -1907,9 +1971,7 @@
19071971 /* Is the client already known to have an expired lease? */
19081972 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
19091973 return 0;
1910
- spin_lock(&clp->cl_lock);
1911
- cred = ops->get_state_renewal_cred_locked(clp);
1912
- spin_unlock(&clp->cl_lock);
1974
+ cred = ops->get_state_renewal_cred(clp);
19131975 if (cred == NULL) {
19141976 cred = nfs4_get_clid_cred(clp);
19151977 status = -ENOKEY;
....@@ -1917,7 +1979,7 @@
19171979 goto out;
19181980 }
19191981 status = ops->renew_lease(clp, cred);
1920
- put_rpccred(cred);
1982
+ put_cred(cred);
19211983 if (status == -ETIMEDOUT) {
19221984 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
19231985 return 0;
....@@ -1951,7 +2013,6 @@
19512013 return -EPERM;
19522014 case -EACCES:
19532015 case -NFS4ERR_DELAY:
1954
- case -ETIMEDOUT:
19552016 case -EAGAIN:
19562017 ssleep(1);
19572018 break;
....@@ -1977,7 +2038,7 @@
19772038
19782039 static int nfs4_establish_lease(struct nfs_client *clp)
19792040 {
1980
- struct rpc_cred *cred;
2041
+ const struct cred *cred;
19812042 const struct nfs4_state_recovery_ops *ops =
19822043 clp->cl_mvops->reboot_recovery_ops;
19832044 int status;
....@@ -1989,7 +2050,7 @@
19892050 if (cred == NULL)
19902051 return -ENOENT;
19912052 status = ops->establish_clid(clp, cred);
1992
- put_rpccred(cred);
2053
+ put_cred(cred);
19932054 if (status != 0)
19942055 return status;
19952056 pnfs_destroy_all_layouts(clp);
....@@ -2036,7 +2097,7 @@
20362097 *
20372098 * Returns zero or a negative NFS4ERR status code.
20382099 */
2039
-static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred)
2100
+static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred)
20402101 {
20412102 struct nfs_client *clp = server->nfs_client;
20422103 struct nfs4_fs_locations *locations = NULL;
....@@ -2076,8 +2137,10 @@
20762137 }
20772138
20782139 status = nfs4_begin_drain_session(clp);
2079
- if (status != 0)
2080
- return status;
2140
+ if (status != 0) {
2141
+ result = status;
2142
+ goto out;
2143
+ }
20812144
20822145 status = nfs4_replace_transport(server, locations);
20832146 if (status != 0) {
....@@ -2109,14 +2172,12 @@
21092172 const struct nfs4_state_maintenance_ops *ops =
21102173 clp->cl_mvops->state_renewal_ops;
21112174 struct nfs_server *server;
2112
- struct rpc_cred *cred;
2175
+ const struct cred *cred;
21132176
21142177 dprintk("%s: migration reported on \"%s\"\n", __func__,
21152178 clp->cl_hostname);
21162179
2117
- spin_lock(&clp->cl_lock);
2118
- cred = ops->get_state_renewal_cred_locked(clp);
2119
- spin_unlock(&clp->cl_lock);
2180
+ cred = ops->get_state_renewal_cred(clp);
21202181 if (cred == NULL)
21212182 return -NFS4ERR_NOENT;
21222183
....@@ -2137,13 +2198,13 @@
21372198 rcu_read_unlock();
21382199 status = nfs4_try_migration(server, cred);
21392200 if (status < 0) {
2140
- put_rpccred(cred);
2201
+ put_cred(cred);
21412202 return status;
21422203 }
21432204 goto restart;
21442205 }
21452206 rcu_read_unlock();
2146
- put_rpccred(cred);
2207
+ put_cred(cred);
21472208 return 0;
21482209 }
21492210
....@@ -2157,14 +2218,12 @@
21572218 const struct nfs4_state_maintenance_ops *ops =
21582219 clp->cl_mvops->state_renewal_ops;
21592220 struct nfs_server *server;
2160
- struct rpc_cred *cred;
2221
+ const struct cred *cred;
21612222
21622223 dprintk("%s: lease moved reported on \"%s\"\n", __func__,
21632224 clp->cl_hostname);
21642225
2165
- spin_lock(&clp->cl_lock);
2166
- cred = ops->get_state_renewal_cred_locked(clp);
2167
- spin_unlock(&clp->cl_lock);
2226
+ cred = ops->get_state_renewal_cred(clp);
21682227 if (cred == NULL)
21692228 return -NFS4ERR_NOENT;
21702229
....@@ -2192,7 +2251,7 @@
21922251 rcu_read_unlock();
21932252
21942253 out:
2195
- put_rpccred(cred);
2254
+ put_cred(cred);
21962255 return 0;
21972256 }
21982257
....@@ -2215,7 +2274,7 @@
22152274 const struct nfs4_state_recovery_ops *ops =
22162275 clp->cl_mvops->reboot_recovery_ops;
22172276 struct rpc_clnt *clnt;
2218
- struct rpc_cred *cred;
2277
+ const struct cred *cred;
22192278 int i, status;
22202279
22212280 dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);
....@@ -2231,7 +2290,7 @@
22312290 goto out_unlock;
22322291
22332292 status = ops->detect_trunking(clp, result, cred);
2234
- put_rpccred(cred);
2293
+ put_cred(cred);
22352294 switch (status) {
22362295 case 0:
22372296 case -EINTR:
....@@ -2240,11 +2299,11 @@
22402299 case -ETIMEDOUT:
22412300 if (clnt->cl_softrtry)
22422301 break;
2243
- /* Fall through */
2302
+ fallthrough;
22442303 case -NFS4ERR_DELAY:
22452304 case -EAGAIN:
22462305 ssleep(1);
2247
- /* Fall through */
2306
+ fallthrough;
22482307 case -NFS4ERR_STALE_CLIENTID:
22492308 dprintk("NFS: %s after status %d, retrying\n",
22502309 __func__, status);
....@@ -2256,7 +2315,7 @@
22562315 }
22572316 if (clnt->cl_auth->au_flavor == RPC_AUTH_UNIX)
22582317 break;
2259
- /* Fall through */
2318
+ fallthrough;
22602319 case -NFS4ERR_CLID_INUSE:
22612320 case -NFS4ERR_WRONGSEC:
22622321 /* No point in retrying if we already used RPC_AUTH_UNIX */
....@@ -2362,8 +2421,7 @@
23622421 {
23632422 /* FIXME: For now, we destroy all layouts. */
23642423 pnfs_destroy_all_layouts(clp);
2365
- /* FIXME: For now, we test all delegations+open state+locks. */
2366
- nfs41_handle_some_state_revoked(clp);
2424
+ nfs_test_expired_all_delegations(clp);
23672425 dprintk("%s: Recallable state revoked on server %s!\n", __func__,
23682426 clp->cl_hostname);
23692427 }
....@@ -2422,7 +2480,7 @@
24222480
24232481 static int nfs4_reset_session(struct nfs_client *clp)
24242482 {
2425
- struct rpc_cred *cred;
2483
+ const struct cred *cred;
24262484 int status;
24272485
24282486 if (!nfs4_has_session(clp))
....@@ -2460,14 +2518,13 @@
24602518 dprintk("%s: session reset was successful for server %s!\n",
24612519 __func__, clp->cl_hostname);
24622520 out:
2463
- if (cred)
2464
- put_rpccred(cred);
2521
+ put_cred(cred);
24652522 return status;
24662523 }
24672524
24682525 static int nfs4_bind_conn_to_session(struct nfs_client *clp)
24692526 {
2470
- struct rpc_cred *cred;
2527
+ const struct cred *cred;
24712528 int ret;
24722529
24732530 if (!nfs4_has_session(clp))
....@@ -2477,8 +2534,7 @@
24772534 return ret;
24782535 cred = nfs4_get_clid_cred(clp);
24792536 ret = nfs4_proc_bind_conn_to_session(clp, cred);
2480
- if (cred)
2481
- put_rpccred(cred);
2537
+ put_cred(cred);
24822538 clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
24832539 switch (ret) {
24842540 case 0:
....@@ -2494,6 +2550,21 @@
24942550 }
24952551 return 0;
24962552 }
2553
+
2554
+static void nfs4_layoutreturn_any_run(struct nfs_client *clp)
2555
+{
2556
+ int iomode = 0;
2557
+
2558
+ if (test_and_clear_bit(NFS4CLNT_RECALL_ANY_LAYOUT_READ, &clp->cl_state))
2559
+ iomode += IOMODE_READ;
2560
+ if (test_and_clear_bit(NFS4CLNT_RECALL_ANY_LAYOUT_RW, &clp->cl_state))
2561
+ iomode += IOMODE_RW;
2562
+ /* Note: IOMODE_READ + IOMODE_RW == IOMODE_ANY */
2563
+ if (iomode) {
2564
+ pnfs_layout_return_unused_byclid(clp, iomode);
2565
+ set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
2566
+ }
2567
+}
24972568 #else /* CONFIG_NFS_V4_1 */
24982569 static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
24992570
....@@ -2501,15 +2572,28 @@
25012572 {
25022573 return 0;
25032574 }
2575
+
2576
+static void nfs4_layoutreturn_any_run(struct nfs_client *clp)
2577
+{
2578
+}
25042579 #endif /* CONFIG_NFS_V4_1 */
25052580
25062581 static void nfs4_state_manager(struct nfs_client *clp)
25072582 {
2583
+ unsigned int memflags;
25082584 int status = 0;
25092585 const char *section = "", *section_sep = "";
25102586
2587
+ /*
2588
+ * State recovery can deadlock if the direct reclaim code tries
2589
+ * start NFS writeback. So ensure memory allocations are all
2590
+ * GFP_NOFS.
2591
+ */
2592
+ memflags = memalloc_nofs_save();
2593
+
25112594 /* Ensure exclusive access to NFSv4 state */
25122595 do {
2596
+ trace_nfs4_state_mgr(clp);
25132597 clear_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
25142598 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
25152599 section = "purge state";
....@@ -2580,6 +2664,7 @@
25802664 if (status < 0)
25812665 goto out_error;
25822666 nfs4_state_end_reclaim_reboot(clp);
2667
+ continue;
25832668 }
25842669
25852670 /* Detect expired delegations... */
....@@ -2590,7 +2675,7 @@
25902675 }
25912676
25922677 /* Now recover expired state... */
2593
- if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
2678
+ if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
25942679 section = "reclaim nograce";
25952680 status = nfs4_do_reclaim(clp,
25962681 clp->cl_mvops->nograce_recovery_ops);
....@@ -2598,35 +2683,44 @@
25982683 continue;
25992684 if (status < 0)
26002685 goto out_error;
2686
+ clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
26012687 }
26022688
2689
+ memalloc_nofs_restore(memflags);
26032690 nfs4_end_drain_session(clp);
26042691 nfs4_clear_state_manager_bit(clp);
26052692
2606
- if (!test_and_set_bit(NFS4CLNT_DELEGRETURN_RUNNING, &clp->cl_state)) {
2693
+ if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
2694
+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING,
2695
+ &clp->cl_state)) {
2696
+ memflags = memalloc_nofs_save();
2697
+ continue;
2698
+ }
2699
+
2700
+ if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) {
26072701 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
26082702 nfs_client_return_marked_delegations(clp);
26092703 set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state);
26102704 }
2611
- clear_bit(NFS4CLNT_DELEGRETURN_RUNNING, &clp->cl_state);
2705
+ nfs4_layoutreturn_any_run(clp);
2706
+ clear_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state);
26122707 }
26132708
2614
- /* Did we race with an attempt to give us more work? */
2615
- if (!test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state))
2616
- return;
2617
- if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
2618
- return;
2709
+ return;
2710
+
26192711 } while (refcount_read(&clp->cl_count) > 1 && !signalled());
26202712 goto out_drain;
26212713
26222714 out_error:
26232715 if (strlen(section))
26242716 section_sep = ": ";
2717
+ trace_nfs4_state_mgr_failed(clp, section, status);
26252718 pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s"
26262719 " with error %d\n", section_sep, section,
26272720 clp->cl_hostname, -status);
26282721 ssleep(1);
26292722 out_drain:
2723
+ memalloc_nofs_restore(memflags);
26302724 nfs4_end_drain_session(clp);
26312725 nfs4_clear_state_manager_bit(clp);
26322726 }
....@@ -2634,9 +2728,34 @@
26342728 static int nfs4_run_state_manager(void *ptr)
26352729 {
26362730 struct nfs_client *clp = ptr;
2731
+ struct rpc_clnt *cl = clp->cl_rpcclient;
2732
+
2733
+ while (cl != cl->cl_parent)
2734
+ cl = cl->cl_parent;
26372735
26382736 allow_signal(SIGKILL);
2737
+again:
26392738 nfs4_state_manager(clp);
2739
+
2740
+ if (test_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) &&
2741
+ !test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) {
2742
+ wait_var_event_interruptible(&clp->cl_state,
2743
+ test_bit(NFS4CLNT_RUN_MANAGER,
2744
+ &clp->cl_state));
2745
+ if (!atomic_read(&cl->cl_swapper))
2746
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
2747
+ if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
2748
+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state))
2749
+ goto again;
2750
+ /* Either no longer a swapper, or were signalled */
2751
+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
2752
+ }
2753
+
2754
+ if (refcount_read(&clp->cl_count) > 1 && !signalled() &&
2755
+ test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) &&
2756
+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state))
2757
+ goto again;
2758
+
26402759 nfs_put_client(clp);
26412760 module_put_and_exit(0);
26422761 return 0;