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 | /* |
