diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-03 03:55:18 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:44 -0500 |
| commit | fe650407a86823bcafbfbee96c7bc6a1b5cd1c76 (patch) | |
| tree | 38e899d40fabba538bb558c0dcc3d38f830beadb | |
| parent | a5d16a4d090bd2af86e648ed9bb205903fcf1e86 (diff) | |
NFSv4: Make DELEGRETURN an interruptible operation.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | fs/nfs/nfs4proc.c | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 718fcc722556..f060e6538edc 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -2885,19 +2885,71 @@ nfs4_proc_setclientid_confirm(struct nfs4_client *clp) | |||
| 2885 | return status; | 2885 | return status; |
| 2886 | } | 2886 | } |
| 2887 | 2887 | ||
| 2888 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 2888 | struct nfs4_delegreturndata { |
| 2889 | struct nfs4_delegreturnargs args; | ||
| 2890 | struct nfs_fh fh; | ||
| 2891 | nfs4_stateid stateid; | ||
| 2892 | struct rpc_cred *cred; | ||
| 2893 | int rpc_status; | ||
| 2894 | }; | ||
| 2895 | |||
| 2896 | static void nfs4_delegreturn_prepare(struct rpc_task *task, void *calldata) | ||
| 2889 | { | 2897 | { |
| 2890 | struct nfs4_delegreturnargs args = { | 2898 | struct nfs4_delegreturndata *data = calldata; |
| 2891 | .fhandle = NFS_FH(inode), | ||
| 2892 | .stateid = stateid, | ||
| 2893 | }; | ||
| 2894 | struct rpc_message msg = { | 2899 | struct rpc_message msg = { |
| 2895 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], | 2900 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], |
| 2896 | .rpc_argp = &args, | 2901 | .rpc_argp = &data->args, |
| 2897 | .rpc_cred = cred, | 2902 | .rpc_cred = data->cred, |
| 2898 | }; | 2903 | }; |
| 2904 | rpc_call_setup(task, &msg, 0); | ||
| 2905 | } | ||
| 2899 | 2906 | ||
| 2900 | return rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 2907 | static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) |
| 2908 | { | ||
| 2909 | struct nfs4_delegreturndata *data = calldata; | ||
| 2910 | data->rpc_status = task->tk_status; | ||
| 2911 | } | ||
| 2912 | |||
| 2913 | static void nfs4_delegreturn_release(void *calldata) | ||
| 2914 | { | ||
| 2915 | struct nfs4_delegreturndata *data = calldata; | ||
| 2916 | |||
| 2917 | put_rpccred(data->cred); | ||
| 2918 | kfree(calldata); | ||
| 2919 | } | ||
| 2920 | |||
| 2921 | const static struct rpc_call_ops nfs4_delegreturn_ops = { | ||
| 2922 | .rpc_call_prepare = nfs4_delegreturn_prepare, | ||
| 2923 | .rpc_call_done = nfs4_delegreturn_done, | ||
| 2924 | .rpc_release = nfs4_delegreturn_release, | ||
| 2925 | }; | ||
| 2926 | |||
| 2927 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | ||
| 2928 | { | ||
| 2929 | struct nfs4_delegreturndata *data; | ||
| 2930 | struct rpc_task *task; | ||
| 2931 | int status; | ||
| 2932 | |||
| 2933 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
| 2934 | if (data == NULL) | ||
| 2935 | return -ENOMEM; | ||
| 2936 | data->args.fhandle = &data->fh; | ||
| 2937 | data->args.stateid = &data->stateid; | ||
| 2938 | nfs_copy_fh(&data->fh, NFS_FH(inode)); | ||
| 2939 | memcpy(&data->stateid, stateid, sizeof(data->stateid)); | ||
| 2940 | data->cred = get_rpccred(cred); | ||
| 2941 | data->rpc_status = 0; | ||
| 2942 | |||
| 2943 | task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); | ||
| 2944 | if (IS_ERR(task)) { | ||
| 2945 | nfs4_delegreturn_release(data); | ||
| 2946 | return PTR_ERR(task); | ||
| 2947 | } | ||
| 2948 | status = nfs4_wait_for_completion_rpc_task(task); | ||
| 2949 | if (status == 0) | ||
| 2950 | status = data->rpc_status; | ||
| 2951 | rpc_release_task(task); | ||
| 2952 | return status; | ||
| 2901 | } | 2953 | } |
| 2902 | 2954 | ||
| 2903 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 2955 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) |
