diff options
-rw-r--r-- | fs/nfsd/nfs4callback.c | 74 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 28 |
2 files changed, 52 insertions, 50 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index b88b207d75d9..f4fab69a8c30 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -494,6 +494,49 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
494 | do_probe_callback(clp); | 494 | do_probe_callback(clp); |
495 | } | 495 | } |
496 | 496 | ||
497 | static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) | ||
498 | { | ||
499 | struct nfs4_delegation *dp = calldata; | ||
500 | struct nfs4_client *clp = dp->dl_client; | ||
501 | |||
502 | switch (task->tk_status) { | ||
503 | case -EIO: | ||
504 | /* Network partition? */ | ||
505 | atomic_set(&clp->cl_cb_conn.cb_set, 0); | ||
506 | warn_no_callback_path(clp, task->tk_status); | ||
507 | case -EBADHANDLE: | ||
508 | case -NFS4ERR_BAD_STATEID: | ||
509 | /* Race: client probably got cb_recall | ||
510 | * before open reply granting delegation */ | ||
511 | break; | ||
512 | default: | ||
513 | /* success, or error we can't handle */ | ||
514 | return; | ||
515 | } | ||
516 | if (dp->dl_retries--) { | ||
517 | rpc_delay(task, 2*HZ); | ||
518 | task->tk_status = 0; | ||
519 | rpc_restart_call(task); | ||
520 | } else { | ||
521 | atomic_set(&clp->cl_cb_conn.cb_set, 0); | ||
522 | warn_no_callback_path(clp, task->tk_status); | ||
523 | } | ||
524 | } | ||
525 | |||
526 | static void nfsd4_cb_recall_release(void *calldata) | ||
527 | { | ||
528 | struct nfs4_delegation *dp = calldata; | ||
529 | struct nfs4_client *clp = dp->dl_client; | ||
530 | |||
531 | nfs4_put_delegation(dp); | ||
532 | put_nfs4_client(clp); | ||
533 | } | ||
534 | |||
535 | static const struct rpc_call_ops nfsd4_cb_recall_ops = { | ||
536 | .rpc_call_done = nfsd4_cb_recall_done, | ||
537 | .rpc_release = nfsd4_cb_recall_release, | ||
538 | }; | ||
539 | |||
497 | /* | 540 | /* |
498 | * called with dp->dl_count inc'ed. | 541 | * called with dp->dl_count inc'ed. |
499 | */ | 542 | */ |
@@ -507,32 +550,13 @@ nfsd4_cb_recall(struct nfs4_delegation *dp) | |||
507 | .rpc_argp = dp, | 550 | .rpc_argp = dp, |
508 | .rpc_cred = clp->cl_cb_conn.cb_cred | 551 | .rpc_cred = clp->cl_cb_conn.cb_cred |
509 | }; | 552 | }; |
510 | int status = 0; | 553 | int status; |
511 | 554 | ||
512 | dp->dl_retries = 1; | 555 | dp->dl_retries = 1; |
513 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); | 556 | status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT, |
514 | while (dp->dl_retries--) { | 557 | &nfsd4_cb_recall_ops, dp); |
515 | switch (status) { | 558 | if (status) { |
516 | case -EIO: | 559 | put_nfs4_client(clp); |
517 | /* Network partition? */ | 560 | nfs4_put_delegation(dp); |
518 | atomic_set(&clp->cl_cb_conn.cb_set, 0); | ||
519 | case -EBADHANDLE: | ||
520 | case -NFS4ERR_BAD_STATEID: | ||
521 | /* Race: client probably got cb_recall | ||
522 | * before open reply granting delegation */ | ||
523 | break; | ||
524 | default: | ||
525 | goto out_put_cred; | ||
526 | } | ||
527 | ssleep(2); | ||
528 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); | ||
529 | } | 561 | } |
530 | out_put_cred: | ||
531 | /* | ||
532 | * Success or failure, now we're either waiting for lease expiration | ||
533 | * or deleg_return. | ||
534 | */ | ||
535 | put_nfs4_client(clp); | ||
536 | nfs4_put_delegation(dp); | ||
537 | return; | ||
538 | } | 562 | } |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index cbb16e191d5b..a4bdf2589b41 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2060,19 +2060,6 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access) | |||
2060 | } | 2060 | } |
2061 | 2061 | ||
2062 | /* | 2062 | /* |
2063 | * Recall a delegation | ||
2064 | */ | ||
2065 | static int | ||
2066 | do_recall(void *__dp) | ||
2067 | { | ||
2068 | struct nfs4_delegation *dp = __dp; | ||
2069 | |||
2070 | dp->dl_file->fi_had_conflict = true; | ||
2071 | nfsd4_cb_recall(dp); | ||
2072 | return 0; | ||
2073 | } | ||
2074 | |||
2075 | /* | ||
2076 | * Spawn a thread to perform a recall on the delegation represented | 2063 | * Spawn a thread to perform a recall on the delegation represented |
2077 | * by the lease (file_lock) | 2064 | * by the lease (file_lock) |
2078 | * | 2065 | * |
@@ -2083,8 +2070,7 @@ do_recall(void *__dp) | |||
2083 | static | 2070 | static |
2084 | void nfsd_break_deleg_cb(struct file_lock *fl) | 2071 | void nfsd_break_deleg_cb(struct file_lock *fl) |
2085 | { | 2072 | { |
2086 | struct nfs4_delegation *dp= (struct nfs4_delegation *)fl->fl_owner; | 2073 | struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner; |
2087 | struct task_struct *t; | ||
2088 | 2074 | ||
2089 | dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); | 2075 | dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); |
2090 | if (!dp) | 2076 | if (!dp) |
@@ -2112,16 +2098,8 @@ void nfsd_break_deleg_cb(struct file_lock *fl) | |||
2112 | */ | 2098 | */ |
2113 | fl->fl_break_time = 0; | 2099 | fl->fl_break_time = 0; |
2114 | 2100 | ||
2115 | t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall"); | 2101 | dp->dl_file->fi_had_conflict = true; |
2116 | if (IS_ERR(t)) { | 2102 | nfsd4_cb_recall(dp); |
2117 | struct nfs4_client *clp = dp->dl_client; | ||
2118 | |||
2119 | printk(KERN_INFO "NFSD: Callback thread failed for " | ||
2120 | "for client (clientid %08x/%08x)\n", | ||
2121 | clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); | ||
2122 | put_nfs4_client(dp->dl_client); | ||
2123 | nfs4_put_delegation(dp); | ||
2124 | } | ||
2125 | } | 2103 | } |
2126 | 2104 | ||
2127 | /* | 2105 | /* |