From e24650c2e744f99541125a5b023f0d02cad19d14 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 17 Oct 2006 00:09:38 -0700 Subject: [PATCH] md: fix /proc/mdstat refcounting I have seen mdadm oops after successfully unloading md module. This patch privents from unloading md module while mdadm is polling /proc/mdstat. Cc: Neil Brown Signed-off-by: Akinbou Mita Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/md/md.c') diff --git a/drivers/md/md.c b/drivers/md/md.c index 57fa64f93e5f..f7f19088f3be 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -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, -- cgit From 1c05b4bc22cd640d3a534bd2851a8413d5df3709 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 21 Oct 2006 10:24:08 -0700 Subject: [PATCH] md: endian annotation for v1 superblock access Includes a couple of bugfixes found by sparse. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/md/md.c') diff --git a/drivers/md/md.c b/drivers/md/md.c index f7f19088f3be..7daa7b1e145f 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); -- cgit From 2b6e845986347ef86729e8651908af3e8a8441f5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 28 Oct 2006 10:38:30 -0700 Subject: [PATCH] md: fix bug where spares don't always get rebuilt properly when they become live If save_raid_disk is >= 0, then the device could be a device that is already in sync that is being re-added. So we need to default this value to -1. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/md/md.c') diff --git a/drivers/md/md.c b/drivers/md/md.c index 7daa7b1e145f..c40ce9f9cc9b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2003,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; -- cgit From 01ab5662f573fe3a6bcefa200f15ab3069cec8a3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 28 Oct 2006 10:38:30 -0700 Subject: [PATCH] md: simplify checking of available size when resizing an array When "mdadm --grow --size=xxx" is used to resize an array (use more or less of each device), we check the new siza against the available space in each device. We already have that number recorded in rdev->size, so calculating it is pointless (and wrong in one obscure case). Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/md/md.c') diff --git a/drivers/md/md.c b/drivers/md/md.c index c40ce9f9cc9b..50ab4a936e30 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4045,11 +4045,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)) -- cgit From 7870db4c7fa1b03fec133c4f4e67fdaa04c5ac15 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 2 Nov 2006 22:06:57 -0800 Subject: [PATCH] md: send online/offline uevents when an md array starts/stops This allows udev to do something intelligent when an array becomes available. Acked-by: Greg KH Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/md/md.c') diff --git a/drivers/md/md.c b/drivers/md/md.c index 50ab4a936e30..d11135604403 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3200,6 +3200,7 @@ static int do_md_run(mddev_t * mddev) mddev->changed = 1; md_new_event(mddev); + kobject_uevent(&mddev->gendisk->kobj, KOBJ_ONLINE); return 0; } @@ -3313,6 +3314,7 @@ static int do_md_stop(mddev_t * mddev, int mode) module_put(mddev->pers->owner); mddev->pers = NULL; + kobject_uevent(&mddev->gendisk->kobj, KOBJ_OFFLINE); if (mddev->ro) mddev->ro = 0; } -- cgit