* [PATCH md 000 of 7] Introduction
@ 2005-08-02 9:53 NeilBrown
2005-08-04 5:10 ` Andrew Morton
0 siblings, 1 reply; 12+ messages in thread
From: NeilBrown @ 2005-08-02 9:53 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
Following are 7 patches for md in 2.6.13-rc4
They are all fairly well tested, with the possible exception of '4' -
I haven't actually tried throwing BIO_RW_BARRIER requests are any md
devices. However the code is very straight forward.
I'm happy (even keen) for these to go into 2.6.13.
If it's getting a bit late, then 2 is probably the most important.
The others we can probably live without.
Thanks,
NeilBrown
[PATCH md 001 of 7] Remove a stray debugging printk.
[PATCH md 002 of 7] Make 'md' and alias for 'md-mod'
[PATCH md 003 of 7] Fix minor error in raid10 read-balancing calculation.
[PATCH md 004 of 7] Fail IO requests to md that require a barrier.
[PATCH md 005 of 7] Always honour md bitmap being read from disk
[PATCH md 006 of 7] Yet another attempt to get bitmap-based resync to do the right thing in all cases...
[PATCH md 007 of 7] Make sure md bitmap updates are flushed when array is stopped.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH md 000 of 7] Introduction
2005-08-02 9:53 [PATCH md 000 of 7] Introduction NeilBrown
@ 2005-08-04 5:10 ` Andrew Morton
2005-08-04 5:36 ` Neil Brown
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2005-08-04 5:10 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-raid
NeilBrown <neilb@cse.unsw.edu.au> wrote:
>
>
> Following are 7 patches for md in 2.6.13-rc4
> They are all fairly well tested, with the possible exception of '4' -
> I haven't actually tried throwing BIO_RW_BARRIER requests are any md
> devices. However the code is very straight forward.
>
> I'm happy (even keen) for these to go into 2.6.13.
> If it's getting a bit late, then 2 is probably the most important.
> The others we can probably live without.
>
hm, OK. Merging 1) and 2) seems sane. I must say that I worry about 4)
and would prefer to defer things if poss.
If there are others there which you really would prefer to see in 2.6.13
then please let me know.
>
>
> [PATCH md 001 of 7] Remove a stray debugging printk.
> [PATCH md 002 of 7] Make 'md' and alias for 'md-mod'
> [PATCH md 003 of 7] Fix minor error in raid10 read-balancing calculation.
> [PATCH md 004 of 7] Fail IO requests to md that require a barrier.
> [PATCH md 005 of 7] Always honour md bitmap being read from disk
> [PATCH md 006 of 7] Yet another attempt to get bitmap-based resync to do the right thing in all cases...
> [PATCH md 007 of 7] Make sure md bitmap updates are flushed when array is stopped.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH md 000 of 7] Introduction
2005-08-04 5:10 ` Andrew Morton
@ 2005-08-04 5:36 ` Neil Brown
2005-08-04 5:45 ` Andrew Morton
0 siblings, 1 reply; 12+ messages in thread
From: Neil Brown @ 2005-08-04 5:36 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
On Wednesday August 3, akpm@osdl.org wrote:
> NeilBrown <neilb@cse.unsw.edu.au> wrote:
> >
> >
> > Following are 7 patches for md in 2.6.13-rc4
> > They are all fairly well tested, with the possible exception of '4' -
> > I haven't actually tried throwing BIO_RW_BARRIER requests are any md
> > devices. However the code is very straight forward.
> >
> > I'm happy (even keen) for these to go into 2.6.13.
> > If it's getting a bit late, then 2 is probably the most important.
> > The others we can probably live without.
> >
>
> hm, OK. Merging 1) and 2) seems sane. I must say that I worry about 4)
> and would prefer to defer things if poss.
Fair enough. 4 can wait until 2.6.14 (only a couple of months away,
right :-)
>
> If there are others there which you really would prefer to see in 2.6.13
> then please let me know.
>
5, 6, and 7 I would really prefer to be in 2.6.13.
The intent-bitmap stuff is broken (in small but potentially
significant ways) without them, and they are complete no-ops if
bitmaps aren't enabled:
5 only touches bitmap.c
6 removes the setting for R1BIO_Degraded which is not used and
slightly re-arranges an 'if' statement. All other changes are
complete no-ops if bitmaps aren't enabled.
7: if bitmaps aren't enabled, all this does is call "wait_event"
exactly the same way as will very possibly be called a few lines
later when md_update_sb is called.
So I'm convinced (and hopefully convincing) that they don't have any
significant effect if bitmaps aren't enabled, and fix genuine problems
with bitmaps, and so are appropriate for 2.6.13...
Thanks,
NeilBrown
>
> >
> >
> > [PATCH md 001 of 7] Remove a stray debugging printk.
> > [PATCH md 002 of 7] Make 'md' and alias for 'md-mod'
> > [PATCH md 003 of 7] Fix minor error in raid10 read-balancing calculation.
> > [PATCH md 004 of 7] Fail IO requests to md that require a barrier.
> > [PATCH md 005 of 7] Always honour md bitmap being read from disk
> > [PATCH md 006 of 7] Yet another attempt to get bitmap-based resync to do the right thing in all cases...
> > [PATCH md 007 of 7] Make sure md bitmap updates are flushed when array is stopped.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH md 000 of 7] Introduction
2005-08-04 5:36 ` Neil Brown
@ 2005-08-04 5:45 ` Andrew Morton
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Morton @ 2005-08-04 5:45 UTC (permalink / raw)
To: Neil Brown; +Cc: linux-raid
Neil Brown <neilb@cse.unsw.edu.au> wrote:
>
> On Wednesday August 3, akpm@osdl.org wrote:
> > NeilBrown <neilb@cse.unsw.edu.au> wrote:
> > >
> > >
> > > Following are 7 patches for md in 2.6.13-rc4
> > > They are all fairly well tested, with the possible exception of '4' -
> > > I haven't actually tried throwing BIO_RW_BARRIER requests are any md
> > > devices. However the code is very straight forward.
> > >
> > > I'm happy (even keen) for these to go into 2.6.13.
> > > If it's getting a bit late, then 2 is probably the most important.
> > > The others we can probably live without.
> > >
> >
> > hm, OK. Merging 1) and 2) seems sane. I must say that I worry about 4)
> > and would prefer to defer things if poss.
>
> Fair enough. 4 can wait until 2.6.14 (only a couple of months away,
> right :-)
Thereabouts..
> >
> > If there are others there which you really would prefer to see in 2.6.13
> > then please let me know.
> >
>
> 5, 6, and 7 I would really prefer to be in 2.6.13.
OK.
> The intent-bitmap stuff is broken (in small but potentially
> significant ways) without them, and they are complete no-ops if
> bitmaps aren't enabled:
> 5 only touches bitmap.c
> 6 removes the setting for R1BIO_Degraded which is not used and
> slightly re-arranges an 'if' statement. All other changes are
> complete no-ops if bitmaps aren't enabled.
> 7: if bitmaps aren't enabled, all this does is call "wait_event"
> exactly the same way as will very possibly be called a few lines
> later when md_update_sb is called.
>
> So I'm convinced (and hopefully convincing) that they don't have any
> significant effect if bitmaps aren't enabled, and fix genuine problems
> with bitmaps, and so are appropriate for 2.6.13...
We'll see ;)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 000 of 7] Introduction
@ 2005-08-29 7:33 NeilBrown
2005-08-29 7:33 ` [PATCH md 001 of 7] Remove old cruft from md_k.h header file NeilBrown
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
Herewith, a group of patches for md/raid in 2.6.13-mm.
They (together with the md patches already in -mm) are all appropriate
for the flood which will be pouring in to Linus now that 2.6.13 is
out.
There are a few bug fixes (it's SO good having a test suite to help find these),
a couple of code cleanups, and the write-intent-logging stuff is now supported
on raid4/5/6 as well as raid1.
Thanks,
NeilBrown
[PATCH md 001 of 7] Remove old cruft from md_k.h header file.
[PATCH md 002 of 7] Limit size of sb read/written to appropriate amount.
[PATCH md 003 of 7] Add write-intent-bitmap support to raid5
[PATCH md 004 of 7] write-intent bitmap support for raid6
[PATCH md 005 of 7] Use kthread infrastructure in md
[PATCH md 006 of 7] Ensure bitmap_writeback_daemon handles shutdown properly.
[PATCH md 007 of 7] Tidy up daemon stop/start code in md/bitmap.c
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 006 of 7] Ensure bitmap_writeback_daemon handles shutdown properly.
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
2005-08-29 7:33 ` [PATCH md 001 of 7] Remove old cruft from md_k.h header file NeilBrown
2005-08-29 7:33 ` [PATCH md 004 of 7] write-intent bitmap support for raid6 NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
2005-08-29 7:33 ` [PATCH md 007 of 7] Tidy up daemon stop/start code in md/bitmap.c NeilBrown
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
mddev->bitmap gets clearred before the writeback daemon is stopped.
So the write_back daemon needs to be careful not to dereference
the 'bitmap' if it is NULL.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./drivers/md/bitmap.c | 3 +++
1 file changed, 3 insertions(+)
diff ./drivers/md/bitmap.c~current~ ./drivers/md/bitmap.c
--- ./drivers/md/bitmap.c~current~ 2005-08-29 16:32:20.000000000 +1000
+++ ./drivers/md/bitmap.c 2005-08-29 16:46:50.000000000 +1000
@@ -1156,6 +1156,9 @@ static void bitmap_writeback_daemon(mdde
err = -EINTR;
goto out;
}
+ if (bitmap == NULL)
+ /* about to be stopped. */
+ return;
PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap));
/* wait on bitmap page writebacks */
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 007 of 7] Tidy up daemon stop/start code in md/bitmap.c
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
` (2 preceding siblings ...)
2005-08-29 7:33 ` [PATCH md 006 of 7] Ensure bitmap_writeback_daemon handles shutdown properly NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
2005-08-29 7:33 ` [PATCH md 002 of 7] Limit size of sb read/written to appropriate amount NeilBrown
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
The bitmap code used to have two daemons, so there is some 'common'
start/stop code. But now there is only one, so the common code is
just noise.
This patch tidies this up somewhat.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./drivers/md/bitmap.c | 73 ++++++++++++++++++--------------------------------
1 file changed, 27 insertions(+), 46 deletions(-)
diff ./drivers/md/bitmap.c~current~ ./drivers/md/bitmap.c
--- ./drivers/md/bitmap.c~current~ 2005-08-29 16:46:50.000000000 +1000
+++ ./drivers/md/bitmap.c 2005-08-29 17:04:24.000000000 +1000
@@ -626,7 +626,7 @@ static void bitmap_file_unmap(struct bit
page_cache_release(sb_page);
}
-static void bitmap_stop_daemons(struct bitmap *bitmap);
+static void bitmap_stop_daemon(struct bitmap *bitmap);
/* dequeue the next item in a page list -- don't call from irq context */
static struct page_list *dequeue_page(struct bitmap *bitmap)
@@ -668,7 +668,7 @@ static void bitmap_file_put(struct bitma
bitmap->file = NULL;
spin_unlock_irqrestore(&bitmap->lock, flags);
- bitmap_stop_daemons(bitmap);
+ bitmap_stop_daemon(bitmap);
drain_write_queues(bitmap);
@@ -1188,21 +1188,12 @@ static void bitmap_writeback_daemon(mdde
}
}
-static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr,
+static mdk_thread_t *bitmap_start_daemon(struct bitmap *bitmap,
void (*func)(mddev_t *), char *name)
{
mdk_thread_t *daemon;
- unsigned long flags;
char namebuf[32];
- spin_lock_irqsave(&bitmap->lock, flags);
- *ptr = NULL;
-
- if (!bitmap->file) /* no need for daemon if there's no backing file */
- goto out_unlock;
-
- spin_unlock_irqrestore(&bitmap->lock, flags);
-
#ifdef INJECT_FATAL_FAULT_2
daemon = NULL;
#else
@@ -1212,47 +1203,32 @@ static int bitmap_start_daemon(struct bi
if (!daemon) {
printk(KERN_ERR "%s: failed to start bitmap daemon\n",
bmname(bitmap));
- return -ECHILD;
+ return ERR_PTR(-ECHILD);
}
- spin_lock_irqsave(&bitmap->lock, flags);
- *ptr = daemon;
-
md_wakeup_thread(daemon); /* start it running */
PRINTK("%s: %s daemon (pid %d) started...\n",
bmname(bitmap), name, daemon->tsk->pid);
-out_unlock:
- spin_unlock_irqrestore(&bitmap->lock, flags);
- return 0;
-}
-static int bitmap_start_daemons(struct bitmap *bitmap)
-{
- int err = bitmap_start_daemon(bitmap, &bitmap->writeback_daemon,
- bitmap_writeback_daemon, "bitmap_wb");
- return err;
+ return daemon;
}
-static void bitmap_stop_daemon(struct bitmap *bitmap, mdk_thread_t **ptr)
+static void bitmap_stop_daemon(struct bitmap *bitmap)
{
- mdk_thread_t *daemon;
- unsigned long flags;
-
- spin_lock_irqsave(&bitmap->lock, flags);
- daemon = *ptr;
- *ptr = NULL;
- spin_unlock_irqrestore(&bitmap->lock, flags);
- if (daemon)
- md_unregister_thread(daemon); /* destroy the thread */
-}
+ /* the daemon can't stop itself... it'll just exit instead... */
+ if (bitmap->writeback_daemon && ! IS_ERR(bitmap->writeback_daemon) &&
+ current->pid != bitmap->writeback_daemon->tsk->pid) {
+ mdk_thread_t *daemon;
+ unsigned long flags;
-static void bitmap_stop_daemons(struct bitmap *bitmap)
-{
- /* the daemons can't stop themselves... they'll just exit instead... */
- if (bitmap->writeback_daemon &&
- current->pid != bitmap->writeback_daemon->tsk->pid)
- bitmap_stop_daemon(bitmap, &bitmap->writeback_daemon);
+ spin_lock_irqsave(&bitmap->lock, flags);
+ daemon = bitmap->writeback_daemon;
+ bitmap->writeback_daemon = NULL;
+ spin_unlock_irqrestore(&bitmap->lock, flags);
+ if (daemon && ! IS_ERR(daemon))
+ md_unregister_thread(daemon); /* destroy the thread */
+ }
}
static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
@@ -1637,10 +1613,15 @@ int bitmap_create(mddev_t *mddev)
mddev->bitmap = bitmap;
- /* kick off the bitmap daemons */
- err = bitmap_start_daemons(bitmap);
- if (err)
- return err;
+ if (file)
+ /* kick off the bitmap writeback daemon */
+ bitmap->writeback_daemon =
+ bitmap_start_daemon(bitmap,
+ bitmap_writeback_daemon,
+ "bitmap_wb");
+
+ if (IS_ERR(bitmap->writeback_daemon))
+ return PTR_ERR(bitmap->writeback_daemon);
return bitmap_update_sb(bitmap);
error:
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 004 of 7] write-intent bitmap support for raid6
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
2005-08-29 7:33 ` [PATCH md 001 of 7] Remove old cruft from md_k.h header file NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
2005-08-29 7:33 ` [PATCH md 006 of 7] Ensure bitmap_writeback_daemon handles shutdown properly NeilBrown
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
This is a direct port of the raid5 patch.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./drivers/md/md.c | 2
./drivers/md/raid6main.c | 133 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 124 insertions(+), 11 deletions(-)
diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~ 2005-08-29 16:32:24.000000000 +1000
+++ ./drivers/md/md.c 2005-08-29 16:37:35.000000000 +1000
@@ -645,7 +645,7 @@ static int super_90_validate(mddev_t *md
if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
mddev->bitmap_file == NULL) {
- if (mddev->level != 1 && mddev->level != 5) {
+ if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6) {
/* FIXME use a better test */
printk(KERN_WARNING "md: bitmaps only support for raid1\n");
return -EINVAL;
diff ./drivers/md/raid6main.c~current~ ./drivers/md/raid6main.c
--- ./drivers/md/raid6main.c~current~ 2005-08-29 16:32:20.000000000 +1000
+++ ./drivers/md/raid6main.c 2005-08-29 16:37:35.000000000 +1000
@@ -29,6 +29,8 @@
#include <asm/atomic.h>
#include "raid6.h"
+#include <linux/raid/bitmap.h>
+
/*
* Stripe cache
*/
@@ -98,8 +100,13 @@ static inline void __release_stripe(raid
if (test_bit(STRIPE_HANDLE, &sh->state)) {
if (test_bit(STRIPE_DELAYED, &sh->state))
list_add_tail(&sh->lru, &conf->delayed_list);
- else
+ else if (test_bit(STRIPE_BIT_DELAY, &sh->state) &&
+ conf->seq_write == sh->bm_seq)
+ list_add_tail(&sh->lru, &conf->bitmap_list);
+ else {
+ clear_bit(STRIPE_BIT_DELAY, &sh->state);
list_add_tail(&sh->lru, &conf->handle_list);
+ }
md_wakeup_thread(conf->mddev->thread);
} else {
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
@@ -262,6 +269,9 @@ static struct stripe_head *get_active_st
spin_lock_irq(&conf->device_lock);
do {
+ wait_event_lock_irq(conf->wait_for_stripe,
+ conf->quiesce == 0,
+ conf->device_lock, /* nothing */);
sh = __find_stripe(conf, sector);
if (!sh) {
if (!conf->inactive_blocked)
@@ -906,6 +916,7 @@ static int add_stripe_bio(struct stripe_
{
struct bio **bip;
raid6_conf_t *conf = sh->raid_conf;
+ int firstwrite=0;
PRINTK("adding bh b#%llu to stripe s#%llu\n",
(unsigned long long)bi->bi_sector,
@@ -914,9 +925,11 @@ static int add_stripe_bio(struct stripe_
spin_lock(&sh->lock);
spin_lock_irq(&conf->device_lock);
- if (forwrite)
+ if (forwrite) {
bip = &sh->dev[dd_idx].towrite;
- else
+ if (*bip == NULL && sh->dev[dd_idx].written == NULL)
+ firstwrite = 1;
+ } else
bip = &sh->dev[dd_idx].toread;
while (*bip && (*bip)->bi_sector < bi->bi_sector) {
if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
@@ -939,6 +952,13 @@ static int add_stripe_bio(struct stripe_
(unsigned long long)bi->bi_sector,
(unsigned long long)sh->sector, dd_idx);
+ if (conf->mddev->bitmap && firstwrite) {
+ sh->bm_seq = conf->seq_write;
+ bitmap_startwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0);
+ set_bit(STRIPE_BIT_DELAY, &sh->state);
+ }
+
if (forwrite) {
/* check if page is covered */
sector_t sector = sh->dev[dd_idx].sector;
@@ -1066,12 +1086,13 @@ static void handle_stripe(struct stripe_
* need to be failed
*/
if (failed > 2 && to_read+to_write+written) {
- spin_lock_irq(&conf->device_lock);
for (i=disks; i--; ) {
+ int bitmap_end = 0;
+ spin_lock_irq(&conf->device_lock);
/* fail all writes first */
bi = sh->dev[i].towrite;
sh->dev[i].towrite = NULL;
- if (bi) to_write--;
+ if (bi) { to_write--; bitmap_end = 1; }
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
@@ -1089,6 +1110,7 @@ static void handle_stripe(struct stripe_
/* and fail all 'written' */
bi = sh->dev[i].written;
sh->dev[i].written = NULL;
+ if (bi) bitmap_end = 1;
while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1117,8 +1139,11 @@ static void handle_stripe(struct stripe_
bi = nextbi;
}
}
+ spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0, 0);
}
- spin_unlock_irq(&conf->device_lock);
}
if (failed > 2 && syncing) {
md_done_sync(conf->mddev, STRIPE_SECTORS,0);
@@ -1155,6 +1180,7 @@ static void handle_stripe(struct stripe_
if (!test_bit(R5_LOCKED, &dev->flags) &&
test_bit(R5_UPTODATE, &dev->flags) ) {
/* We can return any write requests */
+ int bitmap_end = 0;
struct bio *wbi, *wbi2;
PRINTK("Return write for stripe %llu disc %d\n",
(unsigned long long)sh->sector, i);
@@ -1170,7 +1196,13 @@ static void handle_stripe(struct stripe_
}
wbi = wbi2;
}
+ if (dev->towrite == NULL)
+ bitmap_end = 1;
spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS,
+ !test_bit(STRIPE_DEGRADED, &sh->state), 0);
}
}
}
@@ -1285,7 +1317,8 @@ static void handle_stripe(struct stripe_
}
}
/* now if nothing is locked, and if we have enough data, we can start a write request */
- if (locked == 0 && rcw == 0) {
+ if (locked == 0 && rcw == 0 &&
+ !test_bit(STRIPE_BIT_DELAY, &sh->state)) {
if ( must_compute > 0 ) {
/* We have failed blocks and need to compute them */
switch ( failed ) {
@@ -1388,6 +1421,7 @@ static void handle_stripe(struct stripe_
bdev = &sh->dev[failed_num[1]];
locked += !test_bit(R5_LOCKED, &bdev->flags);
set_bit(R5_LOCKED, &bdev->flags);
+ clear_bit(STRIPE_DEGRADED, &sh->state);
set_bit(R5_Wantwrite, &bdev->flags);
set_bit(STRIPE_INSYNC, &sh->state);
@@ -1457,6 +1491,8 @@ static void handle_stripe(struct stripe_
bi->bi_next = NULL;
generic_make_request(bi);
} else {
+ if (rw == 1)
+ set_bit(STRIPE_DEGRADED, &sh->state);
PRINTK("skip op %ld on disc %d for sector %llu\n",
bi->bi_rw, i, (unsigned long long)sh->sector);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -1481,6 +1517,20 @@ static inline void raid6_activate_delaye
}
}
+static inline void activate_bit_delay(raid6_conf_t *conf)
+{
+ /* device_lock is held */
+ struct list_head head;
+ list_add(&head, &conf->bitmap_list);
+ list_del_init(&conf->bitmap_list);
+ while (!list_empty(&head)) {
+ struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ atomic_inc(&sh->count);
+ __release_stripe(conf, sh);
+ }
+}
+
static void unplug_slaves(mddev_t *mddev)
{
raid6_conf_t *conf = mddev_to_conf(mddev);
@@ -1513,8 +1563,10 @@ static void raid6_unplug_device(request_
spin_lock_irqsave(&conf->device_lock, flags);
- if (blk_remove_plug(q))
+ if (blk_remove_plug(q)) {
+ conf->seq_flush++;
raid6_activate_delayed(conf);
+ }
md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags);
@@ -1652,10 +1704,20 @@ static sector_t sync_request(mddev_t *md
sector_t first_sector;
int raid_disks = conf->raid_disks;
int data_disks = raid_disks - 2;
+ sector_t max_sector = mddev->size << 1;
+ int sync_blocks;
- if (sector_nr >= mddev->size <<1) {
+ if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
+ if (mddev->curr_resync < max_sector) /* aborted */
+ bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
+ &sync_blocks, 1);
+ else /* compelted sync */
+ conf->fullsync = 0;
+ bitmap_close_sync(mddev->bitmap);
+
return 0;
}
/* if there are 2 or more failed drives and we are trying
@@ -1667,6 +1729,13 @@ static sector_t sync_request(mddev_t *md
*skipped = 1;
return rv;
}
+ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+ !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
+ /* we can skip this block, and probably more */
+ sync_blocks /= STRIPE_SECTORS;
+ *skipped = 1;
+ return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
+ }
x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk);
@@ -1683,6 +1752,7 @@ static sector_t sync_request(mddev_t *md
*/
schedule_timeout_uninterruptible(1);
}
+ bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
spin_lock(&sh->lock);
set_bit(STRIPE_SYNCING, &sh->state);
clear_bit(STRIPE_INSYNC, &sh->state);
@@ -1716,6 +1786,13 @@ static void raid6d (mddev_t *mddev)
while (1) {
struct list_head *first;
+ if (conf->seq_flush - conf->seq_write > 0) {
+ int seq = conf->seq_flush;
+ bitmap_unplug(mddev->bitmap);
+ conf->seq_write = seq;
+ activate_bit_delay(conf);
+ }
+
if (list_empty(&conf->handle_list) &&
atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
!blk_queue_plugged(mddev->queue) &&
@@ -1749,7 +1826,7 @@ static void raid6d (mddev_t *mddev)
PRINTK("--- raid6d inactive\n");
}
-static int run (mddev_t *mddev)
+static int run(mddev_t *mddev)
{
raid6_conf_t *conf;
int raid_disk, memory;
@@ -1779,6 +1856,7 @@ static int run (mddev_t *mddev)
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
INIT_LIST_HEAD(&conf->delayed_list);
+ INIT_LIST_HEAD(&conf->bitmap_list);
INIT_LIST_HEAD(&conf->inactive_list);
atomic_set(&conf->active_stripes, 0);
atomic_set(&conf->preread_active_stripes, 0);
@@ -1898,6 +1976,9 @@ static int run (mddev_t *mddev)
/* Ok, everything is just fine now */
mddev->array_size = mddev->size * (mddev->raid_disks - 2);
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+
mddev->queue->unplug_fn = raid6_unplug_device;
mddev->queue->issue_flush_fn = raid6_issue_flush;
return 0;
@@ -2075,6 +2156,8 @@ static int raid6_add_disk(mddev_t *mddev
rdev->in_sync = 0;
rdev->raid_disk = disk;
found = 1;
+ if (rdev->saved_raid_disk != disk)
+ conf->fullsync = 1;
p->rdev = rdev;
break;
}
@@ -2104,6 +2187,35 @@ static int raid6_resize(mddev_t *mddev,
return 0;
}
+static void raid6_quiesce(mddev_t *mddev, int state)
+{
+ raid6_conf_t *conf = mddev_to_conf(mddev);
+
+ switch(state) {
+ case 1: /* stop all writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 1;
+ wait_event_lock_irq(conf->wait_for_stripe,
+ atomic_read(&conf->active_stripes) == 0,
+ conf->device_lock, /* nothing */);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+
+ case 0: /* re-enable writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 0;
+ wake_up(&conf->wait_for_stripe);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+ }
+ if (mddev->thread) {
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+ else
+ mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+ md_wakeup_thread(mddev->thread);
+ }
+}
static mdk_personality_t raid6_personality=
{
.name = "raid6",
@@ -2118,6 +2230,7 @@ static mdk_personality_t raid6_personali
.spare_active = raid6_spare_active,
.sync_request = sync_request,
.resize = raid6_resize,
+ .quiesce = raid6_quiesce,
};
static int __init raid6_init (void)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 005 of 7] Use kthread infrastructure in md
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
` (5 preceding siblings ...)
2005-08-29 7:33 ` [PATCH md 003 of 7] Add write-intent-bitmap support to raid5 NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
Switch MD to use the kthread infrastructure, to simplify the code and
get rid of tasklist_lock abuse in md_unregister_thread.
Also don't flush signals in md_thread, as the called thread will
always do that.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./drivers/md/md.c | 48 ++++++++++--------------------------------------
1 file changed, 10 insertions(+), 38 deletions(-)
diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~ 2005-08-29 16:37:35.000000000 +1000
+++ ./drivers/md/md.c 2005-08-29 16:37:40.000000000 +1000
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/config.h>
+#include <linux/kthread.h>
#include <linux/linkage.h>
#include <linux/raid/md.h>
#include <linux/raid/bitmap.h>
@@ -3049,18 +3050,6 @@ static int md_thread(void * arg)
{
mdk_thread_t *thread = arg;
- lock_kernel();
-
- /*
- * Detach thread
- */
-
- daemonize(thread->name, mdname(thread->mddev));
-
- current->exit_signal = SIGCHLD;
- allow_signal(SIGKILL);
- thread->tsk = current;
-
/*
* md_thread is a 'system-thread', it's priority should be very
* high. We avoid resource deadlocks individually in each
@@ -3072,14 +3061,14 @@ static int md_thread(void * arg)
* bdflush, otherwise bdflush will deadlock if there are too
* many dirty RAID5 blocks.
*/
- unlock_kernel();
complete(thread->event);
- while (thread->run) {
+ while (!kthread_should_stop()) {
void (*run)(mddev_t *);
wait_event_interruptible_timeout(thread->wqueue,
- test_bit(THREAD_WAKEUP, &thread->flags),
+ test_bit(THREAD_WAKEUP, &thread->flags)
+ || kthread_should_stop(),
thread->timeout);
try_to_freeze();
@@ -3088,11 +3077,8 @@ static int md_thread(void * arg)
run = thread->run;
if (run)
run(thread->mddev);
-
- if (signal_pending(current))
- flush_signals(current);
}
- complete(thread->event);
+
return 0;
}
@@ -3109,11 +3095,9 @@ mdk_thread_t *md_register_thread(void (*
const char *name)
{
mdk_thread_t *thread;
- int ret;
struct completion event;
- thread = (mdk_thread_t *) kmalloc
- (sizeof(mdk_thread_t), GFP_KERNEL);
+ thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
if (!thread)
return NULL;
@@ -3126,8 +3110,8 @@ mdk_thread_t *md_register_thread(void (*
thread->mddev = mddev;
thread->name = name;
thread->timeout = MAX_SCHEDULE_TIMEOUT;
- ret = kernel_thread(md_thread, thread, 0);
- if (ret < 0) {
+ thread->tsk = kthread_run(md_thread, thread, mdname(thread->mddev));
+ if (IS_ERR(thread->tsk)) {
kfree(thread);
return NULL;
}
@@ -3137,21 +3121,9 @@ mdk_thread_t *md_register_thread(void (*
void md_unregister_thread(mdk_thread_t *thread)
{
- struct completion event;
-
- init_completion(&event);
-
- thread->event = &event;
-
- /* As soon as ->run is set to NULL, the task could disappear,
- * so we need to hold tasklist_lock until we have sent the signal
- */
dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
- read_lock(&tasklist_lock);
- thread->run = NULL;
- send_sig(SIGKILL, thread->tsk, 1);
- read_unlock(&tasklist_lock);
- wait_for_completion(&event);
+
+ kthread_stop(thread->tsk);
kfree(thread);
}
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 003 of 7] Add write-intent-bitmap support to raid5
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
` (4 preceding siblings ...)
2005-08-29 7:33 ` [PATCH md 002 of 7] Limit size of sb read/written to appropriate amount NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
2005-08-29 7:33 ` [PATCH md 005 of 7] Use kthread infrastructure in md NeilBrown
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
Most awkward part of this is delaying write requests until bitmap
updates have been flushed.
To achieve this, we have a sequence number (seq_flush) which is incremented
each time the raid5 is unplugged.
If the raid thread notices that this has changed, it flushes
bitmap changes, and assigned the value of seq_flush to seq_write.
When a write request arrives, it is given the number from seq_write, and
that write request may not complete until seq_flush is larger than the saved
seq number.
We have a new queue for storing stripes which are waiting for a bitmap
flush and an extra flag for stripes to record if the write was 'degraded'
and so should not clear the a bit in the bitmap.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./drivers/md/md.c | 3
./drivers/md/raid5.c | 133 +++++++++++++++++++++++++++++++++++++++----
./include/linux/raid/raid5.h | 14 ++++
3 files changed, 137 insertions(+), 13 deletions(-)
diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~ 2005-08-29 16:32:20.000000000 +1000
+++ ./drivers/md/md.c 2005-08-29 16:32:24.000000000 +1000
@@ -645,7 +645,7 @@ static int super_90_validate(mddev_t *md
if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
mddev->bitmap_file == NULL) {
- if (mddev->level != 1) {
+ if (mddev->level != 1 && mddev->level != 5) {
/* FIXME use a better test */
printk(KERN_WARNING "md: bitmaps only support for raid1\n");
return -EINVAL;
@@ -3517,7 +3517,6 @@ void md_done_sync(mddev_t *mddev, int bl
*/
void md_write_start(mddev_t *mddev, struct bio *bi)
{
- DEFINE_WAIT(w);
if (bio_data_dir(bi) != WRITE)
return;
diff ./drivers/md/raid5.c~current~ ./drivers/md/raid5.c
--- ./drivers/md/raid5.c~current~ 2005-08-29 16:32:20.000000000 +1000
+++ ./drivers/md/raid5.c 2005-08-29 16:32:24.000000000 +1000
@@ -24,6 +24,8 @@
#include <linux/bitops.h>
#include <asm/atomic.h>
+#include <linux/raid/bitmap.h>
+
/*
* Stripe cache
*/
@@ -79,8 +81,13 @@ static inline void __release_stripe(raid
if (test_bit(STRIPE_HANDLE, &sh->state)) {
if (test_bit(STRIPE_DELAYED, &sh->state))
list_add_tail(&sh->lru, &conf->delayed_list);
- else
+ else if (test_bit(STRIPE_BIT_DELAY, &sh->state) &&
+ conf->seq_write == sh->bm_seq)
+ list_add_tail(&sh->lru, &conf->bitmap_list);
+ else {
+ clear_bit(STRIPE_BIT_DELAY, &sh->state);
list_add_tail(&sh->lru, &conf->handle_list);
+ }
md_wakeup_thread(conf->mddev->thread);
} else {
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
@@ -244,6 +251,9 @@ static struct stripe_head *get_active_st
spin_lock_irq(&conf->device_lock);
do {
+ wait_event_lock_irq(conf->wait_for_stripe,
+ conf->quiesce == 0,
+ conf->device_lock, /* nothing */);
sh = __find_stripe(conf, sector);
if (!sh) {
if (!conf->inactive_blocked)
@@ -803,6 +813,7 @@ static int add_stripe_bio(struct stripe_
{
struct bio **bip;
raid5_conf_t *conf = sh->raid_conf;
+ int firstwrite=0;
PRINTK("adding bh b#%llu to stripe s#%llu\n",
(unsigned long long)bi->bi_sector,
@@ -811,9 +822,11 @@ static int add_stripe_bio(struct stripe_
spin_lock(&sh->lock);
spin_lock_irq(&conf->device_lock);
- if (forwrite)
+ if (forwrite) {
bip = &sh->dev[dd_idx].towrite;
- else
+ if (*bip == NULL && sh->dev[dd_idx].written == NULL)
+ firstwrite = 1;
+ } else
bip = &sh->dev[dd_idx].toread;
while (*bip && (*bip)->bi_sector < bi->bi_sector) {
if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
@@ -836,6 +849,13 @@ static int add_stripe_bio(struct stripe_
(unsigned long long)bi->bi_sector,
(unsigned long long)sh->sector, dd_idx);
+ if (conf->mddev->bitmap && firstwrite) {
+ sh->bm_seq = conf->seq_write;
+ bitmap_startwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0);
+ set_bit(STRIPE_BIT_DELAY, &sh->state);
+ }
+
if (forwrite) {
/* check if page is covered */
sector_t sector = sh->dev[dd_idx].sector;
@@ -958,12 +978,13 @@ static void handle_stripe(struct stripe_
* need to be failed
*/
if (failed > 1 && to_read+to_write+written) {
- spin_lock_irq(&conf->device_lock);
for (i=disks; i--; ) {
+ int bitmap_end = 0;
+ spin_lock_irq(&conf->device_lock);
/* fail all writes first */
bi = sh->dev[i].towrite;
sh->dev[i].towrite = NULL;
- if (bi) to_write--;
+ if (bi) { to_write--; bitmap_end = 1; }
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
@@ -981,6 +1002,7 @@ static void handle_stripe(struct stripe_
/* and fail all 'written' */
bi = sh->dev[i].written;
sh->dev[i].written = NULL;
+ if (bi) bitmap_end = 1;
while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
clear_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1009,8 +1031,11 @@ static void handle_stripe(struct stripe_
bi = nextbi;
}
}
+ spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS, 0, 0);
}
- spin_unlock_irq(&conf->device_lock);
}
if (failed > 1 && syncing) {
md_done_sync(conf->mddev, STRIPE_SECTORS,0);
@@ -1038,6 +1063,7 @@ static void handle_stripe(struct stripe_
test_bit(R5_UPTODATE, &dev->flags) ) {
/* We can return any write requests */
struct bio *wbi, *wbi2;
+ int bitmap_end = 0;
PRINTK("Return write for disc %d\n", i);
spin_lock_irq(&conf->device_lock);
wbi = dev->written;
@@ -1051,7 +1077,13 @@ static void handle_stripe(struct stripe_
}
wbi = wbi2;
}
+ if (dev->towrite == NULL)
+ bitmap_end = 1;
spin_unlock_irq(&conf->device_lock);
+ if (bitmap_end)
+ bitmap_endwrite(conf->mddev->bitmap, sh->sector,
+ STRIPE_SECTORS,
+ !test_bit(STRIPE_DEGRADED, &sh->state), 0);
}
}
}
@@ -1175,7 +1207,8 @@ static void handle_stripe(struct stripe_
}
}
/* now if nothing is locked, and if we have enough data, we can start a write request */
- if (locked == 0 && (rcw == 0 ||rmw == 0)) {
+ if (locked == 0 && (rcw == 0 ||rmw == 0) &&
+ !test_bit(STRIPE_BIT_DELAY, &sh->state)) {
PRINTK("Computing parity...\n");
compute_parity(sh, rcw==0 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);
/* now every locked buffer is ready to be written */
@@ -1231,6 +1264,7 @@ static void handle_stripe(struct stripe_
dev = &sh->dev[failed_num];
set_bit(R5_LOCKED, &dev->flags);
set_bit(R5_Wantwrite, &dev->flags);
+ clear_bit(STRIPE_DEGRADED, &sh->state);
locked++;
set_bit(STRIPE_INSYNC, &sh->state);
set_bit(R5_Syncio, &dev->flags);
@@ -1298,6 +1332,8 @@ static void handle_stripe(struct stripe_
bi->bi_next = NULL;
generic_make_request(bi);
} else {
+ if (rw == 1)
+ set_bit(STRIPE_DEGRADED, &sh->state);
PRINTK("skip op %ld on disc %d for sector %llu\n",
bi->bi_rw, i, (unsigned long long)sh->sector);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -1322,6 +1358,20 @@ static inline void raid5_activate_delaye
}
}
+static inline void activate_bit_delay(raid5_conf_t *conf)
+{
+ /* device_lock is held */
+ struct list_head head;
+ list_add(&head, &conf->bitmap_list);
+ list_del_init(&conf->bitmap_list);
+ while (!list_empty(&head)) {
+ struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ atomic_inc(&sh->count);
+ __release_stripe(conf, sh);
+ }
+}
+
static void unplug_slaves(mddev_t *mddev)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -1354,8 +1404,10 @@ static void raid5_unplug_device(request_
spin_lock_irqsave(&conf->device_lock, flags);
- if (blk_remove_plug(q))
+ if (blk_remove_plug(q)) {
+ conf->seq_flush++;
raid5_activate_delayed(conf);
+ }
md_wakeup_thread(mddev->thread);
spin_unlock_irqrestore(&conf->device_lock, flags);
@@ -1493,10 +1545,20 @@ static sector_t sync_request(mddev_t *md
sector_t first_sector;
int raid_disks = conf->raid_disks;
int data_disks = raid_disks-1;
+ sector_t max_sector = mddev->size << 1;
+ int sync_blocks;
- if (sector_nr >= mddev->size <<1) {
+ if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
+ if (mddev->curr_resync < max_sector) /* aborted */
+ bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
+ &sync_blocks, 1);
+ else /* compelted sync */
+ conf->fullsync = 0;
+ bitmap_close_sync(mddev->bitmap);
+
return 0;
}
/* if there is 1 or more failed drives and we are trying
@@ -1508,6 +1570,13 @@ static sector_t sync_request(mddev_t *md
*skipped = 1;
return rv;
}
+ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+ !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
+ /* we can skip this block, and probably more */
+ sync_blocks /= STRIPE_SECTORS;
+ *skipped = 1;
+ return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
+ }
x = sector_nr;
chunk_offset = sector_div(x, sectors_per_chunk);
@@ -1524,6 +1593,7 @@ static sector_t sync_request(mddev_t *md
*/
schedule_timeout_uninterruptible(1);
}
+ bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
spin_lock(&sh->lock);
set_bit(STRIPE_SYNCING, &sh->state);
clear_bit(STRIPE_INSYNC, &sh->state);
@@ -1557,6 +1627,13 @@ static void raid5d (mddev_t *mddev)
while (1) {
struct list_head *first;
+ if (conf->seq_flush - conf->seq_write > 0) {
+ int seq = conf->seq_flush;
+ bitmap_unplug(mddev->bitmap);
+ conf->seq_write = seq;
+ activate_bit_delay(conf);
+ }
+
if (list_empty(&conf->handle_list) &&
atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
!blk_queue_plugged(mddev->queue) &&
@@ -1590,7 +1667,7 @@ static void raid5d (mddev_t *mddev)
PRINTK("--- raid5d inactive\n");
}
-static int run (mddev_t *mddev)
+static int run(mddev_t *mddev)
{
raid5_conf_t *conf;
int raid_disk, memory;
@@ -1620,6 +1697,7 @@ static int run (mddev_t *mddev)
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
INIT_LIST_HEAD(&conf->delayed_list);
+ INIT_LIST_HEAD(&conf->bitmap_list);
INIT_LIST_HEAD(&conf->inactive_list);
atomic_set(&conf->active_stripes, 0);
atomic_set(&conf->preread_active_stripes, 0);
@@ -1731,6 +1809,9 @@ memory = conf->max_nr_stripes * (sizeof(
/* Ok, everything is just fine now */
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->issue_flush_fn = raid5_issue_flush;
@@ -1911,6 +1992,8 @@ static int raid5_add_disk(mddev_t *mddev
rdev->in_sync = 0;
rdev->raid_disk = disk;
found = 1;
+ if (rdev->saved_raid_disk != disk)
+ conf->fullsync = 1;
p->rdev = rdev;
break;
}
@@ -1940,6 +2023,35 @@ static int raid5_resize(mddev_t *mddev,
return 0;
}
+static void raid5_quiesce(mddev_t *mddev, int state)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ switch(state) {
+ case 1: /* stop all writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 1;
+ wait_event_lock_irq(conf->wait_for_stripe,
+ atomic_read(&conf->active_stripes) == 0,
+ conf->device_lock, /* nothing */);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+
+ case 0: /* re-enable writes */
+ spin_lock_irq(&conf->device_lock);
+ conf->quiesce = 0;
+ wake_up(&conf->wait_for_stripe);
+ spin_unlock_irq(&conf->device_lock);
+ break;
+ }
+ if (mddev->thread) {
+ if (mddev->bitmap)
+ mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+ else
+ mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+ md_wakeup_thread(mddev->thread);
+ }
+}
static mdk_personality_t raid5_personality=
{
.name = "raid5",
@@ -1954,6 +2066,7 @@ static mdk_personality_t raid5_personali
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
+ .quiesce = raid5_quiesce,
};
static int __init raid5_init (void)
diff ./include/linux/raid/raid5.h~current~ ./include/linux/raid/raid5.h
--- ./include/linux/raid/raid5.h~current~ 2005-08-29 16:32:20.000000000 +1000
+++ ./include/linux/raid/raid5.h 2005-08-29 16:32:24.000000000 +1000
@@ -134,6 +134,7 @@ struct stripe_head {
unsigned long state; /* state flags */
atomic_t count; /* nr of active thread/requests */
spinlock_t lock;
+ int bm_seq; /* sequence number for bitmap flushes */
struct r5dev {
struct bio req;
struct bio_vec vec;
@@ -165,12 +166,13 @@ struct stripe_head {
/*
* Stripe state
*/
-#define STRIPE_ERROR 1
#define STRIPE_HANDLE 2
#define STRIPE_SYNCING 3
#define STRIPE_INSYNC 4
#define STRIPE_PREREAD_ACTIVE 5
#define STRIPE_DELAYED 6
+#define STRIPE_DEGRADED 7
+#define STRIPE_BIT_DELAY 8
/*
* Plugging:
@@ -210,10 +212,20 @@ struct raid5_private_data {
struct list_head handle_list; /* stripes needing handling */
struct list_head delayed_list; /* stripes that have plugged requests */
+ struct list_head bitmap_list; /* stripes delaying awaiting bitmap update */
atomic_t preread_active_stripes; /* stripes with scheduled io */
char cache_name[20];
kmem_cache_t *slab_cache; /* for allocating stripes */
+
+ int seq_flush, seq_write;
+ int quiesce;
+
+ int fullsync; /* set to 1 if a full sync is needed,
+ * (fresh device added).
+ * Cleared when a sync completes.
+ */
+
/*
* Free stripes pool
*/
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 002 of 7] Limit size of sb read/written to appropriate amount.
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
` (3 preceding siblings ...)
2005-08-29 7:33 ` [PATCH md 007 of 7] Tidy up daemon stop/start code in md/bitmap.c NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
2005-08-29 7:33 ` [PATCH md 003 of 7] Add write-intent-bitmap support to raid5 NeilBrown
2005-08-29 7:33 ` [PATCH md 005 of 7] Use kthread infrastructure in md NeilBrown
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
version-1 superblocks are not (normally) 4K long, and can be of
variable size. Writing the full 4K can cause corruption (but only in
non-default configurations).
With this patch the super-block-flavour can choose a size to read, and
set a size to write based on what it finds.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./drivers/md/md.c | 20 +++++++++++++++-----
./include/linux/raid/md_k.h | 1 +
2 files changed, 16 insertions(+), 5 deletions(-)
diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~ 2005-08-29 15:52:32.000000000 +1000
+++ ./drivers/md/md.c 2005-08-29 15:52:47.000000000 +1000
@@ -393,7 +393,7 @@ int sync_page_io(struct block_device *bd
return ret;
}
-static int read_disk_sb(mdk_rdev_t * rdev)
+static int read_disk_sb(mdk_rdev_t * rdev, int size)
{
char b[BDEVNAME_SIZE];
if (!rdev->sb_page) {
@@ -404,7 +404,7 @@ static int read_disk_sb(mdk_rdev_t * rde
return 0;
- if (!sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, READ))
+ if (!sync_page_io(rdev->bdev, rdev->sb_offset<<1, size, rdev->sb_page, READ))
goto fail;
rdev->sb_loaded = 1;
return 0;
@@ -531,7 +531,7 @@ static int super_90_load(mdk_rdev_t *rde
sb_offset = calc_dev_sboffset(rdev->bdev);
rdev->sb_offset = sb_offset;
- ret = read_disk_sb(rdev);
+ ret = read_disk_sb(rdev, MD_SB_BYTES);
if (ret) return ret;
ret = -EINVAL;
@@ -564,6 +564,7 @@ static int super_90_load(mdk_rdev_t *rde
rdev->preferred_minor = sb->md_minor;
rdev->data_offset = 0;
+ rdev->sb_size = MD_SB_BYTES;
if (sb->level == LEVEL_MULTIPATH)
rdev->desc_nr = -1;
@@ -837,6 +838,7 @@ static int super_1_load(mdk_rdev_t *rdev
int ret;
sector_t sb_offset;
char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+ int bmask;
/*
* Calculate the position of the superblock.
@@ -865,7 +867,10 @@ static int super_1_load(mdk_rdev_t *rdev
}
rdev->sb_offset = sb_offset;
- ret = read_disk_sb(rdev);
+ /* superblock is rarely larger than 1K, but it can be larger,
+ * and it is safe to read 4k, so we do that
+ */
+ ret = read_disk_sb(rdev, 4096);
if (ret) return ret;
@@ -891,6 +896,11 @@ static int super_1_load(mdk_rdev_t *rdev
rdev->preferred_minor = 0xffff;
rdev->data_offset = le64_to_cpu(sb->data_offset);
+ rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
+ bmask = block_size(rdev->bdev)-1;
+ if (rdev->sb_size & bmask)
+ rdev-> sb_size = (rdev->sb_size | bmask)+1;
+
if (refdev == 0)
return 1;
else {
@@ -1375,7 +1385,7 @@ repeat:
dprintk("%s ", bdevname(rdev->bdev,b));
if (!rdev->faulty) {
md_super_write(mddev,rdev,
- rdev->sb_offset<<1, MD_SB_BYTES,
+ rdev->sb_offset<<1, rdev->sb_size,
rdev->sb_page);
dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
bdevname(rdev->bdev,b),
diff ./include/linux/raid/md_k.h~current~ ./include/linux/raid/md_k.h
--- ./include/linux/raid/md_k.h~current~ 2005-08-29 15:52:38.000000000 +1000
+++ ./include/linux/raid/md_k.h 2005-08-29 15:52:47.000000000 +1000
@@ -102,6 +102,7 @@ struct mdk_rdev_s
int sb_loaded;
sector_t data_offset; /* start of data in array */
sector_t sb_offset;
+ int sb_size; /* bytes in the superblock */
int preferred_minor; /* autorun support */
/* A device can be in one of three states based on two flags:
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH md 001 of 7] Remove old cruft from md_k.h header file.
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
@ 2005-08-29 7:33 ` NeilBrown
2005-08-29 7:33 ` [PATCH md 004 of 7] write-intent bitmap support for raid6 NeilBrown
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: NeilBrown @ 2005-08-29 7:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-raid
These inlines haven't been used for ages, they should go.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
### Diffstat output
./include/linux/raid/md_k.h | 64 --------------------------------------------
1 file changed, 64 deletions(-)
diff ./include/linux/raid/md_k.h~current~ ./include/linux/raid/md_k.h
--- ./include/linux/raid/md_k.h~current~ 2005-08-29 15:52:25.000000000 +1000
+++ ./include/linux/raid/md_k.h 2005-08-29 15:52:38.000000000 +1000
@@ -86,70 +86,6 @@ typedef struct mdk_rdev_s mdk_rdev_t;
#define MAX_CHUNK_SIZE (4096*1024)
/*
- * default readahead
- */
-
-static inline int disk_faulty(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_FAULTY);
-}
-
-static inline int disk_active(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_ACTIVE);
-}
-
-static inline int disk_sync(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_SYNC);
-}
-
-static inline int disk_spare(mdp_disk_t * d)
-{
- return !disk_sync(d) && !disk_active(d) && !disk_faulty(d);
-}
-
-static inline int disk_removed(mdp_disk_t * d)
-{
- return d->state & (1 << MD_DISK_REMOVED);
-}
-
-static inline void mark_disk_faulty(mdp_disk_t * d)
-{
- d->state |= (1 << MD_DISK_FAULTY);
-}
-
-static inline void mark_disk_active(mdp_disk_t * d)
-{
- d->state |= (1 << MD_DISK_ACTIVE);
-}
-
-static inline void mark_disk_sync(mdp_disk_t * d)
-{
- d->state |= (1 << MD_DISK_SYNC);
-}
-
-static inline void mark_disk_spare(mdp_disk_t * d)
-{
- d->state = 0;
-}
-
-static inline void mark_disk_removed(mdp_disk_t * d)
-{
- d->state = (1 << MD_DISK_FAULTY) | (1 << MD_DISK_REMOVED);
-}
-
-static inline void mark_disk_inactive(mdp_disk_t * d)
-{
- d->state &= ~(1 << MD_DISK_ACTIVE);
-}
-
-static inline void mark_disk_nonsync(mdp_disk_t * d)
-{
- d->state &= ~(1 << MD_DISK_SYNC);
-}
-
-/*
* MD's 'extended' device
*/
struct mdk_rdev_s
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-08-29 7:33 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-29 7:33 [PATCH md 000 of 7] Introduction NeilBrown
2005-08-29 7:33 ` [PATCH md 001 of 7] Remove old cruft from md_k.h header file NeilBrown
2005-08-29 7:33 ` [PATCH md 004 of 7] write-intent bitmap support for raid6 NeilBrown
2005-08-29 7:33 ` [PATCH md 006 of 7] Ensure bitmap_writeback_daemon handles shutdown properly NeilBrown
2005-08-29 7:33 ` [PATCH md 007 of 7] Tidy up daemon stop/start code in md/bitmap.c NeilBrown
2005-08-29 7:33 ` [PATCH md 002 of 7] Limit size of sb read/written to appropriate amount NeilBrown
2005-08-29 7:33 ` [PATCH md 003 of 7] Add write-intent-bitmap support to raid5 NeilBrown
2005-08-29 7:33 ` [PATCH md 005 of 7] Use kthread infrastructure in md NeilBrown
-- strict thread matches above, loose matches on Subject: below --
2005-08-02 9:53 [PATCH md 000 of 7] Introduction NeilBrown
2005-08-04 5:10 ` Andrew Morton
2005-08-04 5:36 ` Neil Brown
2005-08-04 5:45 ` Andrew Morton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox