Bug#696650: [PATCH v5] md: protect against crash upon fsync on ro array

2013-01-31 Thread Sebastian Riemer
Hi Neil,

please apply this patch! It is correct, now.

It applies to 3.2.y, 3.4.y, 3.7.y and latest 3.8-rc5. All these versions
are affected by this bug.

3.0.y and 2.6.34.y are also affected. Please also find the patches for
these versions attached. I've tested them. They work.

The strange thing is that 2.6.32.y is immune against this bug. So it
must be a regression. The patch restores the same behavior as present in
2.6.32: fsync receives success.

I've tested against the following versions: 3.8-rc5, 3.7.5, 3.4.28,
3.2.37, 3.0.61, 2.6.34.14 and 2.6.32.60.

Cheers,
Sebastian


On 29.01.2013 13:29, Paul Menzel wrote:
 Any further objection?
 
 Small typo (occurs) in commit message.

From adfac4df99edc1a83dced9c732464634d3381a9f Mon Sep 17 00:00:00 2001
From: Sebastian Riemer sebastian.rie...@profitbricks.com
Date: Fri, 25 Jan 2013 12:46:59 +0100
Subject: [PATCH v5] md: protect against crash upon fsync on ro array

If an fsync occurs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we return success upon a flush
request but we return -EROFS for other writes.
We detect flush requests by checking if the bio has zero sectors.

Cc: Christoph Hellwig h...@infradead.org
Cc: Ben Hutchings b...@decadent.org.uk
Cc: NeilBrown ne...@suse.de
Signed-off-by: Sebastian Riemer sebastian.rie...@profitbricks.com
Reported-by: Ben Hutchings b...@decadent.org.uk
Acked-by: Paul Menzel paulepan...@users.sourceforge.net
---
 drivers/md/md.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3db3d1b..1e634a6 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, 
struct bio *bio)
bio_io_error(bio);
return;
}
+   if (mddev-ro == 1  unlikely(rw == WRITE)) {
+   bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
+   return;
+   }
smp_rmb(); /* Ensure implications of  'active' are visible */
rcu_read_lock();
if (mddev-suspended) {
-- 
1.7.1
From 58ecc54ef2ea1692b2a608183901708d3cad5120 Mon Sep 17 00:00:00 2001
From: Sebastian Riemer sebastian.rie...@profitbricks.com
Date: Fri, 25 Jan 2013 12:46:59 +0100
Subject: [PATCH 3.0.y] md: protect against crash upon fsync on ro array
Reply-To: linux-raid linux-r...@vger.kernel.org

If an fsync occurs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we return success upon a flush
request but we return -EROFS for other writes.
We detect flush requests by checking if the bio has zero sectors.

Cc: Christoph Hellwig h...@infradead.org
Cc: Ben Hutchings b...@decadent.org.uk
Cc: NeilBrown ne...@suse.de
Signed-off-by: Sebastian Riemer sebastian.rie...@profitbricks.com
Reported-by: Ben Hutchings b...@decadent.org.uk
Acked-by: Paul Menzel paulepan...@users.sourceforge.net
---
 drivers/md/md.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 98262e5..4ef75e9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -299,6 +299,10 @@ static int md_make_request(struct request_queue *q, struct 
bio *bio)
bio_io_error(bio);
return 0;
}
+   if (mddev-ro == 1  unlikely(rw == WRITE)) {
+   bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
+   return 0;
+   }
smp_rmb(); /* Ensure implications of  'active' are visible */
rcu_read_lock();
if (mddev-suspended) {
-- 
1.7.1

From 58ecc54ef2ea1692b2a608183901708d3cad5120 Mon Sep 17 00:00:00 2001
From: Sebastian Riemer sebastian.rie...@profitbricks.com
Date: Fri, 25 Jan 2013 12:46:59 +0100
Subject: [PATCH 2.6.34.y] md: protect against crash upon fsync on ro array
Reply-To: linux-raid linux-r...@vger.kernel.org

If an fsync occurs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we return success upon a flush
request but we return -EROFS for other writes.
We detect flush requests by checking if the bio has zero sectors.

Cc: Christoph Hellwig h...@infradead.org
Cc: Ben Hutchings b...@decadent.org.uk
Cc: NeilBrown ne...@suse.de
Signed-off-by: Sebastian Riemer sebastian.rie...@profitbricks.com
Reported-by: Ben Hutchings b...@decadent.org.uk
Acked-by: Paul Menzel paulepan...@users.sourceforge.net
---
 drivers/md/md.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index d8e5adc..ba1c0be 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -221,6 +221,10 @@ static int

Bug#696650: [PATCH v4] md: protect against crash upon fsync on ro array

2013-01-29 Thread Sebastian Riemer
On 29.01.2013 06:45, Ben Hutchings wrote:
 I'm slightly uneasy about returning 0 for all writes to a read-only
 deivce, because if someone ever fails to check the read-only flag
 elsewhere this could turn into silent data loss.  Does this work:
 
   BUG_ON(bio_segments(bio));
 
 Or should it be:
 
   bio_endio(bio, bio_segments(bio) == 0 ? 0 : -EROFS);
 
 to make the error survivable?

Good point. But it's better to use bio_sectors as bi_size is the
important information. I've seen that DRBD detects empty flushes the
same way.

For testing I've disabled the set_disk_ro in md_set_readonly. Then,
I did direct IO writes on the read-only array and it worked - I've
received Input/output error in the user space.

I've attached version 4 of the patch.

Any further objection?
From adfac4df99edc1a83dced9c732464634d3381a9f Mon Sep 17 00:00:00 2001
From: Sebastian Riemer sebastian.rie...@profitbricks.com
Date: Fri, 25 Jan 2013 12:46:59 +0100
Subject: [PATCH v4] md: protect against crash upon fsync on ro array

If an fsync occurrs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we return success upon a flush
request but we return -EROFS for other writes.
We detect flush requests by checking if the bio has zero sectors.

Cc: Christoph Hellwig h...@infradead.org
Cc: Ben Hutchings b...@decadent.org.uk
Cc: NeilBrown ne...@suse.de
Signed-off-by: Sebastian Riemer sebastian.rie...@profitbricks.com
Reported-by: Ben Hutchings b...@decadent.org.uk
---
 drivers/md/md.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3db3d1b..1e634a6 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, 
struct bio *bio)
bio_io_error(bio);
return;
}
+   if (mddev-ro == 1  unlikely(rw == WRITE)) {
+   bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
+   return;
+   }
smp_rmb(); /* Ensure implications of  'active' are visible */
rcu_read_lock();
if (mddev-suspended) {
-- 
1.7.1



Bug#696650: [PATCH v2] md: protect against crash upon fsync on ro array

2013-01-28 Thread Sebastian Riemer
Subject was: Re: fsync() on read-only RAID triggers BUG

On 27.01.2013 17:39, Christoph Hellwig wrote:
 On Sat, Jan 26, 2013 at 07:44:40PM +, Ben Hutchings wrote:
 I applied this on top of 3.2.37 and it certainly fixes the crash.
 However I wonder whether fsync() should fail or should immediately
 succeed.  I don't know whether the installer expects it to succeed.
 
 It should succeed.

O.K., then I hope Neil applies the attached patch. I've changed the
return value to success.

This is also something for linux-stable and should apply to many kernel
versions without an issue.
From fe0357344877c9b9cc623fd582a4e0670e448317 Mon Sep 17 00:00:00 2001
From: Sebastian Riemer sebastian.rie...@profitbricks.com
Date: Fri, 25 Jan 2013 12:46:59 +0100
Subject: [PATCH v2] md: protect against crash upon fsync on ro array

If an fsync occurrs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we silently return success.

Cc: Christoph Hellwig h...@infradead.org
Cc: Ben Hutchings b...@decadent.org.uk
Cc: NeilBrown ne...@suse.de
Signed-off-by: Sebastian Riemer sebastian.rie...@profitbricks.com
Reported-by: Ben Hutchings b...@decadent.org.uk

---
 drivers/md/md.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3db3d1b..475e0be 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -322,6 +322,11 @@ static void md_make_request(struct request_queue *q, 
struct bio *bio)
}
finish_wait(mddev-sb_wait, __wait);
}
+   if (mddev-ro == 1  unlikely(rw == WRITE)) {
+   rcu_read_unlock();
+   bio_endio(bio, 0);
+   return;
+   }
atomic_inc(mddev-active_io);
rcu_read_unlock();
 
