diff options
| -rw-r--r-- | fs/nfs/callback_proc.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 25 | ||||
| -rw-r--r-- | fs/nfs/nfs4state.c | 7 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 4 | ||||
| -rw-r--r-- | include/linux/nfs_fs_sb.h | 5 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 2 | 
6 files changed, 36 insertions, 9 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 0be08b964f3..0ef047b7d28 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -576,7 +576,7 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,  	if (args->crsa_target_max_slots == fc_tbl->max_slots)  		goto out; -	fc_tbl->target_max_slots = args->crsa_target_max_slots; +	fc_tbl->target_highest_slotid = args->crsa_target_max_slots;  	nfs41_handle_recall_slot(cps->clp);  out:  	dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 197ef3e4e1f..d91abaa522e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -488,6 +488,28 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)  	res->sr_slot = NULL;  } +/* Update the client's idea of target_highest_slotid */ +static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl, +		u32 target_highest_slotid) +{ +	if (tbl->target_highest_slotid == target_highest_slotid) +		return; +	tbl->target_highest_slotid = target_highest_slotid; +	tbl->generation++; +} + +static void nfs41_update_target_slotid(struct nfs4_slot_table *tbl, +		struct nfs4_slot *slot, +		struct nfs4_sequence_res *res) +{ +	spin_lock(&tbl->slot_tbl_lock); +	if (tbl->generation != slot->generation) +		goto out; +	nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid); +out: +	spin_unlock(&tbl->slot_tbl_lock); +} +  static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)  {  	struct nfs4_session *session; @@ -522,6 +544,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *  		/* Check sequence flags */  		if (res->sr_status_flags != 0)  			nfs4_schedule_lease_recovery(clp); +		nfs41_update_target_slotid(slot->table, slot, res);  		break;  	case -NFS4ERR_DELAY:  		/* The server detected a resend of the RPC call and @@ -583,6 +606,7 @@ static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)  		tbl->highest_used_slotid = slotid;  	ret = &tbl->slots[slotid];  	ret->renewal_time = jiffies; +	ret->generation = tbl->generation;  out:  	dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", @@ -5693,6 +5717,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,  		tbl->max_slots = max_slots;  	}  	tbl->highest_used_slotid = NFS4_NO_SLOT; +	tbl->target_highest_slotid = max_slots - 1;  	for (i = 0; i < tbl->max_slots; i++)  		tbl->slots[i].seq_nr = ivalue;  	spin_unlock(&tbl->slot_tbl_lock); diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 9495789c425..842cb8c2f65 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -2033,17 +2033,16 @@ static int nfs4_recall_slot(struct nfs_client *clp)  		return 0;  	nfs4_begin_drain_session(clp);  	fc_tbl = &clp->cl_session->fc_slot_table; -	new = nfs4_alloc_slots(fc_tbl, fc_tbl->target_max_slots, GFP_NOFS); +	new = nfs4_alloc_slots(fc_tbl, fc_tbl->target_highest_slotid + 1, GFP_NOFS);          if (!new)  		return -ENOMEM;  	spin_lock(&fc_tbl->slot_tbl_lock); -	for (i = 0; i < fc_tbl->target_max_slots; i++) +	for (i = 0; i <= fc_tbl->target_highest_slotid; i++)  		new[i].seq_nr = fc_tbl->slots[i].seq_nr;  	old = fc_tbl->slots;  	fc_tbl->slots = new; -	fc_tbl->max_slots = fc_tbl->target_max_slots; -	fc_tbl->target_max_slots = 0; +	fc_tbl->max_slots = fc_tbl->target_highest_slotid + 1;  	clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots;  	spin_unlock(&fc_tbl->slot_tbl_lock); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 27b0fec1a6b..05d34f1fcc1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -5552,8 +5552,8 @@ static int decode_sequence(struct xdr_stream *xdr,  	}  	/* highest slot id - currently not processed */  	dummy = be32_to_cpup(p++); -	/* target highest slot id - currently not processed */ -	dummy = be32_to_cpup(p++); +	/* target highest slot id */ +	res->sr_target_highest_slotid = be32_to_cpup(p++);  	/* result flags */  	res->sr_status_flags = be32_to_cpup(p);  	status = 0; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b0412873d29..57d406997de 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -217,8 +217,9 @@ struct nfs4_slot_table {  	u32		max_slots;		/* # slots in table */  	u32		highest_used_slotid;	/* sent to server on each SEQ.  						 * op for dynamic resizing */ -	u32		target_max_slots;	/* Set by CB_RECALL_SLOT as -						 * the new max_slots */ +	u32		target_highest_slotid;	/* Server max_slot target */ +	unsigned long	generation;		/* Generation counter for +						   target_highest_slotid */  	struct completion complete;  }; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index deb31bbbb85..08c47db7417 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -188,6 +188,7 @@ struct nfs4_channel_attrs {  /* nfs41 sessions slot seqid */  struct nfs4_slot {  	struct nfs4_slot_table	*table; +	unsigned long		generation;  	unsigned long		renewal_time;  	u32			slot_nr;  	u32		 	seq_nr; @@ -202,6 +203,7 @@ struct nfs4_sequence_res {  	struct nfs4_slot	*sr_slot;	/* slot used to send request */  	int			sr_status;	/* sequence operation status */  	u32			sr_status_flags; +	u32			sr_target_highest_slotid;  };  struct nfs4_get_lease_time_args {  |