diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-03 03:55:38 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:51 -0500 |
commit | fa178f29c0f8a0dce748181a5351f4a92fd4f455 (patch) | |
tree | 07de5ced8d16d832ebed98c58a2c0498affa12db /fs/nfs/nfs4proc.c | |
parent | beb2a5ec386e5ce6891ebd1c06b913da04354b40 (diff) |
NFSv4: Ensure DELEGRETURN returns attributes
Upon return of a write delegation, the server will almost always bump the
change attribute. Ensure that we pick up that change so that we don't
invalidate our data cache unnecessarily.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b3349154994b..984ca3454d04 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2920,11 +2920,12 @@ nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) | |||
2920 | 2920 | ||
2921 | struct nfs4_delegreturndata { | 2921 | struct nfs4_delegreturndata { |
2922 | struct nfs4_delegreturnargs args; | 2922 | struct nfs4_delegreturnargs args; |
2923 | struct nfs4_delegreturnres res; | ||
2923 | struct nfs_fh fh; | 2924 | struct nfs_fh fh; |
2924 | nfs4_stateid stateid; | 2925 | nfs4_stateid stateid; |
2925 | struct rpc_cred *cred; | 2926 | struct rpc_cred *cred; |
2926 | unsigned long timestamp; | 2927 | unsigned long timestamp; |
2927 | const struct nfs_server *server; | 2928 | struct nfs_fattr fattr; |
2928 | int rpc_status; | 2929 | int rpc_status; |
2929 | }; | 2930 | }; |
2930 | 2931 | ||
@@ -2934,8 +2935,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *calldata) | |||
2934 | struct rpc_message msg = { | 2935 | struct rpc_message msg = { |
2935 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], | 2936 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], |
2936 | .rpc_argp = &data->args, | 2937 | .rpc_argp = &data->args, |
2938 | .rpc_resp = &data->res, | ||
2937 | .rpc_cred = data->cred, | 2939 | .rpc_cred = data->cred, |
2938 | }; | 2940 | }; |
2941 | nfs_fattr_init(data->res.fattr); | ||
2939 | rpc_call_setup(task, &msg, 0); | 2942 | rpc_call_setup(task, &msg, 0); |
2940 | } | 2943 | } |
2941 | 2944 | ||
@@ -2944,7 +2947,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) | |||
2944 | struct nfs4_delegreturndata *data = calldata; | 2947 | struct nfs4_delegreturndata *data = calldata; |
2945 | data->rpc_status = task->tk_status; | 2948 | data->rpc_status = task->tk_status; |
2946 | if (data->rpc_status == 0) | 2949 | if (data->rpc_status == 0) |
2947 | renew_lease(data->server, data->timestamp); | 2950 | renew_lease(data->res.server, data->timestamp); |
2948 | } | 2951 | } |
2949 | 2952 | ||
2950 | static void nfs4_delegreturn_release(void *calldata) | 2953 | static void nfs4_delegreturn_release(void *calldata) |
@@ -2964,6 +2967,7 @@ const static struct rpc_call_ops nfs4_delegreturn_ops = { | |||
2964 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 2967 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) |
2965 | { | 2968 | { |
2966 | struct nfs4_delegreturndata *data; | 2969 | struct nfs4_delegreturndata *data; |
2970 | struct nfs_server *server = NFS_SERVER(inode); | ||
2967 | struct rpc_task *task; | 2971 | struct rpc_task *task; |
2968 | int status; | 2972 | int status; |
2969 | 2973 | ||
@@ -2972,11 +2976,13 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co | |||
2972 | return -ENOMEM; | 2976 | return -ENOMEM; |
2973 | data->args.fhandle = &data->fh; | 2977 | data->args.fhandle = &data->fh; |
2974 | data->args.stateid = &data->stateid; | 2978 | data->args.stateid = &data->stateid; |
2979 | data->args.bitmask = server->attr_bitmask; | ||
2975 | nfs_copy_fh(&data->fh, NFS_FH(inode)); | 2980 | nfs_copy_fh(&data->fh, NFS_FH(inode)); |
2976 | memcpy(&data->stateid, stateid, sizeof(data->stateid)); | 2981 | memcpy(&data->stateid, stateid, sizeof(data->stateid)); |
2982 | data->res.fattr = &data->fattr; | ||
2983 | data->res.server = server; | ||
2977 | data->cred = get_rpccred(cred); | 2984 | data->cred = get_rpccred(cred); |
2978 | data->timestamp = jiffies; | 2985 | data->timestamp = jiffies; |
2979 | data->server = NFS_SERVER(inode); | ||
2980 | data->rpc_status = 0; | 2986 | data->rpc_status = 0; |
2981 | 2987 | ||
2982 | task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); | 2988 | task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); |
@@ -2985,8 +2991,11 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co | |||
2985 | return PTR_ERR(task); | 2991 | return PTR_ERR(task); |
2986 | } | 2992 | } |
2987 | status = nfs4_wait_for_completion_rpc_task(task); | 2993 | status = nfs4_wait_for_completion_rpc_task(task); |
2988 | if (status == 0) | 2994 | if (status == 0) { |
2989 | status = data->rpc_status; | 2995 | status = data->rpc_status; |
2996 | if (status == 0) | ||
2997 | nfs_post_op_update_inode(inode, &data->fattr); | ||
2998 | } | ||
2990 | rpc_release_task(task); | 2999 | rpc_release_task(task); |
2991 | return status; | 3000 | return status; |
2992 | } | 3001 | } |