+++ /dev/null
-From e09c978aae5bedfdb379be80363b024b7d82638b Mon Sep 17 00:00:00 2001
-From: Trond Myklebust <trond.myklebust@primarydata.com>
-Date: Sat, 27 Aug 2016 23:44:04 -0400
-Subject: NFSv4.1: Fix Oopsable condition in server callback races
-
-From: Trond Myklebust <trond.myklebust@primarydata.com>
-
-commit e09c978aae5bedfdb379be80363b024b7d82638b upstream.
-
-The slot table hasn't been an array since v3.7. Ensure that we
-use nfs4_lookup_slot() to access the slot correctly.
-
-Fixes: 87dda67e7386 ("NFSv4.1: Allow SEQUENCE to resize the slot table...")
-Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- fs/nfs/callback_proc.c | 5 +----
- fs/nfs/nfs4session.c | 33 +++++++++++++++++++++++++++++++++
- fs/nfs/nfs4session.h | 1 +
- 3 files changed, 35 insertions(+), 4 deletions(-)
-
---- a/fs/nfs/callback_proc.c
-+++ b/fs/nfs/callback_proc.c
-@@ -400,11 +400,8 @@ static bool referring_call_exists(struct
- ((u32 *)&rclist->rcl_sessionid.data)[3],
- ref->rc_sequenceid, ref->rc_slotid);
-
-- spin_lock(&tbl->slot_tbl_lock);
-- status = (test_bit(ref->rc_slotid, tbl->used_slots) &&
-- tbl->slots[ref->rc_slotid].seq_nr ==
-+ status = nfs4_slot_seqid_in_use(tbl, ref->rc_slotid,
- ref->rc_sequenceid);
-- spin_unlock(&tbl->slot_tbl_lock);
- if (status)
- goto out;
- }
---- a/fs/nfs/nfs4session.c
-+++ b/fs/nfs/nfs4session.c
-@@ -135,6 +135,39 @@ static struct nfs4_slot *nfs4_find_or_cr
- return ERR_PTR(-ENOMEM);
- }
-
-+static int nfs4_slot_get_seqid(struct nfs4_slot_table *tbl, u32 slotid,
-+ u32 *seq_nr)
-+ __must_hold(&tbl->slot_tbl_lock)
-+{
-+ struct nfs4_slot *slot;
-+
-+ slot = nfs4_lookup_slot(tbl, slotid);
-+ if (IS_ERR(slot))
-+ return PTR_ERR(slot);
-+ *seq_nr = slot->seq_nr;
-+ return 0;
-+}
-+
-+/*
-+ * nfs4_slot_seqid_in_use - test if a slot sequence id is still in use
-+ *
-+ * Given a slot table, slot id and sequence number, determine if the
-+ * RPC call in question is still in flight. This function is mainly
-+ * intended for use by the callback channel.
-+ */
-+bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, u32 slotid, u32 seq_nr)
-+{
-+ u32 cur_seq;
-+ bool ret = false;
-+
-+ spin_lock(&tbl->slot_tbl_lock);
-+ if (nfs4_slot_get_seqid(tbl, slotid, &cur_seq) == 0 &&
-+ cur_seq == seq_nr && test_bit(slotid, tbl->used_slots))
-+ ret = true;
-+ spin_unlock(&tbl->slot_tbl_lock);
-+ return ret;
-+}
-+
- /*
- * nfs4_alloc_slot - efficiently look for a free slot
- *
---- a/fs/nfs/nfs4session.h
-+++ b/fs/nfs/nfs4session.h
-@@ -77,6 +77,7 @@ extern int nfs4_setup_slot_table(struct
- unsigned int max_reqs, const char *queue);
- extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl);
- extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl);
-+extern bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, u32 slotid, u32 seq_nr);
- extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot);
- extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl);
- bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,