Commit 894bcdfb authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
  md: don't retry recovery of raid1 that fails due to error on source drive.
  md: Allow md devices to be created by name.
  md: make devices disappear when they are no longer needed.
  md: centralise all freeing of an 'mddev' in 'md_free'
  md: move allocation of ->queue from mddev_find to md_probe
  md: need another print_sb for mdp_superblock_1
  md: use list_for_each_entry macro directly
  md: raid0: make hash_spacing and preshift sector-based.
  md: raid0: Represent the size of strip zones in sectors.
  md: raid0 create_strip_zones(): Add KERN_INFO/KERN_ERR to printk's.
  md: raid0 create_strip_zones(): Make two local variables sector-based.
  md: raid0: Represent zone->zone_offset in sectors.
  md: raid0: Represent device offset in sectors.
  md: raid0_make_request(): Replace local variable block by sector.
  md: raid0_make_request(): Remove local variable chunk_size.
  md: raid0_make_request(): Replace chunksize_bits by chunksect_bits.
  md: use sysfs_notify_dirent to notify changes to md/sync_action.
  md: fix bitmap-on-external-file bug.
parents a419df8a 4044ba58
...@@ -215,7 +215,6 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, ...@@ -215,7 +215,6 @@ static struct page *read_sb_page(mddev_t *mddev, long offset,
/* choose a good rdev and read the page from there */ /* choose a good rdev and read the page from there */
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp;
sector_t target; sector_t target;
if (!page) if (!page)
...@@ -223,7 +222,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, ...@@ -223,7 +222,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset,
if (!page) if (!page)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
rdev_for_each(rdev, tmp, mddev) { list_for_each_entry(rdev, &mddev->disks, same_set) {
if (! test_bit(In_sync, &rdev->flags) if (! test_bit(In_sync, &rdev->flags)
|| test_bit(Faulty, &rdev->flags)) || test_bit(Faulty, &rdev->flags))
continue; continue;
...@@ -964,7 +963,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) ...@@ -964,7 +963,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
*/ */
page = bitmap->sb_page; page = bitmap->sb_page;
offset = sizeof(bitmap_super_t); offset = sizeof(bitmap_super_t);
read_sb_page(bitmap->mddev, bitmap->offset, if (!file)
read_sb_page(bitmap->mddev,
bitmap->offset,
page, page,
index, count); index, count);
} else if (file) { } else if (file) {
......
...@@ -283,7 +283,6 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size) ...@@ -283,7 +283,6 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size)
static int run(mddev_t *mddev) static int run(mddev_t *mddev)
{ {
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp;
int i; int i;
conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL);
...@@ -296,7 +295,7 @@ static int run(mddev_t *mddev) ...@@ -296,7 +295,7 @@ static int run(mddev_t *mddev)
} }
conf->nfaults = 0; conf->nfaults = 0;
rdev_for_each(rdev, tmp, mddev) list_for_each_entry(rdev, &mddev->disks, same_set)
conf->rdev = rdev; conf->rdev = rdev;
mddev->array_sectors = mddev->size * 2; mddev->array_sectors = mddev->size * 2;
......
...@@ -105,7 +105,6 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) ...@@ -105,7 +105,6 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
int i, nb_zone, cnt; int i, nb_zone, cnt;
sector_t min_sectors; sector_t min_sectors;
sector_t curr_sector; sector_t curr_sector;
struct list_head *tmp;
conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t),
GFP_KERNEL); GFP_KERNEL);
...@@ -115,7 +114,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) ...@@ -115,7 +114,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
cnt = 0; cnt = 0;
conf->array_sectors = 0; conf->array_sectors = 0;
rdev_for_each(rdev, tmp, mddev) { list_for_each_entry(rdev, &mddev->disks, same_set) {
int j = rdev->raid_disk; int j = rdev->raid_disk;
dev_info_t *disk = conf->disks + j; dev_info_t *disk = conf->disks + j;
......
This diff is collapsed.
...@@ -408,7 +408,6 @@ static int multipath_run (mddev_t *mddev) ...@@ -408,7 +408,6 @@ static int multipath_run (mddev_t *mddev)
int disk_idx; int disk_idx;
struct multipath_info *disk; struct multipath_info *disk;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp;
if (mddev->level != LEVEL_MULTIPATH) { if (mddev->level != LEVEL_MULTIPATH) {
printk("multipath: %s: raid level not set to multipath IO (%d)\n", printk("multipath: %s: raid level not set to multipath IO (%d)\n",
...@@ -441,7 +440,7 @@ static int multipath_run (mddev_t *mddev) ...@@ -441,7 +440,7 @@ static int multipath_run (mddev_t *mddev)
} }
conf->working_disks = 0; conf->working_disks = 0;
rdev_for_each(rdev, tmp, mddev) { list_for_each_entry(rdev, &mddev->disks, same_set) {
disk_idx = rdev->raid_disk; disk_idx = rdev->raid_disk;
if (disk_idx < 0 || if (disk_idx < 0 ||
disk_idx >= mddev->raid_disks) disk_idx >= mddev->raid_disks)
......
This diff is collapsed.
...@@ -1016,12 +1016,16 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -1016,12 +1016,16 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* else mark the drive as failed * else mark the drive as failed
*/ */
if (test_bit(In_sync, &rdev->flags) if (test_bit(In_sync, &rdev->flags)
&& (conf->raid_disks - mddev->degraded) == 1) && (conf->raid_disks - mddev->degraded) == 1) {
/* /*
* Don't fail the drive, act as though we were just a * Don't fail the drive, act as though we were just a
* normal single drive * normal single drive.
* However don't try a recovery from this drive as
* it is very likely to fail.
*/ */
mddev->recovery_disabled = 1;
return; return;
}
if (test_and_clear_bit(In_sync, &rdev->flags)) { if (test_and_clear_bit(In_sync, &rdev->flags)) {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&conf->device_lock, flags); spin_lock_irqsave(&conf->device_lock, flags);
...@@ -1919,7 +1923,6 @@ static int run(mddev_t *mddev) ...@@ -1919,7 +1923,6 @@ static int run(mddev_t *mddev)
int i, j, disk_idx; int i, j, disk_idx;
mirror_info_t *disk; mirror_info_t *disk;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp;
if (mddev->level != 1) { if (mddev->level != 1) {
printk("raid1: %s: raid level not set to mirroring (%d)\n", printk("raid1: %s: raid level not set to mirroring (%d)\n",
...@@ -1964,7 +1967,7 @@ static int run(mddev_t *mddev) ...@@ -1964,7 +1967,7 @@ static int run(mddev_t *mddev)
spin_lock_init(&conf->device_lock); spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock; mddev->queue->queue_lock = &conf->device_lock;
rdev_for_each(rdev, tmp, mddev) { list_for_each_entry(rdev, &mddev->disks, same_set) {
disk_idx = rdev->raid_disk; disk_idx = rdev->raid_disk;
if (disk_idx >= mddev->raid_disks if (disk_idx >= mddev->raid_disks
|| disk_idx < 0) || disk_idx < 0)
......
...@@ -2025,7 +2025,6 @@ static int run(mddev_t *mddev) ...@@ -2025,7 +2025,6 @@ static int run(mddev_t *mddev)
int i, disk_idx; int i, disk_idx;
mirror_info_t *disk; mirror_info_t *disk;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *tmp;
int nc, fc, fo; int nc, fc, fo;
sector_t stride, size; sector_t stride, size;
...@@ -2108,7 +2107,7 @@ static int run(mddev_t *mddev) ...@@ -2108,7 +2107,7 @@ static int run(mddev_t *mddev)
spin_lock_init(&conf->device_lock); spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock; mddev->queue->queue_lock = &conf->device_lock;
rdev_for_each(rdev, tmp, mddev) { list_for_each_entry(rdev, &mddev->disks, same_set) {
disk_idx = rdev->raid_disk; disk_idx = rdev->raid_disk;
if (disk_idx >= mddev->raid_disks if (disk_idx >= mddev->raid_disks
|| disk_idx < 0) || disk_idx < 0)
......
...@@ -3998,7 +3998,6 @@ static int run(mddev_t *mddev) ...@@ -3998,7 +3998,6 @@ static int run(mddev_t *mddev)
int raid_disk, memory; int raid_disk, memory;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct disk_info *disk; struct disk_info *disk;
struct list_head *tmp;
int working_disks = 0; int working_disks = 0;
if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) { if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
...@@ -4108,7 +4107,7 @@ static int run(mddev_t *mddev) ...@@ -4108,7 +4107,7 @@ static int run(mddev_t *mddev)
pr_debug("raid5: run(%s) called.\n", mdname(mddev)); pr_debug("raid5: run(%s) called.\n", mdname(mddev));
rdev_for_each(rdev, tmp, mddev) { list_for_each_entry(rdev, &mddev->disks, same_set) {
raid_disk = rdev->raid_disk; raid_disk = rdev->raid_disk;
if (raid_disk >= conf->raid_disks if (raid_disk >= conf->raid_disks
|| raid_disk < 0) || raid_disk < 0)
...@@ -4533,7 +4532,6 @@ static int raid5_start_reshape(mddev_t *mddev) ...@@ -4533,7 +4532,6 @@ static int raid5_start_reshape(mddev_t *mddev)
{ {
raid5_conf_t *conf = mddev_to_conf(mddev); raid5_conf_t *conf = mddev_to_conf(mddev);
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
struct list_head *rtmp;
int spares = 0; int spares = 0;
int added_devices = 0; int added_devices = 0;
unsigned long flags; unsigned long flags;
...@@ -4541,7 +4539,7 @@ static int raid5_start_reshape(mddev_t *mddev) ...@@ -4541,7 +4539,7 @@ static int raid5_start_reshape(mddev_t *mddev)
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return -EBUSY; return -EBUSY;
rdev_for_each(rdev, rtmp, mddev) list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk < 0 && if (rdev->raid_disk < 0 &&
!test_bit(Faulty, &rdev->flags)) !test_bit(Faulty, &rdev->flags))
spares++; spares++;
...@@ -4563,7 +4561,7 @@ static int raid5_start_reshape(mddev_t *mddev) ...@@ -4563,7 +4561,7 @@ static int raid5_start_reshape(mddev_t *mddev)
/* Add some new drives, as many as will fit. /* Add some new drives, as many as will fit.
* We know there are enough to make the newly sized array work. * We know there are enough to make the newly sized array work.
*/ */
rdev_for_each(rdev, rtmp, mddev) list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk < 0 && if (rdev->raid_disk < 0 &&
!test_bit(Faulty, &rdev->flags)) { !test_bit(Faulty, &rdev->flags)) {
if (raid5_add_disk(mddev, rdev) == 0) { if (raid5_add_disk(mddev, rdev) == 0) {
......
...@@ -1005,6 +1005,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) ...@@ -1005,6 +1005,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
} }
lock_kernel(); lock_kernel();
restart:
ret = -ENXIO; ret = -ENXIO;
disk = get_gendisk(bdev->bd_dev, &partno); disk = get_gendisk(bdev->bd_dev, &partno);
...@@ -1025,6 +1026,19 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) ...@@ -1025,6 +1026,19 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
if (disk->fops->open) { if (disk->fops->open) {
ret = disk->fops->open(bdev, mode); ret = disk->fops->open(bdev, mode);
if (ret == -ERESTARTSYS) {
/* Lost a race with 'disk' being
* deleted, try again.
* See md.c
*/
disk_put_part(bdev->bd_part);
bdev->bd_part = NULL;
module_put(disk->fops->owner);
put_disk(disk);
bdev->bd_disk = NULL;
mutex_unlock(&bdev->bd_mutex);
goto restart;
}
if (ret) if (ret)
goto out_clear; goto out_clear;
} }
......
...@@ -137,6 +137,9 @@ struct mddev_s ...@@ -137,6 +137,9 @@ struct mddev_s
struct gendisk *gendisk; struct gendisk *gendisk;
struct kobject kobj; struct kobject kobj;
int hold_active;
#define UNTIL_IOCTL 1
#define UNTIL_STOP 2
/* Superblock information */ /* Superblock information */
int major_version, int major_version,
...@@ -215,6 +218,9 @@ struct mddev_s ...@@ -215,6 +218,9 @@ struct mddev_s
#define MD_RECOVERY_FROZEN 9 #define MD_RECOVERY_FROZEN 9
unsigned long recovery; unsigned long recovery;
int recovery_disabled; /* if we detect that recovery
* will always fail, set this
* so we don't loop trying */
int in_sync; /* know to not need resync */ int in_sync; /* know to not need resync */
struct mutex reconfig_mutex; struct mutex reconfig_mutex;
...@@ -244,6 +250,9 @@ struct mddev_s ...@@ -244,6 +250,9 @@ struct mddev_s
struct sysfs_dirent *sysfs_state; /* handle for 'array_state' struct sysfs_dirent *sysfs_state; /* handle for 'array_state'
* file in sysfs. * file in sysfs.
*/ */
struct sysfs_dirent *sysfs_action; /* handle for 'sync_action' */
struct work_struct del_work; /* used for delayed sysfs removal */
spinlock_t write_lock; spinlock_t write_lock;
wait_queue_head_t sb_wait; /* for waiting on superblock updates */ wait_queue_head_t sb_wait; /* for waiting on superblock updates */
...@@ -334,17 +343,14 @@ static inline char * mdname (mddev_t * mddev) ...@@ -334,17 +343,14 @@ static inline char * mdname (mddev_t * mddev)
* iterates through some rdev ringlist. It's safe to remove the * iterates through some rdev ringlist. It's safe to remove the
* current 'rdev'. Dont touch 'tmp' though. * current 'rdev'. Dont touch 'tmp' though.
*/ */
#define rdev_for_each_list(rdev, tmp, list) \ #define rdev_for_each_list(rdev, tmp, head) \
\ list_for_each_entry_safe(rdev, tmp, head, same_set)
for ((tmp) = (list).next; \
(rdev) = (list_entry((tmp), mdk_rdev_t, same_set)), \
(tmp) = (tmp)->next, (tmp)->prev != &(list) \
; )
/* /*
* iterates through the 'same array disks' ringlist * iterates through the 'same array disks' ringlist
*/ */
#define rdev_for_each(rdev, tmp, mddev) \ #define rdev_for_each(rdev, tmp, mddev) \
rdev_for_each_list(rdev, tmp, (mddev)->disks) list_for_each_entry_safe(rdev, tmp, &((mddev)->disks), same_set)
#define rdev_for_each_rcu(rdev, mddev) \ #define rdev_for_each_rcu(rdev, mddev) \
list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set) list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
......
...@@ -194,6 +194,8 @@ static inline __u64 md_event(mdp_super_t *sb) { ...@@ -194,6 +194,8 @@ static inline __u64 md_event(mdp_super_t *sb) {
return (ev<<32)| sb->events_lo; return (ev<<32)| sb->events_lo;
} }
#define MD_SUPERBLOCK_1_TIME_SEC_MASK ((1ULL<<40) - 1)
/* /*
* The version-1 superblock : * The version-1 superblock :
* All numeric fields are little-endian. * All numeric fields are little-endian.
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
struct strip_zone struct strip_zone
{ {
sector_t zone_offset; /* Zone offset in md_dev */ sector_t zone_start; /* Zone offset in md_dev (in sectors) */
sector_t dev_offset; /* Zone offset in real dev */ sector_t dev_start; /* Zone offset in real dev (in sectors) */
sector_t size; /* Zone size */ sector_t sectors; /* Zone size in sectors */
int nb_dev; /* # of devices attached to the zone */ int nb_dev; /* # of devices attached to the zone */
mdk_rdev_t **dev; /* Devices attached to the zone */ mdk_rdev_t **dev; /* Devices attached to the zone */
}; };
...@@ -19,8 +19,8 @@ struct raid0_private_data ...@@ -19,8 +19,8 @@ struct raid0_private_data
mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */ mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */
int nr_strip_zones; int nr_strip_zones;
sector_t hash_spacing; sector_t spacing;
int preshift; /* shift this before divide by hash_spacing */ int sector_shift; /* shift this before divide by spacing */
}; };
typedef struct raid0_private_data raid0_conf_t; typedef struct raid0_private_data raid0_conf_t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment