mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
	akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
	Trond Myklebust <Trond.Myklebust@netapp.com>
Subject: [09/35] NFSv4.1: Fix the callback highest_used_slotid behaviour
Date: Fri, 26 Aug 2011 14:49:26 -0700	[thread overview]
Message-ID: <20110826215053.815842209@clark.kroah.org> (raw)
In-Reply-To: <20110826215139.GA11498@kroah.com>

3.0-stable review patch.  If anyone has any objections, please let us know.

------------------

From: Trond Myklebust <Trond.Myklebust@netapp.com>

commit 55a673990ec04cf63005318bcf08c2b0046e5778 upstream.

Currently, there is no guarantee that we will call nfs4_cb_take_slot() even
though nfs4_callback_compound() will consistently call
nfs4_cb_free_slot() provided the cb_process_state has set the 'clp' field.
The result is that we can trigger the BUG_ON() upon the next call to
nfs4_cb_take_slot().

This patch fixes the above problem by using the slot id that was taken in
the CB_SEQUENCE operation as a flag for whether or not we need to call
nfs4_cb_free_slot().
It also fixes an atomicity problem: we need to set tbl->highest_used_slotid
atomically with the check for NFS4_SESSION_DRAINING, otherwise we end up
racing with the various tests in nfs4_begin_drain_session().

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 fs/nfs/callback.h      |    2 +-
 fs/nfs/callback_proc.c |   20 ++++++++++++++------
 fs/nfs/callback_xdr.c  |   24 +++++++-----------------
 3 files changed, 22 insertions(+), 24 deletions(-)

--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -38,6 +38,7 @@ enum nfs4_callback_opnum {
 struct cb_process_state {
 	__be32			drc_status;
 	struct nfs_client	*clp;
+	int			slotid;
 };
 
 struct cb_compound_hdr_arg {
@@ -166,7 +167,6 @@ extern unsigned nfs4_callback_layoutreca
 	void *dummy, struct cb_process_state *cps);
 
 extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
-extern void nfs4_cb_take_slot(struct nfs_client *clp);
 
 struct cb_devicenotifyitem {
 	uint32_t		cbd_notify_type;
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -333,7 +333,7 @@ validate_seqid(struct nfs4_slot_table *t
 	/* Normal */
 	if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
 		slot->seq_nr++;
-		return htonl(NFS4_OK);
+		goto out_ok;
 	}
 
 	/* Replay */
@@ -352,11 +352,14 @@ validate_seqid(struct nfs4_slot_table *t
 	/* Wraparound */
 	if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
 		slot->seq_nr = 1;
-		return htonl(NFS4_OK);
+		goto out_ok;
 	}
 
 	/* Misordered request */
 	return htonl(NFS4ERR_SEQ_MISORDERED);
+out_ok:
+	tbl->highest_used_slotid = args->csa_slotid;
+	return htonl(NFS4_OK);
 }
 
 /*
@@ -418,26 +421,32 @@ __be32 nfs4_callback_sequence(struct cb_
 			      struct cb_sequenceres *res,
 			      struct cb_process_state *cps)
 {
+	struct nfs4_slot_table *tbl;
 	struct nfs_client *clp;
 	int i;
 	__be32 status = htonl(NFS4ERR_BADSESSION);
 
-	cps->clp = NULL;
-
 	clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid);
 	if (clp == NULL)
 		goto out;
 
+	tbl = &clp->cl_session->bc_slot_table;
+
+	spin_lock(&tbl->slot_tbl_lock);
 	/* state manager is resetting the session */
 	if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) {
-		status = NFS4ERR_DELAY;
+		spin_unlock(&tbl->slot_tbl_lock);
+		status = htonl(NFS4ERR_DELAY);
 		goto out;
 	}
 
 	status = validate_seqid(&clp->cl_session->bc_slot_table, args);
+	spin_unlock(&tbl->slot_tbl_lock);
 	if (status)
 		goto out;
 
+	cps->slotid = args->csa_slotid;
+
 	/*
 	 * Check for pending referring calls.  If a match is found, a
 	 * related callback was received before the response to the original
@@ -454,7 +463,6 @@ __be32 nfs4_callback_sequence(struct cb_
 	res->csr_slotid = args->csa_slotid;
 	res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
 	res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
-	nfs4_cb_take_slot(clp);
 
 out:
 	cps->clp = clp; /* put in nfs4_callback_compound */
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -754,26 +754,15 @@ static void nfs4_callback_free_slot(stru
 	 * Let the state manager know callback processing done.
 	 * A single slot, so highest used slotid is either 0 or -1
 	 */
-	tbl->highest_used_slotid--;
+	tbl->highest_used_slotid = -1;
 	nfs4_check_drain_bc_complete(session);
 	spin_unlock(&tbl->slot_tbl_lock);
 }
 
-static void nfs4_cb_free_slot(struct nfs_client *clp)
+static void nfs4_cb_free_slot(struct cb_process_state *cps)
 {
-	if (clp && clp->cl_session)
-		nfs4_callback_free_slot(clp->cl_session);
-}
-
-/* A single slot, so highest used slotid is either 0 or -1 */
-void nfs4_cb_take_slot(struct nfs_client *clp)
-{
-	struct nfs4_slot_table *tbl = &clp->cl_session->bc_slot_table;
-
-	spin_lock(&tbl->slot_tbl_lock);
-	tbl->highest_used_slotid++;
-	BUG_ON(tbl->highest_used_slotid != 0);
-	spin_unlock(&tbl->slot_tbl_lock);
+	if (cps->slotid != -1)
+		nfs4_callback_free_slot(cps->clp->cl_session);
 }
 
 #else /* CONFIG_NFS_V4_1 */
