X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=blobdiff_plain;f=fs%2Fnfsd%2Fnfs4callback.c;h=f4fab69a8c30c7fc5f733cde9dd961c2875b349a;hp=0aaf68beedbdda4c960f299cf78bf30b6c0b39ed;hb=63e4863fabc6e165a6ca813051305be58966da45;hpb=e300a63ce4ccec073d254d883a3638d5dca1d771 diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 0aaf68b..f4fab69 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -215,18 +215,18 @@ encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) } static int -encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec) +encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp) { __be32 *p; - int len = cb_rec->cbr_fh.fh_size; + int len = dp->dl_fh.fh_size; - RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len); + RESERVE_SPACE(12+sizeof(dp->dl_stateid) + len); WRITE32(OP_CB_RECALL); - WRITE32(cb_rec->cbr_stateid.si_generation); - WRITEMEM(&cb_rec->cbr_stateid.si_opaque, sizeof(stateid_opaque_t)); - WRITE32(cb_rec->cbr_trunc); + WRITE32(dp->dl_stateid.si_generation); + WRITEMEM(&dp->dl_stateid.si_opaque, sizeof(stateid_opaque_t)); + WRITE32(0); /* truncate optimization not implemented */ WRITE32(len); - WRITEMEM(&cb_rec->cbr_fh.fh_base, len); + WRITEMEM(&dp->dl_fh.fh_base, len); return 0; } @@ -241,11 +241,11 @@ nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) } static int -nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_cb_recall *args) +nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_delegation *args) { struct xdr_stream xdr; struct nfs4_cb_compound_hdr hdr = { - .ident = args->cbr_ident, + .ident = args->dl_ident, .nops = 1, }; @@ -369,7 +369,7 @@ static int max_cb_time(void) int setup_callback_client(struct nfs4_client *clp) { struct sockaddr_in addr; - struct nfs4_callback *cb = &clp->cl_callback; + struct nfs4_cb_conn *cb = &clp->cl_cb_conn; struct rpc_timeout timeparms = { .to_initval = max_cb_time(), .to_retries = 0, @@ -422,7 +422,7 @@ static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) if (task->tk_status) warn_no_callback_path(clp, task->tk_status); else - atomic_set(&clp->cl_callback.cb_set, 1); + atomic_set(&clp->cl_cb_conn.cb_set, 1); put_nfs4_client(clp); } @@ -430,7 +430,7 @@ static const struct rpc_call_ops nfsd4_cb_probe_ops = { .rpc_call_done = nfsd4_cb_probe_done, }; -static struct rpc_cred *lookup_cb_cred(struct nfs4_callback *cb) +static struct rpc_cred *lookup_cb_cred(struct nfs4_cb_conn *cb) { struct auth_cred acred = { .machine_cred = 1 @@ -448,7 +448,7 @@ static struct rpc_cred *lookup_cb_cred(struct nfs4_callback *cb) void do_probe_callback(struct nfs4_client *clp) { - struct nfs4_callback *cb = &clp->cl_callback; + struct nfs4_cb_conn *cb = &clp->cl_cb_conn; struct rpc_message msg = { .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], .rpc_argp = clp, @@ -480,7 +480,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) { int status; - BUG_ON(atomic_read(&clp->cl_callback.cb_set)); + BUG_ON(atomic_read(&clp->cl_cb_conn.cb_set)); status = setup_callback_client(clp); if (status) { @@ -494,6 +494,49 @@ nfsd4_probe_callback(struct nfs4_client *clp) do_probe_callback(clp); } +static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) +{ + struct nfs4_delegation *dp = calldata; + struct nfs4_client *clp = dp->dl_client; + + switch (task->tk_status) { + case -EIO: + /* Network partition? */ + atomic_set(&clp->cl_cb_conn.cb_set, 0); + warn_no_callback_path(clp, task->tk_status); + case -EBADHANDLE: + case -NFS4ERR_BAD_STATEID: + /* Race: client probably got cb_recall + * before open reply granting delegation */ + break; + default: + /* success, or error we can't handle */ + return; + } + if (dp->dl_retries--) { + rpc_delay(task, 2*HZ); + task->tk_status = 0; + rpc_restart_call(task); + } else { + atomic_set(&clp->cl_cb_conn.cb_set, 0); + warn_no_callback_path(clp, task->tk_status); + } +} + +static void nfsd4_cb_recall_release(void *calldata) +{ + struct nfs4_delegation *dp = calldata; + struct nfs4_client *clp = dp->dl_client; + + nfs4_put_delegation(dp); + put_nfs4_client(clp); +} + +static const struct rpc_call_ops nfsd4_cb_recall_ops = { + .rpc_call_done = nfsd4_cb_recall_done, + .rpc_release = nfsd4_cb_recall_release, +}; + /* * called with dp->dl_count inc'ed. */ @@ -501,42 +544,19 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp) { struct nfs4_client *clp = dp->dl_client; - struct rpc_clnt *clnt = clp->cl_callback.cb_client; - struct nfs4_cb_recall *cbr = &dp->dl_recall; + struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client; struct rpc_message msg = { .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL], - .rpc_argp = cbr, - .rpc_cred = clp->cl_callback.cb_cred + .rpc_argp = dp, + .rpc_cred = clp->cl_cb_conn.cb_cred }; - int retries = 1; - int status = 0; - - cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */ - cbr->cbr_dp = dp; - - status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); - while (retries--) { - switch (status) { - case -EIO: - /* Network partition? */ - atomic_set(&clp->cl_callback.cb_set, 0); - case -EBADHANDLE: - case -NFS4ERR_BAD_STATEID: - /* Race: client probably got cb_recall - * before open reply granting delegation */ - break; - default: - goto out_put_cred; - } - ssleep(2); - status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); + int status; + + dp->dl_retries = 1; + status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT, + &nfsd4_cb_recall_ops, dp); + if (status) { + put_nfs4_client(clp); + nfs4_put_delegation(dp); } -out_put_cred: - /* - * Success or failure, now we're either waiting for lease expiration - * or deleg_return. - */ - put_nfs4_client(clp); - nfs4_put_delegation(dp); - return; }