Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 164645
b: refs/heads/master
c: 2a1d1b5
h: refs/heads/master
i:
  164643: aaf2ec8
v: v3
  • Loading branch information
Ricardo Labiaga authored and J. Bruce Fields committed Sep 16, 2009
1 parent 4ebdb7c commit 81571e3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 199ff35e1c8724871e157c2e48556c2794946e82
refs/heads/master: 2a1d1b593803d7c18a369bf148f3b48c5a3260fc
62 changes: 62 additions & 0 deletions trunk/fs/nfsd/nfs4callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,67 @@ nfsd4_probe_callback(struct nfs4_client *clp)
do_probe_callback(clp);
}

/*
* There's currently a single callback channel slot.
* If the slot is available, then mark it busy. Otherwise, set the
* thread for sleeping on the callback RPC wait queue.
*/
static int nfsd41_cb_setup_sequence(struct nfs4_client *clp,
struct rpc_task *task)
{
struct nfs4_rpc_args *args = task->tk_msg.rpc_argp;
u32 *ptr = (u32 *)clp->cl_sessionid.data;
int status = 0;

dprintk("%s: %u:%u:%u:%u\n", __func__,
ptr[0], ptr[1], ptr[2], ptr[3]);

if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
dprintk("%s slot is busy\n", __func__);
status = -EAGAIN;
goto out;
}

/*
* We'll need the clp during XDR encoding and decoding,
* and the sequence during decoding to verify the reply
*/
args->args_seq.cbs_clp = clp;
task->tk_msg.rpc_resp = &args->args_seq;

out:
dprintk("%s status=%d\n", __func__, status);
return status;
}

/*
* TODO: cb_sequence should support referring call lists, cachethis, multiple
* slots, and mark callback channel down on communication errors.
*/
static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
{
struct nfs4_delegation *dp = calldata;
struct nfs4_client *clp = dp->dl_client;
struct nfs4_rpc_args *args = task->tk_msg.rpc_argp;
u32 minorversion = clp->cl_cb_conn.cb_minorversion;
int status = 0;

args->args_seq.cbs_minorversion = minorversion;
if (minorversion) {
status = nfsd41_cb_setup_sequence(clp, task);
if (status) {
if (status != -EAGAIN) {
/* terminate rpc task */
task->tk_status = status;
task->tk_action = NULL;
}
return;
}
}
rpc_call_start(task);
}

static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
{
struct nfs4_delegation *dp = calldata;
Expand Down Expand Up @@ -540,6 +601,7 @@ static void nfsd4_cb_recall_release(void *calldata)
}

static const struct rpc_call_ops nfsd4_cb_recall_ops = {
.rpc_call_prepare = nfsd4_cb_prepare,
.rpc_call_done = nfsd4_cb_recall_done,
.rpc_release = nfsd4_cb_recall_release,
};
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
unconf->cl_cb_conn.cb_minorversion =
cstate->minorversion;
unconf->cl_cb_conn.cb_prog = cr_ses->callback_prog;
unconf->cl_cb_seq_nr = 1;
nfsd4_probe_callback(unconf);
}
conf = unconf;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/nfsd/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ struct nfs4_client {
/* for nfs41 callbacks */
/* We currently support a single back channel with a single slot */
unsigned long cl_cb_slot_busy;
u32 cl_cb_seq_nr;
struct svc_xprt *cl_cb_xprt; /* 4.1 callback transport */
struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */
/* wait here for slots */
Expand Down

0 comments on commit 81571e3

Please sign in to comment.