Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1269609

[PATCH 3.2 45/60] md/raid1: ensure device failure recorded before write request returns.

From Ben Hutchings <ben@decadent.org.uk>
Newsgroups linux.kernel
Subject [PATCH 3.2 45/60] md/raid1: ensure device failure recorded before write request returns.
Date 2015-11-15 03:20 +0100
Message-ID <quV59-3JS-45@gated-at.bofh.it> (permalink)
References <quUVr-3GF-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


3.2.73-rc1 review patch.  If anyone has any objections, please let me know.

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

From: NeilBrown <neilb@suse.com>

commit 55ce74d4bfe1b9444436264c637f39a152d1e5ac upstream.

When a write to one of the legs of a RAID1 fails, the failure is
recorded in the metadata of the other leg(s) so that after a restart
the data on the failed drive wont be trusted even if that drive seems
to be working again  (maybe a cable was unplugged).

Similarly when we record a bad-block in response to a write failure,
we must not let the write complete until the bad-block update is safe.

Currently there is no interlock between the write request completing
and the metadata update.  So it is possible that the write will
complete, the app will confirm success in some way, and then the
machine will crash before the metadata update completes.

This is an extremely small hole for a racy to fit in, but it is
theoretically possible and so should be closed.

So:
 - set MD_CHANGE_PENDING when requesting a metadata update for a
   failed device, so we can know with certainty when it completes
 - queue requests that experienced an error on a new queue which
   is only processed after the metadata update completes
 - call raid_end_bio_io() on bios in that queue when the time comes.

Signed-off-by: NeilBrown <neilb@suse.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/md/md.c    |  1 +
 drivers/md/raid1.c | 29 ++++++++++++++++++++++++++++-
 drivers/md/raid1.h |  5 +++++
 3 files changed, 34 insertions(+), 1 deletion(-)

--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7895,6 +7895,7 @@ int rdev_set_badblocks(struct md_rdev *r
 		/* Make sure they get written out promptly */
 		sysfs_notify_dirent_safe(rdev->sysfs_state);
 		set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags);
