Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 142192
b: refs/heads/master
c: b85d4c0
h: refs/heads/master
v: v3
  • Loading branch information
Benny Halevy authored and J. Bruce Fields committed Apr 4, 2009
1 parent 4c2a247 commit a321d50
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a1bcecd29cdf1670df6908a620add4211c0abb7a
refs/heads/master: b85d4c01b76f6969a085d07a767fa45225cb14be
73 changes: 71 additions & 2 deletions trunk/fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,32 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
return status;
}

static int
check_slot_seqid(u32 seqid, struct nfsd4_slot *slot)
{
dprintk("%s enter. seqid %d slot->sl_seqid %d\n", __func__, seqid,
slot->sl_seqid);

/* The slot is in use, and no response has been sent. */
if (slot->sl_inuse) {
if (seqid == slot->sl_seqid)
return nfserr_jukebox;
else
return nfserr_seq_misordered;
}
/* Normal */
if (likely(seqid == slot->sl_seqid + 1))
return nfs_ok;
/* Replay */
if (seqid == slot->sl_seqid)
return nfserr_replay_cache;
/* Wraparound */
if (seqid == 1 && (slot->sl_seqid + 1) == 0)
return nfs_ok;
/* Misordered replay or misordered new request */
return nfserr_seq_misordered;
}

__be32
nfsd4_create_session(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate,
Expand All @@ -1017,11 +1043,54 @@ nfsd4_destroy_session(struct svc_rqst *r,
}

__be32
nfsd4_sequence(struct svc_rqst *r,
nfsd4_sequence(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate,
struct nfsd4_sequence *seq)
{
return -1; /* stub */
struct nfsd4_session *session;
struct nfsd4_slot *slot;
int status;

spin_lock(&sessionid_lock);
status = nfserr_badsession;
session = find_in_sessionid_hashtbl(&seq->sessionid);
if (!session)
goto out;

status = nfserr_badslot;
if (seq->slotid >= session->se_fnumslots)
goto out;

slot = &session->se_slots[seq->slotid];
dprintk("%s: slotid %d\n", __func__, seq->slotid);

status = check_slot_seqid(seq->seqid, slot);
if (status == nfserr_replay_cache) {
cstate->slot = slot;
cstate->session = session;
goto replay_cache;
}
if (status)
goto out;

/* Success! bump slot seqid */
slot->sl_inuse = true;
slot->sl_seqid = seq->seqid;

cstate->slot = slot;
cstate->session = session;

replay_cache:
/* Renew the clientid on success and on replay.
* Hold a session reference until done processing the compound:
* nfsd4_put_session called only if the cstate slot is set.
*/
renew_client(session->se_client);
nfsd4_get_session(session);
out:
spin_unlock(&sessionid_lock);
dprintk("%s: return %d\n", __func__, ntohl(status));
return status;
}

__be32
Expand Down
33 changes: 30 additions & 3 deletions trunk/fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,16 @@ static __be32
nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
struct nfsd4_sequence *seq)
{
return nfserr_opnotsupp; /* stub */
DECODE_HEAD;

READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
READ32(seq->seqid);
READ32(seq->slotid);
READ32(seq->maxslots);
READ32(seq->cachethis);

DECODE_TAIL;
}

static __be32
Expand Down Expand Up @@ -2828,8 +2837,26 @@ static __be32
nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
struct nfsd4_sequence *seq)
{
/* stub */
return nfserr;
ENCODE_HEAD;

if (nfserr)
return nfserr;

RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
WRITE32(seq->seqid);
WRITE32(seq->slotid);
WRITE32(seq->maxslots);
/*
* FIXME: for now:
* target_maxslots = maxslots
* status_flags = 0
*/
WRITE32(seq->maxslots);
WRITE32(0);

ADJUST_ARGS();
return 0;
}

static __be32
Expand Down
13 changes: 12 additions & 1 deletion trunk/include/linux/nfsd/xdr4.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ struct nfsd4_compound_state {
struct svc_fh current_fh;
struct svc_fh save_fh;
struct nfs4_stateowner *replay_owner;
/* For sessions DRC */
struct nfsd4_session *session;
struct nfsd4_slot *slot;
};

struct nfsd4_change_info {
Expand Down Expand Up @@ -358,7 +361,15 @@ struct nfsd4_create_session {
};

struct nfsd4_sequence {
int foo; /* stub */
struct nfs4_sessionid sessionid; /* request/response */
u32 seqid; /* request/response */
u32 slotid; /* request/response */
u32 maxslots; /* request/response */
u32 cachethis; /* request */
#if 0
u32 target_maxslots; /* response */
u32 status_flags; /* response */
#endif /* not yet */
};

struct nfsd4_destroy_session {
Expand Down

0 comments on commit a321d50

Please sign in to comment.