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 | |
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')
-rw-r--r-- | fs/nfs/delegation.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 17 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 33 |
3 files changed, 35 insertions, 17 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index d2ee09b38cee..66cc720e3927 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -159,8 +159,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation * | |||
159 | { | 159 | { |
160 | int res = 0; | 160 | int res = 0; |
161 | 161 | ||
162 | __nfs_revalidate_inode(NFS_SERVER(inode), inode); | ||
163 | |||
164 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); | 162 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); |
165 | nfs_free_delegation(delegation); | 163 | nfs_free_delegation(delegation); |
166 | return res; | 164 | return res; |
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 | } |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 5d6bda43dfaa..12be1d682164 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -392,9 +392,11 @@ static int nfs_stat_to_errno(int); | |||
392 | decode_getattr_maxsz) | 392 | decode_getattr_maxsz) |
393 | #define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ | 393 | #define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ |
394 | encode_putfh_maxsz + \ | 394 | encode_putfh_maxsz + \ |
395 | encode_delegreturn_maxsz) | 395 | encode_delegreturn_maxsz + \ |
396 | encode_getattr_maxsz) | ||
396 | #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ | 397 | #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ |
397 | decode_delegreturn_maxsz) | 398 | decode_delegreturn_maxsz + \ |
399 | decode_getattr_maxsz) | ||
398 | #define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ | 400 | #define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ |
399 | encode_putfh_maxsz + \ | 401 | encode_putfh_maxsz + \ |
400 | encode_getattr_maxsz) | 402 | encode_getattr_maxsz) |
@@ -1983,14 +1985,20 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const str | |||
1983 | { | 1985 | { |
1984 | struct xdr_stream xdr; | 1986 | struct xdr_stream xdr; |
1985 | struct compound_hdr hdr = { | 1987 | struct compound_hdr hdr = { |
1986 | .nops = 2, | 1988 | .nops = 3, |
1987 | }; | 1989 | }; |
1988 | int status; | 1990 | int status; |
1989 | 1991 | ||
1990 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1992 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1991 | encode_compound_hdr(&xdr, &hdr); | 1993 | encode_compound_hdr(&xdr, &hdr); |
1992 | if ((status = encode_putfh(&xdr, args->fhandle)) == 0) | 1994 | status = encode_putfh(&xdr, args->fhandle); |
1993 | status = encode_delegreturn(&xdr, args->stateid); | 1995 | if (status != 0) |
1996 | goto out; | ||
1997 | status = encode_delegreturn(&xdr, args->stateid); | ||
1998 | if (status != 0) | ||
1999 | goto out; | ||
2000 | status = encode_getfattr(&xdr, args->bitmask); | ||
2001 | out: | ||
1994 | return status; | 2002 | return status; |
1995 | } | 2003 | } |
1996 | 2004 | ||
@@ -4184,7 +4192,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s | |||
4184 | /* | 4192 | /* |
4185 | * DELEGRETURN request | 4193 | * DELEGRETURN request |
4186 | */ | 4194 | */ |
4187 | static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *dummy) | 4195 | static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_delegreturnres *res) |
4188 | { | 4196 | { |
4189 | struct xdr_stream xdr; | 4197 | struct xdr_stream xdr; |
4190 | struct compound_hdr hdr; | 4198 | struct compound_hdr hdr; |
@@ -4192,11 +4200,14 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d | |||
4192 | 4200 | ||
4193 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | 4201 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); |
4194 | status = decode_compound_hdr(&xdr, &hdr); | 4202 | status = decode_compound_hdr(&xdr, &hdr); |
4195 | if (status == 0) { | 4203 | if (status != 0) |
4196 | status = decode_putfh(&xdr); | 4204 | goto out; |
4197 | if (status == 0) | 4205 | status = decode_putfh(&xdr); |
4198 | status = decode_delegreturn(&xdr); | 4206 | if (status != 0) |
4199 | } | 4207 | goto out; |
4208 | status = decode_delegreturn(&xdr); | ||
4209 | decode_getfattr(&xdr, res->fattr, res->server); | ||
4210 | out: | ||
4200 | return status; | 4211 | return status; |
4201 | } | 4212 | } |
4202 | 4213 | ||