summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-11-20 18:10:30 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-12-06 00:30:17 +0100
commitda0507b7c95ccd4d9c86394eef42fe076032af30 (patch)
tree3cbbc9e94b85183e64f14a37732bd1011817032d /fs/nfs
parent464ee9f966404786ba4c6be35dc8362ee8e6ba4e (diff)
downloadop-kernel-dev-da0507b7c95ccd4d9c86394eef42fe076032af30.zip
op-kernel-dev-da0507b7c95ccd4d9c86394eef42fe076032af30.tar.gz
NFSv4.1: Reset the sequence number for slots that have been deallocated
When the server tells us that it is dynamically resizing the session replay cache, we should reset the sequence number for those slots that have been deallocated. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c18
-rw-r--r--fs/nfs/nfs4xdr.c4
2 files changed, 20 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d91abaa..52435ec 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -498,6 +498,22 @@ static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
tbl->generation++;
}
+static void nfs41_set_server_slotid_locked(struct nfs4_slot_table *tbl,
+ u32 highest_slotid)
+{
+ unsigned int max_slotid, i;
+
+ if (tbl->server_highest_slotid == highest_slotid)
+ return;
+ if (tbl->highest_used_slotid > highest_slotid)
+ return;
+ max_slotid = min(tbl->max_slots - 1, highest_slotid);
+ /* Reset the seq_nr for deallocated slots */
+ for (i = tbl->server_highest_slotid + 1; i <= max_slotid; i++)
+ tbl->slots[i].seq_nr = 1;
+ tbl->server_highest_slotid = highest_slotid;
+}
+
static void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
struct nfs4_slot *slot,
struct nfs4_sequence_res *res)
@@ -505,6 +521,7 @@ static void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
spin_lock(&tbl->slot_tbl_lock);
if (tbl->generation != slot->generation)
goto out;
+ nfs41_set_server_slotid_locked(tbl, res->sr_highest_slotid);
nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid);
out:
spin_unlock(&tbl->slot_tbl_lock);
@@ -5718,6 +5735,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
}
tbl->highest_used_slotid = NFS4_NO_SLOT;
tbl->target_highest_slotid = max_slots - 1;
+ tbl->server_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/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 05d34f1..a67040f 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -5550,8 +5550,8 @@ static int decode_sequence(struct xdr_stream *xdr,
dprintk("%s Invalid slot id\n", __func__);
goto out_err;
}
- /* highest slot id - currently not processed */
- dummy = be32_to_cpup(p++);
+ /* highest slot id */
+ res->sr_highest_slotid = be32_to_cpup(p++);
/* target highest slot id */
res->sr_target_highest_slotid = be32_to_cpup(p++);
/* result flags */
OpenPOWER on IntegriCloud