+		set_bit(MD_CHANGE_PENDING, &rdev->mddev->flags);
 		md_wakeup_thread(rdev->mddev->thread);
 	}
 	return rv;
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1240,6 +1240,7 @@ static void error(struct mddev *mddev, s
 	 */
 	set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	set_bit(MD_CHANGE_PENDING, &mddev->flags);
 	printk(KERN_ALERT
 	       "md/raid1:%s: Disk failure on %s, disabling device.\n"
 	       "md/raid1:%s: Operation continuing on %d devices.\n",
@@ -1949,6 +1950,7 @@ static void handle_sync_write_finished(s
 static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
 {
 	int m;
+	bool fail = false;
 	for (m = 0; m < conf->raid_disks ; m++)
 		if (r1_bio->bios[m] == IO_MADE_GOOD) {
 			struct md_rdev *rdev = conf->mirrors[m].rdev;
@@ -1961,6 +1963,7 @@ static void handle_write_finished(struct
 			 * narrow down and record precise write
 			 * errors.
 			 */
+			fail = true;
 			if (!narrow_write_error(r1_bio, m)) {
 				md_error(conf->mddev,
 					 conf->mirrors[m].rdev);
@@ -1972,7 +1975,13 @@ static void handle_write_finished(struct
 		}
 	if (test_bit(R1BIO_WriteError, &r1_bio->state))
 		close_write(r1_bio);
-	raid_end_bio_io(r1_bio);
+	if (fail) {
+		spin_lock_irq(&conf->device_lock);
+		list_add(&r1_bio->retry_list, &conf->bio_end_io_list);
+		spin_unlock_irq(&conf->device_lock);
+		md_wakeup_thread(conf->mddev->thread);
+	} else
+		raid_end_bio_io(r1_bio);
 }
 
 static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
@@ -2075,6 +2084,23 @@ static void raid1d(struct mddev *mddev)
 
 	md_check_recovery(mddev);
 
+	if (!list_empty_careful(&conf->bio_end_io_list) &&
+	    !test_bit(MD_CHANGE_PENDING, &mddev->flags)) {
+		LIST_HEAD(tmp);
+		spin_lock_irqsave(&conf->device_lock, flags);
+		if (!test_bit(MD_CHANGE_PENDING, &mddev->flags)) {
+			list_add(&tmp, &conf->bio_end_io_list);
+			list_del_init(&conf->bio_end_io_list);
+		}
+		spin_unlock_irqrestore(&conf->device_lock, flags);
+		while (!list_empty(&tmp)) {
+			r1_bio = list_first_entry(&conf->bio_end_io_list,
+						  struct r1bio, retry_list);
+			list_del(&r1_bio->retry_list);
+			raid_end_bio_io(r1_bio);
+		}
+	}
+
 	blk_start_plug(&plug);
 	for (;;) {
 
@@ -2473,6 +2499,7 @@ static struct r1conf *setup_conf(struct
 	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
 	INIT_LIST_HEAD(&conf->retry_list);
+	INIT_LIST_HEAD(&conf->bio_end_io_list);
 
 	spin_lock_init(&conf->resync_lock);
 	init_waitqueue_head(&conf->wait_barrier);
--- a/drivers/md/raid1.h
+++ b/drivers/md/raid1.h
@@ -43,6 +43,11 @@ struct r1conf {
 	 * block, or anything else.
 	 */
 	struct list_head	retry_list;
+	/* A separate list of r1bio which just need raid_end_bio_io called.
+	 * This mustn't happen for writes which had any errors if the superblock
+	 * needs to be written.
+	 */
+	struct list_head	bio_end_io_list;
 
 	/* queue pending writes to be submitted on unplug */
 	struct bio_list		pending_bio_list;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 3.2 00/60] 3.2.73-rc1 review Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 43/60] dm btree remove: fix a bug when rebalancing  nodes after removal Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 27/60] 3w-9xxx: don't unmap bounce buffered commands Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 12/60] genirq: Fix race in register_irq_proc() Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 31/60] iommu/vt-d: fix range computation when making  room for large pages Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 28/60] xen-blkfront: check for null drvdata in  blkback_changed (XenbusStateClosing) Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 32/60] xhci: don't finish a TD if we get a short  transfer event mid TD Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 46/60] md/raid1: don't clear bitmap bit when  bad-block-list write fails. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 24/60] iwlwifi: dvm: fix D3 firmware PN programming Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 04/60] regmap: debugfs: Don't bother actually printing  when calculating max length Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:10 +0100
  [PATCH 3.2 55/60] asix: Don't reset PHY on if_up for ASIX 88772 Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 08/60] UBI: Validate data_size Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 53/60] skbuff: Fix skb checksum partial check. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 38/60] IB/cm: Fix rb-tree duplicate free and  use-after-free Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 20/60] usb: Add device quirk for Logitech PTZ cameras Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 33/60] xhci: handle no ping response error properly Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 19/60] USB: Add reset-resume quirk for two Plantronics  usb headphones. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 44/60] dm btree: fix leak of bufio-backed block in  btree_split_beneath error path Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 40/60] powerpc/rtas: Validate rtas.entry before  calling enter_rtas() Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 34/60] xhci: Switch Intel Lynx Point LP ports to EHCI  on shutdown. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 07/60] x86/xen: Do not clip xen_e820_map to  xen_e820_map_entries when sanitizing map Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 03/60] regmap: debugfs: Ensure we don't underflow when  printing access masks Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 51/60] net: add length argument to  skb_copy_and_csum_datagram_iovec Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 05/60] ath9k: declare required extra tx headroom Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 39/60] drm/nouveau/gem: return only valid domain when  there's only one Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 06/60] m68k: Define asmlinkage_protect Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 26/60] sched/core: Fix TASK_DEAD race in  finish_task_switch() Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 45/60] md/raid1: ensure device failure recorded before  write request returns. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 15/60] md/raid0: update queue parameter in a safer  location. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 59/60] KEYS: Fix race between key destruction and  finding a keyring by name Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 23/60] ppp: don't override sk->sk_state in  pppoe_flush_dev() Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 49/60] mvsas: Fix NULL pointer dereference in  mvs_slot_task_free Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 58/60] KVM: x86: work around infinite loop in  microcode when #AC is delivered Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:20 +0100
  [PATCH 3.2 42/60] ppp: fix pppoe_dev deletion condition in  pppoe_release() Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 10/60] MIPS: dma-default: Fix 32-bit fall back to GFP_DMA Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 50/60] sched: declare pid_alive as inline Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 17/60] clocksource: Fix abs() usage w/ 64bit values Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 36/60] crypto: api - Only abort operations on fatal signal Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 16/60] md/raid0: apply base queue limits *before*  disk_stack_limits Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 47/60] md/raid10: ensure device failure recorded  before write request returns. Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 57/60] Failing to send a CLOSE if file is opened  WRONLY and server reboots on a 4.x mount Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  [PATCH 3.2 14/60] [SMB3] Do not fall back to SMBWriteX in  set_file_size error cases Ben Hutchings <ben@decadent.org.uk> - 2015-11-15 03:30 +0100
  Re: [PATCH 3.2 00/60] 3.2.73-rc1 review Guenter Roeck <linux@roeck-us.net> - 2015-11-15 14:50 +0100
    Re: [PATCH 3.2 00/60] 3.2.73-rc1 review Ben Hutchings <ben@decadent.org.uk> - 2015-11-16 12:20 +0100

csiph-web