@@ -784,7 +773,7 @@ preprocess_nfs41_op(int nop, unsigned in
 	return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
 }
 
-static void nfs4_cb_free_slot(struct nfs_client *clp)
+static void nfs4_cb_free_slot(struct cb_process_state *cps)
 {
 }
 #endif /* CONFIG_NFS_V4_1 */
@@ -866,6 +855,7 @@ static __be32 nfs4_callback_compound(str
 	struct cb_process_state cps = {
 		.drc_status = 0,
 		.clp = NULL,
+		.slotid = -1,
 	};
 	unsigned int nops = 0;
 
@@ -906,7 +896,7 @@ static __be32 nfs4_callback_compound(str
 
 	*hdr_res.status = status;
 	*hdr_res.nops = htonl(nops);
-	nfs4_cb_free_slot(cps.clp);
+	nfs4_cb_free_slot(&cps);
 	nfs_put_client(cps.clp);
 	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
 	return rpc_success;



  parent reply	other threads:[~2011-08-27 14:59 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-26 21:51 [00/35] 3.0.4-stable review Greg KH
2011-08-26 21:49 ` [01/35] genirq: Fix wrong bit operation Greg KH
2011-08-26 21:49 ` [02/35] cifs: demote cERROR in build_path_from_dentry to cFYI Greg KH
2011-08-26 21:49 ` [03/35] befs: Validate length of long symbolic links Greg KH
2011-08-26 21:49 ` [04/35] i7core_edac: fixed typo in error count calculation Greg KH
2011-08-26 21:49 ` [05/35] [CIFS] possible memory corruption on mount Greg KH
2011-08-26 21:49 ` [06/35] x86, intel, power: Correct the MSR_IA32_ENERGY_PERF_BIAS message Greg KH
2011-08-26 21:49 ` [07/35] pnfs-obj: Fix the comp_index != 0 case Greg KH
2011-08-26 21:49 ` [08/35] pnfs-obj: Bug when we are running out of bio Greg KH
2011-08-26 21:49 ` Greg KH [this message]
2011-08-26 21:49 ` [10/35] NFSv4.1: Return NFS4ERR_BADSESSION to callbacks during session resets Greg KH
2011-08-26 21:49 ` [11/35] x86, mtrr: lock stop machine during MTRR rendezvous sequence Greg KH
2011-08-26 21:49 ` [12/35] Btrfs: detect wether a device supports discard Greg KH
2011-08-26 21:49 ` [13/35] loop: fix deadlock when sysfs and LOOP_CLR_FD race against each other Greg KH
2011-08-26 21:49 ` [14/35] Btrfs: fix an oops of log replay Greg KH
2011-08-26 21:49 ` [15/35] ALSA: usb-audio - Fix missing mixer dB information Greg KH
2011-08-26 21:49 ` [16/35] ALSA: snd_usb_caiaq: track submitted output urbs Greg KH
2011-08-26 21:49 ` [17/35] ALSA: ac97: Add HP Compaq dc5100 SFF(PT003AW) to Headphone Jack Sense whitelist Greg KH
2011-08-26 21:49 ` [18/35] ext4: Fix ext4_should_writeback_data() for no-journal mode Greg KH
2011-08-26 21:49 ` [19/35] ext4: call ext4_ioend_wait and ext4_flush_completed_IO in ext4_evict_inode Greg KH
2011-08-26 21:49 ` [20/35] ext4: Resolve the hang of direct i/o read in handling EXT4_IO_END_UNWRITTEN Greg KH
2011-08-26 21:49 ` [21/35] ext4: fix nomblk_io_submit option so it correctly converts uninit blocks Greg KH
2011-08-26 21:49 ` [22/35] xen-blkfront: Drop name and minor adjustments for emulated scsi devices Greg KH
2011-08-26 21:49 ` [23/35] xen-blkfront: Fix one off warning about name clash Greg KH
2011-08-26 21:49 ` [24/35] xen/x86: replace order-based range checking of M2P table by linear one Greg KH
2011-08-26 21:49 ` [25/35] xen: Do not enable PV IPIs when vector callback not present Greg KH
2011-08-26 21:49 ` [26/35] x86, olpc: Wait for last byte of EC command to be accepted Greg KH
2011-08-26 21:49 ` [27/35] x86-32, vdso: On system call restart after SYSENTER, use int $0x80 Greg KH
2011-08-26 21:49 ` [28/35] x86, UV: Remove UV delay in starting slave cpus Greg KH
2011-08-26 21:49 ` [29/35] drm/ttm: fix ttm_bo_add_ttm(user) failure path Greg KH
2011-08-26 21:49 ` [30/35] drm/radeon: Extended DDC Probing for Toshiba L300D Radeon Mobility X1100 HDMI-A Connector Greg KH
2011-08-26 21:49 ` [31/35] fuse: check size of FUSE_NOTIFY_INVAL_ENTRY message Greg KH
2011-08-26 21:49 ` [32/35] rt2x00: fix order of entry flags modification Greg KH
2011-08-29  8:29   ` Stanislaw Gruszka
2011-08-30 21:53     ` [stable] " Greg KH
2011-08-26 21:49 ` [33/35] mmc: sdhci: fix retuning timer wrongly deleted in sdhci_tasklet_finish Greg KH
2011-08-26 21:49 ` [34/35] igb: Fix lack of flush after register write and before delay Greg KH
2011-08-26 21:49 ` [35/35] Add a personality to report 2.6.x version numbers Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110826215053.815842209@clark.kroah.org \
    --to=gregkh@suse.de \
    --cc=Trond.Myklebust@netapp.com \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable-review@kernel.org \
    --cc=stable@kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®