aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-03-30 23:39:39 -0400
committerNeilBrown <neilb@suse.de>2009-03-30 23:39:39 -0400
commit409c57f3801701dfee27a28103dda4831306cb20 (patch)
tree430c8e4ebe879b27250e061dc1a1171b12aaadf0 /drivers/md/raid1.c
parente0cf8f045b2023b0b3f919ee93eb94345f648434 (diff)
md: enable suspend/resume of md devices.
To be able to change the 'level' of an md/raid array, we need to suspend the device so that no requests are active - then move some pointers around etc. The code already keeps counts of active requests and the ->quiesce function can be used to wait until those counts hit zero. However the quiesce function blocks new requests once they are all ready 'inside' the personality module, and that is too late if we want to replace the personality modules. So make all md requests come in through a common md_make_request function that keeps track of how many requests have entered the modules but may not yet be on the internal reference counts. Allow md_make_request to be blocked when we want to suspend the device, and make it possible to wait for all those in-transit requests to be added to internal lists so that ->quiesce can wait for them. There is still a problem that when a request completes, we drop the ref count inside the personality code so there is a short time between when the refcount hits zero, and when the personality code is no longer being used. The personality code never blocks (schedule or spinlock) between dropping the refcount and exiting the routine, so this should be safe (as put_module calls synchronize_sched() before unmapping the module code). Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r--drivers/md/raid1.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 779958705abf..7eaca3209364 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2092,6 +2092,9 @@ static int stop(mddev_t *mddev)
2092 /* need to kick something here to make sure I/O goes? */ 2092 /* need to kick something here to make sure I/O goes? */
2093 } 2093 }
2094 2094
2095 raise_barrier(conf);
2096 lower_barrier(conf);
2097
2095 md_unregister_thread(mddev->thread); 2098 md_unregister_thread(mddev->thread);
2096 mddev->thread = NULL; 2099 mddev->thread = NULL;
2097 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 2100 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/