summaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bitmap.c10
-rw-r--r--drivers/md/dm-crypt.c14
-rw-r--r--drivers/md/dm-ioctl.c9
-rw-r--r--drivers/md/dm-raid1.c22
-rw-r--r--drivers/md/dm-round-robin.c2
-rw-r--r--drivers/md/dm.c4
-rw-r--r--drivers/md/md.c25
-rw-r--r--drivers/md/multipath.c4
-rw-r--r--drivers/md/raid1.c4
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c2
11 files changed, 64 insertions, 38 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index d47d38ac71b..d6f614738bb 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -536,7 +536,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) "
"-- forcing full recovery\n", bmname(bitmap), events,
(unsigned long long) bitmap->mddev->events);
- sb->state |= BITMAP_STALE;
+ sb->state |= cpu_to_le32(BITMAP_STALE);
}
success:
/* assign fields using values from superblock */
@@ -544,11 +544,11 @@ success:
bitmap->daemon_sleep = daemon_sleep;
bitmap->daemon_lastrun = jiffies;
bitmap->max_write_behind = write_behind;
- bitmap->flags |= sb->state;
+ bitmap->flags |= le32_to_cpu(sb->state);
if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
bitmap->flags |= BITMAP_HOSTENDIAN;
bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
- if (sb->state & BITMAP_STALE)
+ if (sb->state & cpu_to_le32(BITMAP_STALE))
bitmap->events_cleared = bitmap->mddev->events;
err = 0;
out:
@@ -578,9 +578,9 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
spin_unlock_irqrestore(&bitmap->lock, flags);
sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
switch (op) {
- case MASK_SET: sb->state |= bits;
+ case MASK_SET: sb->state |= cpu_to_le32(bits);
break;
- case MASK_UNSET: sb->state &= ~bits;
+ case MASK_UNSET: sb->state &= cpu_to_le32(~bits);
break;
default: BUG();
}
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 655d816760e..08a40f4e4f6 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/crypto.h>
#include <linux/workqueue.h>
+#include <linux/backing-dev.h>
#include <asm/atomic.h>
#include <linux/scatterlist.h>
#include <asm/page.h>
@@ -602,7 +603,7 @@ static void process_write(struct crypt_io *io)
/* out of memory -> run queues */
if (remaining)
- blk_congestion_wait(bio_data_dir(clone), HZ/100);
+ congestion_wait(bio_data_dir(clone), HZ/100);
}
}
@@ -914,8 +915,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
char *result, unsigned int maxlen)
{
struct crypt_config *cc = (struct crypt_config *) ti->private;
- const char *cipher;
- const char *chainmode = NULL;
unsigned int sz = 0;
switch (type) {
@@ -924,14 +923,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
break;
case STATUSTYPE_TABLE:
- cipher = crypto_blkcipher_name(cc->tfm);
-
- chainmode = cc->chainmode;
-
if (cc->iv_mode)
- DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode);
+ DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode,
+ cc->iv_mode);
else
- DMEMIT("%s-%s ", cipher, chainmode);
+ DMEMIT("%s-%s ", cc->cipher, cc->chainmode);
if (cc->key_size > 0) {
if ((maxlen - sz) < ((cc->key_size << 1) + 1))
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index d13bb15a8a0..4510ad8f971 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -606,9 +606,14 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
return __get_name_cell(param->name);
md = dm_get_md(huge_decode_dev(param->dev));
- if (md)
- mdptr = dm_get_mdptr(md);
+ if (!md)
+ goto out;
+ mdptr = dm_get_mdptr(md);
+ if (!mdptr)
+ dm_put(md);
+
+out:
return mdptr;
}
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 659224cb7c5..48a653b3f51 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -24,6 +24,7 @@
static struct workqueue_struct *_kmirrord_wq;
static struct work_struct _kmirrord_work;
+static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
static inline void wake(void)
{
@@ -83,6 +84,7 @@ struct region_hash {
struct list_head *buckets;
spinlock_t region_lock;
+ atomic_t recovery_in_flight;
struct semaphore recovery_count;
struct list_head clean_regions;
struct list_head quiesced_regions;
@@ -191,6 +193,7 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms,
spin_lock_init(&rh->region_lock);
sema_init(&rh->recovery_count, 0);
+ atomic_set(&rh->recovery_in_flight, 0);
INIT_LIST_HEAD(&rh->clean_regions);
INIT_LIST_HEAD(&rh->quiesced_regions);
INIT_LIST_HEAD(&rh->recovered_regions);
@@ -382,6 +385,8 @@ static void rh_update_states(struct region_hash *rh)
rh->log->type->clear_region(rh->log, reg->key);
rh->log->type->complete_resync_work(rh->log, reg->key, 1);
dispatch_bios(rh->ms, &reg->delayed_bios);
+ if (atomic_dec_and_test(&rh->recovery_in_flight))
+ wake_up_all(&_kmirrord_recovery_stopped);
up(&rh->recovery_count);
mempool_free(reg, rh->region_pool);
}
@@ -502,11 +507,21 @@ static int __rh_recovery_prepare(struct region_hash *rh)
static void rh_recovery_prepare(struct region_hash *rh)
{
- while (!down_trylock(&rh->recovery_count))
+ /* Extra reference to avoid race with rh_stop_recovery */
+ atomic_inc(&rh->recovery_in_flight);
+
+ while (!down_trylock(&rh->recovery_count)) {
+ atomic_inc(&rh->recovery_in_flight);
if (__rh_recovery_prepare(rh) <= 0) {
+ atomic_dec(&rh->recovery_in_flight);
up(&rh->recovery_count);
break;
}
+ }
+
+ /* Drop the extra reference */
+ if (atomic_dec_and_test(&rh->recovery_in_flight))
+ wake_up_all(&_kmirrord_recovery_stopped);
}
/*
@@ -1177,6 +1192,11 @@ static void mirror_postsuspend(struct dm_target *ti)
struct dirty_log *log = ms->rh.log;
rh_stop_recovery(&ms->rh);
+
+ /* Wait for all I/O we generated to complete */
+ wait_event(_kmirrord_recovery_stopped,
+ !atomic_read(&ms->rh.recovery_in_flight));
+
if (log->type->suspend && log->type->suspend(log))
/* FIXME: need better error handling */
DMWARN("log suspend failed");
diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c
index c5a16c55012..6f9fcd4db9b 100644
--- a/drivers/md/dm-round-robin.c
+++ b/drivers/md/dm-round-robin.c
@@ -136,7 +136,7 @@ static int rr_add_path(struct path_selector *ps, struct path *path,
path->pscontext = pi;
- list_add(&pi->list, &s->valid_paths);
+ list_add_tail(&pi->list, &s->valid_paths);
return 0;
}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index b5764a86c8b..fc4f743f3b5 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1285,7 +1285,7 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
down(&md->suspend_lock);
if (dm_suspended(md))
- goto out;
+ goto out_unlock;
map = dm_get_table(md);
@@ -1361,6 +1361,8 @@ out:
}
dm_table_put(map);
+
+out_unlock:
up(&md->suspend_lock);
return r;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 57fa64f93e5..8cbf9c9df1c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -974,12 +974,13 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
* version 1 superblock
*/
-static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
+static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb)
{
- unsigned int disk_csum, csum;
+ __le32 disk_csum;
+ u32 csum;
unsigned long long newcsum;
int size = 256 + le32_to_cpu(sb->max_dev)*2;
- unsigned int *isuper = (unsigned int*)sb;
+ __le32 *isuper = (__le32*)sb;
int i;
disk_csum = sb->sb_csum;
@@ -989,7 +990,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
newcsum += le32_to_cpu(*isuper++);
if (size == 2)
- newcsum += le16_to_cpu(*(unsigned short*) isuper);
+ newcsum += le16_to_cpu(*(__le16*) isuper);
csum = (newcsum & 0xffffffff) + (newcsum >> 32);
sb->sb_csum = disk_csum;
@@ -1106,7 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
if (le32_to_cpu(sb->chunksize))
rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
- if (le32_to_cpu(sb->size) > rdev->size*2)
+ if (le64_to_cpu(sb->size) > rdev->size*2)
return -EINVAL;
return ret;
}
@@ -1228,7 +1229,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
else
sb->resync_offset = cpu_to_le64(0);
- sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+ sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
sb->raid_disks = cpu_to_le32(mddev->raid_disks);
sb->size = cpu_to_le64(mddev->size<<1);
@@ -2002,6 +2003,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
kobject_init(&rdev->kobj);
rdev->desc_nr = -1;
+ rdev->saved_raid_disk = -1;
rdev->flags = 0;
rdev->data_offset = 0;
rdev->sb_events = 0;
@@ -3198,6 +3200,7 @@ static int do_md_run(mddev_t * mddev)
mddev->changed = 1;
md_new_event(mddev);
+ kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE);
return 0;
}
@@ -4043,11 +4046,8 @@ static int update_size(mddev_t *mddev, unsigned long size)
return -EBUSY;
ITERATE_RDEV(mddev,rdev,tmp) {
sector_t avail;
- if (rdev->sb_offset > rdev->data_offset)
- avail = (rdev->sb_offset*2) - rdev->data_offset;
- else
- avail = get_capacity(rdev->bdev->bd_disk)
- - rdev->data_offset;
+ avail = rdev->size * 2;
+
if (fit && (size == 0 || size > avail/2))
size = avail/2;
if (avail < ((sector_t)size << 1))
@@ -4486,6 +4486,7 @@ static int md_thread(void * arg)
* many dirty RAID5 blocks.
*/
+ current->flags |= PF_NOFREEZE;
allow_signal(SIGKILL);
while (!kthread_should_stop()) {
@@ -4502,7 +4503,6 @@ static int md_thread(void * arg)
test_bit(THREAD_WAKEUP, &thread->flags)
|| kthread_should_stop(),
thread->timeout);
- try_to_freeze();
clear_bit(THREAD_WAKEUP, &thread->flags);
@@ -4912,6 +4912,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
}
static struct file_operations md_seq_fops = {
+ .owner = THIS_MODULE,
.open = md_seq_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 171ff41b52b..14da37fee37 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -277,6 +277,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
set_bit(Faulty, &rdev->flags);
set_bit(MD_CHANGE_DEVS, &mddev->flags);
conf->working_disks--;
+ mddev->degraded++;
printk(KERN_ALERT "multipath: IO failure on %s,"
" disabling IO path. \n Operation continuing"
" on %d IO paths.\n",
@@ -336,6 +337,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
conf->working_disks++;
+ mddev->degraded--;
rdev->raid_disk = path;
set_bit(In_sync, &rdev->flags);
rcu_assign_pointer(p->rdev, rdev);
@@ -501,7 +503,7 @@ static int multipath_run (mddev_t *mddev)
mdname(mddev));
goto out_free_conf;
}
- mddev->degraded = conf->raid_disks = conf->working_disks;
+ mddev->degraded = conf->raid_disks - conf->working_disks;
conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
sizeof(struct multipath_bh));
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index dc9d2def027..656fae912fe 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1474,8 +1474,8 @@ static void fix_read_error(conf_t *conf, int read_disk,
"raid1:%s: read error corrected "
"(%d sectors at %llu on %s)\n",
mdname(mddev), s,
- (unsigned long long)sect +
- rdev->data_offset,
+ (unsigned long long)(sect +
+ rdev->data_offset),
bdevname(rdev->bdev, b));
}
}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1250f0eab4a..7492d6033ac 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1470,8 +1470,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
"raid10:%s: read error corrected"
" (%d sectors at %llu on %s)\n",
mdname(mddev), s,
- (unsigned long long)sect+
- rdev->data_offset,
+ (unsigned long long)(sect+
+ rdev->data_offset),
bdevname(rdev->bdev, b));
rdev_dec_pending(rdev, mddev);
@@ -2079,7 +2079,7 @@ static int run(mddev_t *mddev)
disk = conf->mirrors + i;
if (!disk->rdev ||
- !test_bit(In_sync, &rdev->flags)) {
+ !test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0;
mddev->degraded++;
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e14f4578072..69c3e201fa3 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3659,7 +3659,7 @@ static void end_reshape(raid5_conf_t *conf)
bdev = bdget_disk(conf->mddev->gendisk, 0);
if (bdev) {
mutex_lock(&bdev->bd_inode->i_mutex);
- i_size_write(bdev->bd_inode, conf->mddev->array_size << 10);
+ i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10);
mutex_unlock(&bdev->bd_inode->i_mutex);
bdput(bdev);
}