-- 
1.7.1



Bug#696650: [PATCH v3] md: protect against crash upon fsync on ro array

2013-01-28 Thread Sebastian Riemer
On 28.01.2013 11:32, Sebastian Riemer wrote:
 O.K., then I hope Neil applies the attached patch. I've changed the
 return value to success.
 
 This is also something for linux-stable and should apply to many kernel
 versions without an issue.
 

I've tried to race with continuous fsyncs against continuous mdadm -o
/dev/md0; mdadm -w /dev/md0; in parallel but couldn't break it.
Therefore, no additional locking is required and this part can be put
directly before the RCU locking stuff and the suspended handling.

I've attached version 3 of the patch.
From fe0357344877c9b9cc623fd582a4e0670e448317 Mon Sep 17 00:00:00 2001
From: Sebastian Riemer sebastian.rie...@profitbricks.com
Date: Fri, 25 Jan 2013 12:46:59 +0100
Subject: [PATCH v3] md: protect against crash upon fsync on ro array

If an fsync occurrs on a read-only array, we need to send a
completion for the IO and may not increment the active IO count.
Otherwise, we hit a bug trace and can't stop the MD array anymore.

By advice of Christoph Hellwig we silently return success.

Cc: Christoph Hellwig h...@infradead.org
Cc: Ben Hutchings b...@decadent.org.uk
Cc: NeilBrown ne...@suse.de
Signed-off-by: Sebastian Riemer sebastian.rie...@profitbricks.com
Reported-by: Ben Hutchings b...@decadent.org.uk

---
 drivers/md/md.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3db3d1b..6ba20f7 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, 
struct bio *bio)
bio_io_error(bio);
return;
}
+   if (mddev-ro == 1  unlikely(rw == WRITE)) {
+   bio_endio(bio, 0);
+   return;
+   }
smp_rmb(); /* Ensure implications of  'active' are visible */
rcu_read_lock();
if (mddev-suspended) {