diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-01 09:22:30 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 15:24:32 -0400 |
commit | 2050f0cc0703aab7cee798b3cb47037754f368bc (patch) | |
tree | 48a54e68af8e6fe9b72994013aeecbd812e0e4ea | |
parent | 99fe60d062cfecf382c036065b3278b82b6c5eff (diff) |
nfs41: get_lease_time
get_lease_time uses the FSINFO rpc operation to
get the lease time attribute.
nfs4_get_lease_time() is only called from the state manager on session setup
so don't recover from clientid or sequence level errors.
We do need to recover from NFS4ERR_DELAY or NFS4ERR_GRACE.
Use NFS4_POLL_RETRY_MIN - the Linux server returns NFS4ERR_DELAY when an
upcall is needed to resolve an uncached export referenced by a file handle.
[nfs41: sequence res use slotid]
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: remove extraneous rpc_clnt pointer]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: have get_lease_time work on nfs_client]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: get_lease_time recover from NFS4ERR_DELAY]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: pass *session in seq_args and seq_res]
[define nfs4_get_lease_time_{args,res}]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 94 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 51 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 9 |
3 files changed, 154 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6f384e290753..eafc99afd356 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -4189,6 +4189,100 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | |||
4189 | return status; | 4189 | return status; |
4190 | } | 4190 | } |
4191 | 4191 | ||
4192 | struct nfs4_get_lease_time_data { | ||
4193 | struct nfs4_get_lease_time_args *args; | ||
4194 | struct nfs4_get_lease_time_res *res; | ||
4195 | struct nfs_client *clp; | ||
4196 | }; | ||
4197 | |||
4198 | static void nfs4_get_lease_time_prepare(struct rpc_task *task, | ||
4199 | void *calldata) | ||
4200 | { | ||
4201 | int ret; | ||
4202 | struct nfs4_get_lease_time_data *data = | ||
4203 | (struct nfs4_get_lease_time_data *)calldata; | ||
4204 | |||
4205 | dprintk("--> %s\n", __func__); | ||
4206 | /* just setup sequence, do not trigger session recovery | ||
4207 | since we're invoked within one */ | ||
4208 | ret = nfs41_setup_sequence(data->clp->cl_session, | ||
4209 | &data->args->la_seq_args, | ||
4210 | &data->res->lr_seq_res, 0, task); | ||
4211 | |||
4212 | BUG_ON(ret == -EAGAIN); | ||
4213 | rpc_call_start(task); | ||
4214 | dprintk("<-- %s\n", __func__); | ||
4215 | } | ||
4216 | |||
4217 | /* | ||
4218 | * Called from nfs4_state_manager thread for session setup, so don't recover | ||
4219 | * from sequence operation or clientid errors. | ||
4220 | */ | ||
4221 | static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata) | ||
4222 | { | ||
4223 | struct nfs4_get_lease_time_data *data = | ||
4224 | (struct nfs4_get_lease_time_data *)calldata; | ||
4225 | |||
4226 | dprintk("--> %s\n", __func__); | ||
4227 | nfs41_sequence_done(data->clp, &data->res->lr_seq_res, task->tk_status); | ||
4228 | switch (task->tk_status) { | ||
4229 | case -NFS4ERR_DELAY: | ||
4230 | case -NFS4ERR_GRACE: | ||
4231 | dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); | ||
4232 | rpc_delay(task, NFS4_POLL_RETRY_MIN); | ||
4233 | task->tk_status = 0; | ||
4234 | rpc_restart_call(task); | ||
4235 | return; | ||
4236 | } | ||
4237 | nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res); | ||
4238 | dprintk("<-- %s\n", __func__); | ||
4239 | } | ||
4240 | |||
4241 | struct rpc_call_ops nfs4_get_lease_time_ops = { | ||
4242 | .rpc_call_prepare = nfs4_get_lease_time_prepare, | ||
4243 | .rpc_call_done = nfs4_get_lease_time_done, | ||
4244 | }; | ||
4245 | |||
4246 | int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo) | ||
4247 | { | ||
4248 | struct rpc_task *task; | ||
4249 | struct nfs4_get_lease_time_args args; | ||
4250 | struct nfs4_get_lease_time_res res = { | ||
4251 | .lr_fsinfo = fsinfo, | ||
4252 | }; | ||
4253 | struct nfs4_get_lease_time_data data = { | ||
4254 | .args = &args, | ||
4255 | .res = &res, | ||
4256 | .clp = clp, | ||
4257 | }; | ||
4258 | struct rpc_message msg = { | ||
4259 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GET_LEASE_TIME], | ||
4260 | .rpc_argp = &args, | ||
4261 | .rpc_resp = &res, | ||
4262 | }; | ||
4263 | struct rpc_task_setup task_setup = { | ||
4264 | .rpc_client = clp->cl_rpcclient, | ||
4265 | .rpc_message = &msg, | ||
4266 | .callback_ops = &nfs4_get_lease_time_ops, | ||
4267 | .callback_data = &data | ||
4268 | }; | ||
4269 | int status; | ||
4270 | |||
4271 | res.lr_seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE; | ||
4272 | dprintk("--> %s\n", __func__); | ||
4273 | task = rpc_run_task(&task_setup); | ||
4274 | |||
4275 | if (IS_ERR(task)) | ||
4276 | status = PTR_ERR(task); | ||
4277 | else { | ||
4278 | status = task->tk_status; | ||
4279 | rpc_put_task(task); | ||
4280 | } | ||
4281 | dprintk("<-- %s return %d\n", __func__, status); | ||
4282 | |||
4283 | return status; | ||
4284 | } | ||
4285 | |||
4192 | /* Destroy the slot table */ | 4286 | /* Destroy the slot table */ |
4193 | static void nfs4_destroy_slot_table(struct nfs4_session *session) | 4287 | static void nfs4_destroy_slot_table(struct nfs4_session *session) |
4194 | { | 4288 | { |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 783c4214dccd..85ee1d17a461 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -622,6 +622,14 @@ static int nfs4_stat_to_errno(int); | |||
622 | #define NFS4_dec_exchange_id_sz \ | 622 | #define NFS4_dec_exchange_id_sz \ |
623 | (compound_decode_hdr_maxsz + \ | 623 | (compound_decode_hdr_maxsz + \ |
624 | decode_exchange_id_maxsz) | 624 | decode_exchange_id_maxsz) |
625 | #define NFS4_enc_get_lease_time_sz (compound_encode_hdr_maxsz + \ | ||
626 | encode_sequence_maxsz + \ | ||
627 | encode_putrootfh_maxsz + \ | ||
628 | encode_fsinfo_maxsz) | ||
629 | #define NFS4_dec_get_lease_time_sz (compound_decode_hdr_maxsz + \ | ||
630 | decode_sequence_maxsz + \ | ||
631 | decode_putrootfh_maxsz + \ | ||
632 | decode_fsinfo_maxsz) | ||
625 | #endif /* CONFIG_NFS_V4_1 */ | 633 | #endif /* CONFIG_NFS_V4_1 */ |
626 | 634 | ||
627 | static const umode_t nfs_type2fmt[] = { | 635 | static const umode_t nfs_type2fmt[] = { |
@@ -2231,6 +2239,27 @@ static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p, | |||
2231 | encode_nops(&hdr); | 2239 | encode_nops(&hdr); |
2232 | return 0; | 2240 | return 0; |
2233 | } | 2241 | } |
2242 | |||
2243 | /* | ||
2244 | * a GET_LEASE_TIME request | ||
2245 | */ | ||
2246 | static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, | ||
2247 | struct nfs4_get_lease_time_args *args) | ||
2248 | { | ||
2249 | struct xdr_stream xdr; | ||
2250 | struct compound_hdr hdr = { | ||
2251 | .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), | ||
2252 | }; | ||
2253 | const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; | ||
2254 | |||
2255 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | ||
2256 | encode_compound_hdr(&xdr, req, &hdr); | ||
2257 | encode_sequence(&xdr, &args->la_seq_args, &hdr); | ||
2258 | encode_putrootfh(&xdr, &hdr); | ||
2259 | encode_fsinfo(&xdr, lease_bitmap, &hdr); | ||
2260 | encode_nops(&hdr); | ||
2261 | return 0; | ||
2262 | } | ||
2234 | #endif /* CONFIG_NFS_V4_1 */ | 2263 | #endif /* CONFIG_NFS_V4_1 */ |
2235 | 2264 | ||
2236 | /* | 2265 | /* |
@@ -4908,6 +4937,27 @@ static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p, | |||
4908 | status = decode_exchange_id(&xdr, res); | 4937 | status = decode_exchange_id(&xdr, res); |
4909 | return status; | 4938 | return status; |
4910 | } | 4939 | } |
4940 | |||
4941 | /* | ||
4942 | * a GET_LEASE_TIME request | ||
4943 | */ | ||
4944 | static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p, | ||
4945 | struct nfs4_get_lease_time_res *res) | ||
4946 | { | ||
4947 | struct xdr_stream xdr; | ||
4948 | struct compound_hdr hdr; | ||
4949 | int status; | ||
4950 | |||
4951 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | ||
4952 | status = decode_compound_hdr(&xdr, &hdr); | ||
4953 | if (!status) | ||
4954 | status = decode_sequence(&xdr, &res->lr_seq_res, rqstp); | ||
4955 | if (!status) | ||
4956 | status = decode_putrootfh(&xdr); | ||
4957 | if (!status) | ||
4958 | status = decode_fsinfo(&xdr, res->lr_fsinfo); | ||
4959 | return status; | ||
4960 | } | ||
4911 | #endif /* CONFIG_NFS_V4_1 */ | 4961 | #endif /* CONFIG_NFS_V4_1 */ |
4912 | 4962 | ||
4913 | __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) | 4963 | __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) |
@@ -5081,6 +5131,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
5081 | PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), | 5131 | PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), |
5082 | #if defined(CONFIG_NFS_V4_1) | 5132 | #if defined(CONFIG_NFS_V4_1) |
5083 | PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), | 5133 | PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), |
5134 | PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), | ||
5084 | #endif /* CONFIG_NFS_V4_1 */ | 5135 | #endif /* CONFIG_NFS_V4_1 */ |
5085 | }; | 5136 | }; |
5086 | 5137 | ||
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 5d70b924af5e..ca643aa87d46 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -174,6 +174,15 @@ struct nfs4_sequence_res { | |||
174 | int sr_status; /* sequence operation status */ | 174 | int sr_status; /* sequence operation status */ |
175 | }; | 175 | }; |
176 | 176 | ||
177 | struct nfs4_get_lease_time_args { | ||
178 | struct nfs4_sequence_args la_seq_args; | ||
179 | }; | ||
180 | |||
181 | struct nfs4_get_lease_time_res { | ||
182 | struct nfs_fsinfo *lr_fsinfo; | ||
183 | struct nfs4_sequence_res lr_seq_res; | ||
184 | }; | ||
185 | |||
177 | /* | 186 | /* |
178 | * Arguments to the open call. | 187 | * Arguments to the open call. |
179 | */ | 188 | */ |