Updated from Linux LTS 3.10.21 to 3.10.22
This commit is contained in:
@@ -151,6 +151,9 @@ struct cache {
|
||||
atomic_t nr_migrations;
|
||||
wait_queue_head_t migration_wait;
|
||||
|
||||
wait_queue_head_t quiescing_wait;
|
||||
atomic_t quiescing_ack;
|
||||
|
||||
/*
|
||||
* cache_size entries, dirty if set
|
||||
*/
|
||||
@@ -742,8 +745,9 @@ static void cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell,
|
||||
|
||||
static void cleanup_migration(struct dm_cache_migration *mg)
|
||||
{
|
||||
dec_nr_migrations(mg->cache);
|
||||
struct cache *cache = mg->cache;
|
||||
free_migration(mg);
|
||||
dec_nr_migrations(cache);
|
||||
}
|
||||
|
||||
static void migration_failure(struct dm_cache_migration *mg)
|
||||
@@ -1340,24 +1344,6 @@ static void writeback_some_dirty_blocks(struct cache *cache)
|
||||
/*----------------------------------------------------------------
|
||||
* Main worker loop
|
||||
*--------------------------------------------------------------*/
|
||||
static void start_quiescing(struct cache *cache)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cache->lock, flags);
|
||||
cache->quiescing = 1;
|
||||
spin_unlock_irqrestore(&cache->lock, flags);
|
||||
}
|
||||
|
||||
static void stop_quiescing(struct cache *cache)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cache->lock, flags);
|
||||
cache->quiescing = 0;
|
||||
spin_unlock_irqrestore(&cache->lock, flags);
|
||||
}
|
||||
|
||||
static bool is_quiescing(struct cache *cache)
|
||||
{
|
||||
int r;
|
||||
@@ -1370,6 +1356,41 @@ static bool is_quiescing(struct cache *cache)
|
||||
return r;
|
||||
}
|
||||
|
||||
static void ack_quiescing(struct cache *cache)
|
||||
{
|
||||
if (is_quiescing(cache)) {
|
||||
atomic_inc(&cache->quiescing_ack);
|
||||
wake_up(&cache->quiescing_wait);
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_for_quiescing_ack(struct cache *cache)
|
||||
{
|
||||
wait_event(cache->quiescing_wait, atomic_read(&cache->quiescing_ack));
|
||||
}
|
||||
|
||||
static void start_quiescing(struct cache *cache)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cache->lock, flags);
|
||||
cache->quiescing = true;
|
||||
spin_unlock_irqrestore(&cache->lock, flags);
|
||||
|
||||
wait_for_quiescing_ack(cache);
|
||||
}
|
||||
|
||||
static void stop_quiescing(struct cache *cache)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cache->lock, flags);
|
||||
cache->quiescing = false;
|
||||
spin_unlock_irqrestore(&cache->lock, flags);
|
||||
|
||||
atomic_set(&cache->quiescing_ack, 0);
|
||||
}
|
||||
|
||||
static void wait_for_migrations(struct cache *cache)
|
||||
{
|
||||
wait_event(cache->migration_wait, !atomic_read(&cache->nr_migrations));
|
||||
@@ -1414,16 +1435,15 @@ static void do_worker(struct work_struct *ws)
|
||||
struct cache *cache = container_of(ws, struct cache, worker);
|
||||
|
||||
do {
|
||||
if (!is_quiescing(cache))
|
||||
if (!is_quiescing(cache)) {
|
||||
writeback_some_dirty_blocks(cache);
|
||||
process_deferred_writethrough_bios(cache);
|
||||
process_deferred_bios(cache);
|
||||
}
|
||||
|
||||
process_migrations(cache, &cache->quiesced_migrations, issue_copy);
|
||||
process_migrations(cache, &cache->completed_migrations, complete_migration);
|
||||
|
||||
writeback_some_dirty_blocks(cache);
|
||||
|
||||
process_deferred_writethrough_bios(cache);
|
||||
|
||||
if (commit_if_needed(cache)) {
|
||||
process_deferred_flush_bios(cache, false);
|
||||
|
||||
@@ -1436,6 +1456,9 @@ static void do_worker(struct work_struct *ws)
|
||||
process_migrations(cache, &cache->need_commit_migrations,
|
||||
migration_success_post_commit);
|
||||
}
|
||||
|
||||
ack_quiescing(cache);
|
||||
|
||||
} while (more_work(cache));
|
||||
}
|
||||
|
||||
@@ -1998,6 +2021,9 @@ static int cache_create(struct cache_args *ca, struct cache **result)
|
||||
atomic_set(&cache->nr_migrations, 0);
|
||||
init_waitqueue_head(&cache->migration_wait);
|
||||
|
||||
init_waitqueue_head(&cache->quiescing_wait);
|
||||
atomic_set(&cache->quiescing_ack, 0);
|
||||
|
||||
r = -ENOMEM;
|
||||
cache->nr_dirty = 0;
|
||||
cache->dirty_bitset = alloc_bitset(from_cblock(cache->cache_size));
|
||||
|
||||
@@ -86,6 +86,7 @@ struct multipath {
|
||||
unsigned queue_if_no_path:1; /* Queue I/O if last path fails? */
|
||||
unsigned saved_queue_if_no_path:1; /* Saved state during suspension */
|
||||
unsigned retain_attached_hw_handler:1; /* If there's already a hw_handler present, don't change it. */
|
||||
unsigned pg_init_disabled:1; /* pg_init is not currently allowed */
|
||||
|
||||
unsigned pg_init_retries; /* Number of times to retry pg_init */
|
||||
unsigned pg_init_count; /* Number of times pg_init called */
|
||||
@@ -497,7 +498,8 @@ static void process_queued_ios(struct work_struct *work)
|
||||
(!pgpath && !m->queue_if_no_path))
|
||||
must_queue = 0;
|
||||
|
||||
if (m->pg_init_required && !m->pg_init_in_progress && pgpath)
|
||||
if (m->pg_init_required && !m->pg_init_in_progress && pgpath &&
|
||||
!m->pg_init_disabled)
|
||||
__pg_init_all_paths(m);
|
||||
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
@@ -942,10 +944,20 @@ static void multipath_wait_for_pg_init_completion(struct multipath *m)
|
||||
|
||||
static void flush_multipath_work(struct multipath *m)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
m->pg_init_disabled = 1;
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
|
||||
flush_workqueue(kmpath_handlerd);
|
||||
multipath_wait_for_pg_init_completion(m);
|
||||
flush_workqueue(kmultipathd);
|
||||
flush_work(&m->trigger_event);
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
m->pg_init_disabled = 0;
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
}
|
||||
|
||||
static void multipath_dtr(struct dm_target *ti)
|
||||
@@ -1164,7 +1176,7 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
|
||||
if (m->pg_init_count <= m->pg_init_retries)
|
||||
if (m->pg_init_count <= m->pg_init_retries && !m->pg_init_disabled)
|
||||
m->pg_init_required = 1;
|
||||
else
|
||||
limit_reached = 1;
|
||||
@@ -1699,7 +1711,7 @@ out:
|
||||
*---------------------------------------------------------------*/
|
||||
static struct target_type multipath_target = {
|
||||
.name = "multipath",
|
||||
.version = {1, 5, 1},
|
||||
.version = {1, 6, 0},
|
||||
.module = THIS_MODULE,
|
||||
.ctr = multipath_ctr,
|
||||
.dtr = multipath_dtr,
|
||||
|
||||
@@ -583,14 +583,28 @@ static int adjoin(struct dm_table *table, struct dm_target *ti)
|
||||
|
||||
/*
|
||||
* Used to dynamically allocate the arg array.
|
||||
*
|
||||
* We do first allocation with GFP_NOIO because dm-mpath and dm-thin must
|
||||
* process messages even if some device is suspended. These messages have a
|
||||
* small fixed number of arguments.
|
||||
*
|
||||
* On the other hand, dm-switch needs to process bulk data using messages and
|
||||
* excessive use of GFP_NOIO could cause trouble.
|
||||
*/
|
||||
static char **realloc_argv(unsigned *array_size, char **old_argv)
|
||||
{
|
||||
char **argv;
|
||||
unsigned new_size;
|
||||
gfp_t gfp;
|
||||
|
||||
new_size = *array_size ? *array_size * 2 : 64;
|
||||
argv = kmalloc(new_size * sizeof(*argv), GFP_KERNEL);
|
||||
if (*array_size) {
|
||||
new_size = *array_size * 2;
|
||||
gfp = GFP_KERNEL;
|
||||
} else {
|
||||
new_size = 8;
|
||||
gfp = GFP_NOIO;
|
||||
}
|
||||
argv = kmalloc(new_size * sizeof(*argv), gfp);
|
||||
if (argv) {
|
||||
memcpy(argv, old_argv, *array_size * sizeof(*argv));
|
||||
*array_size = new_size;
|
||||
|
||||
@@ -3619,6 +3619,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
|
||||
mddev->in_sync = 1;
|
||||
del_timer_sync(&mddev->safemode_timer);
|
||||
}
|
||||
blk_set_stacking_limits(&mddev->queue->limits);
|
||||
pers->run(mddev);
|
||||
set_bit(MD_CHANGE_DEVS, &mddev->flags);
|
||||
mddev_resume(mddev);
|
||||
|
||||
@@ -509,15 +509,18 @@ static int grow_add_tail_block(struct resize *resize)
|
||||
static int grow_needs_more_blocks(struct resize *resize)
|
||||
{
|
||||
int r;
|
||||
unsigned old_nr_blocks = resize->old_nr_full_blocks;
|
||||
|
||||
if (resize->old_nr_entries_in_last_block > 0) {
|
||||
old_nr_blocks++;
|
||||
|
||||
r = grow_extend_tail_block(resize, resize->max_entries);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = insert_full_ablocks(resize->info, resize->size_of_block,
|
||||
resize->old_nr_full_blocks,
|
||||
old_nr_blocks,
|
||||
resize->new_nr_full_blocks,
|
||||
resize->max_entries, resize->value,
|
||||
&resize->root);
|
||||
|
||||
Reference in New Issue
Block a user