]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
NFSv4.1: Reset the sequence number for slots that have been deallocated
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 20 Nov 2012 23:10:30 +0000 (18:10 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 5 Dec 2012 23:30:17 +0000 (00:30 +0100)
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>
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h

index d91abaa522e85a3c9c2b0ae24d275d68ba8b5c10..52435ec441932b878e2824a9cd5ad3a24714328e 100644 (file)
@@ -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);
index 05d34f1fcc19c65de88f6c880a540c760c617257..a67040f5159722ed20df641bcfb76683412355cc 100644 (file)
@@ -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 */
index 57d406997def7b736c7668b042526c0b399b6125..646e64bbff4c49b35b33f3b81292795df738b566 100644 (file)
@@ -218,6 +218,7 @@ struct nfs4_slot_table {
        u32             highest_used_slotid;    /* sent to server on each SEQ.
                                                 * op for dynamic resizing */
        u32             target_highest_slotid;  /* Server max_slot target */
+       u32             server_highest_slotid;  /* Server highest slotid */
        unsigned long   generation;             /* Generation counter for
                                                   target_highest_slotid */
        struct completion complete;
index 08c47db7417fc61e31f289fbe19a561e24b464ae..3ddb08fba935068cddfdcb8673bed8e29249cb69 100644 (file)
@@ -203,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_highest_slotid;
        u32                     sr_target_highest_slotid;
 };