Handle session level errors, update slot sequence id and sessions bookeeping, free slot. Signed-off-by: Andy Adamson<andros@xxxxxxxxxx> Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> --- fs/nfs/nfs4proc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_xdr.h | 3 ++ 2 files changed, 64 insertions(+), 0 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index af9ee0e..217f891 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -296,6 +296,66 @@ nfs41_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) rpc_wake_up_next(&tbl->slot_tbl_waitq); } +/* For pNFS filelayout data servers: + * the nfs_client is NULL - to signal no lease update. + * session is the data server. + */ +static void nfs41_sequence_done(struct nfs_client *clp, + struct nfs41_sequence_res *res, + int rpc_status) +{ + unsigned long timestamp; + struct nfs4_slot_table *tbl; + struct nfs4_slot *slot; + int status = NFS4_OK; + + if (res->sr_flags & SEQ4_STATUS_USE_TK_STATUS) + status = rpc_status; + + tbl = &res->sr_session->fore_channel.slot_table; + slot = res->sr_slot; + + switch (status) { + case NFS4_OK: + /* + * The sequence call was successful, + * Update the slot's sequence and client's lease renewal timers + */ + ++slot->seq_nr; + if (!clp) + break; + timestamp = res->sr_renewal_time; + spin_lock(&clp->cl_lock); + if (time_before(clp->cl_last_renewal, timestamp)) + clp->cl_last_renewal = timestamp; + spin_unlock(&clp->cl_lock); + break; + + case -NFS4ERR_BADSESSION: + case -NFS4ERR_BADSLOT: + case -NFS4ERR_BADXDR: + case -NFS4ERR_BAD_HIGH_SLOT: + case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: + case -NFS4ERR_DEADSESSION: + case -NFS4ERR_DELAY: + case -NFS4ERR_REP_TOO_BIG: + case -NFS4ERR_REP_TOO_BIG_TO_CACHE: + case -NFS4ERR_REQ_TOO_BIG: + case -NFS4ERR_RETRY_UNCACHED_REP: + case -NFS4ERR_SEQUENCE_POS: + case -NFS4ERR_SEQ_FALSE_RETRY: + case -NFS4ERR_SEQ_MISORDERED: + case -NFS4ERR_TOO_MANY_OPS: + dprintk("%s: status %d\n", __func__, status); + break; + + default: + printk(KERN_WARNING "%s: Unexpected status %d\n", __func__, + status); + } + nfs41_free_slot(tbl, slot); +} + /* * nfs4_find_slot - efficiently look for a free slot * @@ -373,6 +433,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session, dprintk("<-- %s slot=%p slotid=%d seqid=%d\n", __func__, slot, slot_idx(tbl, slot), slot->seq_nr); + res->sr_session = session; res->sr_slot = slot; res->sr_renewal_time = jiffies; return 0; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 9cefe0d..4144ea2 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -134,8 +134,11 @@ struct nfs41_sequence_args { #define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040 #define SEQ4_STATUS_LEASE_MOVED 0x00000080 #define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 +#define SEQ4_STATUS_USE_TK_STATUS 0x10000000 /* internal error */ struct nfs41_sequence_res { + struct nfs4_session *sr_session; + u32 sr_flags; struct nfs4_slot *sr_slot; /* slot used to send request */ unsigned long sr_renewal_time; }; -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html