X-Git-Url: http://git.alex.org.uk diff --git a/drivers/md/md.c b/drivers/md/md.c index 1520d18..065ab4f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -54,13 +55,15 @@ #include "md.h" #include "bitmap.h" -#define DEBUG 0 -#define dprintk(x...) ((void)(DEBUG && printk(x))) - #ifndef MODULE static void autostart_arrays(int part); #endif +/* pers_list is a list of registered personalities protected + * by pers_lock. + * pers_lock does extra service to protect accesses to + * mddev->thread when the mutex cannot be held. + */ static LIST_HEAD(pers_list); static DEFINE_SPINLOCK(pers_lock); @@ -93,13 +96,13 @@ static struct workqueue_struct *md_misc_wq; static int sysctl_speed_limit_min = 1000; static int sysctl_speed_limit_max = 200000; -static inline int speed_min(mddev_t *mddev) +static inline int speed_min(struct mddev *mddev) { return mddev->sync_speed_min ? mddev->sync_speed_min : sysctl_speed_limit_min; } -static inline int speed_max(mddev_t *mddev) +static inline int speed_max(struct mddev *mddev) { return mddev->sync_speed_max ? mddev->sync_speed_max : sysctl_speed_limit_max; @@ -155,7 +158,7 @@ static int start_readonly; static void mddev_bio_destructor(struct bio *bio) { - mddev_t *mddev, **mddevp; + struct mddev *mddev, **mddevp; mddevp = (void*)bio; mddev = mddevp[-1]; @@ -164,10 +167,10 @@ static void mddev_bio_destructor(struct bio *bio) } struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, - mddev_t *mddev) + struct mddev *mddev) { struct bio *b; - mddev_t **mddevp; + struct mddev **mddevp; if (!mddev || !mddev->bio_set) return bio_alloc(gfp_mask, nr_iovecs); @@ -184,10 +187,10 @@ struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, EXPORT_SYMBOL_GPL(bio_alloc_mddev); struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask, - mddev_t *mddev) + struct mddev *mddev) { struct bio *b; - mddev_t **mddevp; + struct mddev **mddevp; if (!mddev || !mddev->bio_set) return bio_clone(bio, gfp_mask); @@ -276,7 +279,7 @@ EXPORT_SYMBOL_GPL(md_trim_bio); */ static DECLARE_WAIT_QUEUE_HEAD(md_event_waiters); static atomic_t md_event_count; -void md_new_event(mddev_t *mddev) +void md_new_event(struct mddev *mddev) { atomic_inc(&md_event_count); wake_up(&md_event_waiters); @@ -286,7 +289,7 @@ EXPORT_SYMBOL_GPL(md_new_event); /* Alternate version that can be called from interrupts * when calling sysfs_notify isn't needed. */ -static void md_new_event_inintr(mddev_t *mddev) +static void md_new_event_inintr(struct mddev *mddev) { atomic_inc(&md_event_count); wake_up(&md_event_waiters); @@ -307,19 +310,19 @@ static DEFINE_SPINLOCK(all_mddevs_lock); * Any code which breaks out of this loop while own * a reference to the current mddev and must mddev_put it. */ -#define for_each_mddev(mddev,tmp) \ +#define for_each_mddev(_mddev,_tmp) \ \ for (({ spin_lock(&all_mddevs_lock); \ - tmp = all_mddevs.next; \ - mddev = NULL;}); \ - ({ if (tmp != &all_mddevs) \ - mddev_get(list_entry(tmp, mddev_t, all_mddevs));\ + _tmp = all_mddevs.next; \ + _mddev = NULL;}); \ + ({ if (_tmp != &all_mddevs) \ + mddev_get(list_entry(_tmp, struct mddev, all_mddevs));\ spin_unlock(&all_mddevs_lock); \ - if (mddev) mddev_put(mddev); \ - mddev = list_entry(tmp, mddev_t, all_mddevs); \ - tmp != &all_mddevs;}); \ + if (_mddev) mddev_put(_mddev); \ + _mddev = list_entry(_tmp, struct mddev, all_mddevs); \ + _tmp != &all_mddevs;}); \ ({ spin_lock(&all_mddevs_lock); \ - tmp = tmp->next;}) \ + _tmp = _tmp->next;}) \ ) @@ -330,18 +333,17 @@ static DEFINE_SPINLOCK(all_mddevs_lock); * call has finished, the bio has been linked into some internal structure * and so is visible to ->quiesce(), so we don't need the refcount any more. */ -static int md_make_request(struct request_queue *q, struct bio *bio) +static void md_make_request(struct request_queue *q, struct bio *bio) { const int rw = bio_data_dir(bio); - mddev_t *mddev = q->queuedata; - int rv; + struct mddev *mddev = q->queuedata; int cpu; unsigned int sectors; if (mddev == NULL || mddev->pers == NULL || !mddev->ready) { bio_io_error(bio); - return 0; + return; } smp_rmb(); /* Ensure implications of 'active' are visible */ rcu_read_lock(); @@ -366,7 +368,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio) * go away inside make_request */ sectors = bio_sectors(bio); - rv = mddev->pers->make_request(mddev, bio); + mddev->pers->make_request(mddev, bio); cpu = part_stat_lock(); part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); @@ -375,8 +377,6 @@ static int md_make_request(struct request_queue *q, struct bio *bio) if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) wake_up(&mddev->sb_wait); - - return rv; } /* mddev_suspend makes sure no new requests are submitted @@ -385,7 +385,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio) * Once ->stop is called and completes, the module will be completely * unused. */ -void mddev_suspend(mddev_t *mddev) +void mddev_suspend(struct mddev *mddev) { BUG_ON(mddev->suspended); mddev->suspended = 1; @@ -395,7 +395,7 @@ void mddev_suspend(mddev_t *mddev) } EXPORT_SYMBOL_GPL(mddev_suspend); -void mddev_resume(mddev_t *mddev) +void mddev_resume(struct mddev *mddev) { mddev->suspended = 0; wake_up(&mddev->sb_wait); @@ -406,7 +406,7 @@ void mddev_resume(mddev_t *mddev) } EXPORT_SYMBOL_GPL(mddev_resume); -int mddev_congested(mddev_t *mddev, int bits) +int mddev_congested(struct mddev *mddev, int bits) { return mddev->suspended; } @@ -418,8 +418,8 @@ EXPORT_SYMBOL(mddev_congested); static void md_end_flush(struct bio *bio, int err) { - mdk_rdev_t *rdev = bio->bi_private; - mddev_t *mddev = rdev->mddev; + struct md_rdev *rdev = bio->bi_private; + struct mddev *mddev = rdev->mddev; rdev_dec_pending(rdev, mddev); @@ -434,8 +434,8 @@ static void md_submit_flush_data(struct work_struct *ws); static void submit_flushes(struct work_struct *ws) { - mddev_t *mddev = container_of(ws, mddev_t, flush_work); - mdk_rdev_t *rdev; + struct mddev *mddev = container_of(ws, struct mddev, flush_work); + struct md_rdev *rdev; INIT_WORK(&mddev->flush_work, md_submit_flush_data); atomic_set(&mddev->flush_pending, 1); @@ -467,7 +467,7 @@ static void submit_flushes(struct work_struct *ws) static void md_submit_flush_data(struct work_struct *ws) { - mddev_t *mddev = container_of(ws, mddev_t, flush_work); + struct mddev *mddev = container_of(ws, struct mddev, flush_work); struct bio *bio = mddev->flush_bio; if (bio->bi_size == 0) @@ -475,15 +475,14 @@ static void md_submit_flush_data(struct work_struct *ws) bio_endio(bio, 0); else { bio->bi_rw &= ~REQ_FLUSH; - if (mddev->pers->make_request(mddev, bio)) - generic_make_request(bio); + mddev->pers->make_request(mddev, bio); } mddev->flush_bio = NULL; wake_up(&mddev->sb_wait); } -void md_flush_request(mddev_t *mddev, struct bio *bio) +void md_flush_request(struct mddev *mddev, struct bio *bio) { spin_lock_irq(&mddev->write_lock); wait_event_lock_irq(mddev->sb_wait, @@ -507,7 +506,7 @@ EXPORT_SYMBOL(md_flush_request); */ struct md_plug_cb { struct blk_plug_cb cb; - mddev_t *mddev; + struct mddev *mddev; }; static void plugger_unplug(struct blk_plug_cb *cb) @@ -521,7 +520,7 @@ static void plugger_unplug(struct blk_plug_cb *cb) /* Check that an unplug wakeup will come shortly. * If not, wakeup the md thread immediately */ -int mddev_check_plugged(mddev_t *mddev) +int mddev_check_plugged(struct mddev *mddev) { struct blk_plug *plug = current->plug; struct md_plug_cb *mdcb; @@ -553,7 +552,7 @@ int mddev_check_plugged(mddev_t *mddev) } EXPORT_SYMBOL_GPL(mddev_check_plugged); -static inline mddev_t *mddev_get(mddev_t *mddev) +static inline struct mddev *mddev_get(struct mddev *mddev) { atomic_inc(&mddev->active); return mddev; @@ -561,7 +560,7 @@ static inline mddev_t *mddev_get(mddev_t *mddev) static void mddev_delayed_delete(struct work_struct *ws); -static void mddev_put(mddev_t *mddev) +static void mddev_put(struct mddev *mddev) { struct bio_set *bs = NULL; @@ -571,7 +570,7 @@ static void mddev_put(mddev_t *mddev) mddev->ctime == 0 && !mddev->hold_active) { /* Array is not configured at all, and not held active, * so destroy it */ - list_del(&mddev->all_mddevs); + list_del_init(&mddev->all_mddevs); bs = mddev->bio_set; mddev->bio_set = NULL; if (mddev->gendisk) { @@ -590,7 +589,7 @@ static void mddev_put(mddev_t *mddev) bioset_free(bs); } -void mddev_init(mddev_t *mddev) +void mddev_init(struct mddev *mddev) { mutex_init(&mddev->open_mutex); mutex_init(&mddev->reconfig_mutex); @@ -613,9 +612,9 @@ void mddev_init(mddev_t *mddev) } EXPORT_SYMBOL_GPL(mddev_init); -static mddev_t * mddev_find(dev_t unit) +static struct mddev * mddev_find(dev_t unit) { - mddev_t *mddev, *new = NULL; + struct mddev *mddev, *new = NULL; if (unit && MAJOR(unit) != MD_MAJOR) unit &= ~((1<reconfig_mutex); } -static inline int mddev_is_locked(mddev_t *mddev) +static inline int mddev_is_locked(struct mddev *mddev) { return mutex_is_locked(&mddev->reconfig_mutex); } -static inline int mddev_trylock(mddev_t * mddev) +static inline int mddev_trylock(struct mddev * mddev) { return mutex_trylock(&mddev->reconfig_mutex); } static struct attribute_group md_redundancy_group; -static void mddev_unlock(mddev_t * mddev) +static void mddev_unlock(struct mddev * mddev) { if (mddev->to_remove) { /* These cannot be removed under reconfig_mutex as @@ -739,12 +738,17 @@ static void mddev_unlock(mddev_t * mddev) } else mutex_unlock(&mddev->reconfig_mutex); + /* As we've dropped the mutex we need a spinlock to + * make sure the thread doesn't disappear + */ + spin_lock(&pers_lock); md_wakeup_thread(mddev->thread); + spin_unlock(&pers_lock); } -static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) +static struct md_rdev * find_rdev_nr(struct mddev *mddev, int nr) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; list_for_each_entry(rdev, &mddev->disks, same_set) if (rdev->desc_nr == nr) @@ -753,9 +757,9 @@ static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) return NULL; } -static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev) +static struct md_rdev * find_rdev(struct mddev * mddev, dev_t dev) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; list_for_each_entry(rdev, &mddev->disks, same_set) if (rdev->bdev->bd_dev == dev) @@ -764,9 +768,9 @@ static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev) return NULL; } -static struct mdk_personality *find_pers(int level, char *clevel) +static struct md_personality *find_pers(int level, char *clevel) { - struct mdk_personality *pers; + struct md_personality *pers; list_for_each_entry(pers, &pers_list, list) { if (level != LEVEL_NONE && pers->level == level) return pers; @@ -777,13 +781,13 @@ static struct mdk_personality *find_pers(int level, char *clevel) } /* return the offset of the super block in 512byte sectors */ -static inline sector_t calc_dev_sboffset(mdk_rdev_t *rdev) +static inline sector_t calc_dev_sboffset(struct md_rdev *rdev) { sector_t num_sectors = i_size_read(rdev->bdev->bd_inode) / 512; return MD_NEW_SIZE_SECTORS(num_sectors); } -static int alloc_disk_sb(mdk_rdev_t * rdev) +static int alloc_disk_sb(struct md_rdev * rdev) { if (rdev->sb_page) MD_BUG(); @@ -797,7 +801,7 @@ static int alloc_disk_sb(mdk_rdev_t * rdev) return 0; } -static void free_disk_sb(mdk_rdev_t * rdev) +static void free_disk_sb(struct md_rdev * rdev) { if (rdev->sb_page) { put_page(rdev->sb_page); @@ -815,8 +819,8 @@ static void free_disk_sb(mdk_rdev_t * rdev) static void super_written(struct bio *bio, int error) { - mdk_rdev_t *rdev = bio->bi_private; - mddev_t *mddev = rdev->mddev; + struct md_rdev *rdev = bio->bi_private; + struct mddev *mddev = rdev->mddev; if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) { printk("md: super_written gets error=%d, uptodate=%d\n", @@ -830,7 +834,7 @@ static void super_written(struct bio *bio, int error) bio_put(bio); } -void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, +void md_super_write(struct mddev *mddev, struct md_rdev *rdev, sector_t sector, int size, struct page *page) { /* write first size bytes of page to sector of rdev @@ -848,10 +852,10 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, bio->bi_end_io = super_written; atomic_inc(&mddev->pending_writes); - submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio); + submit_bio(WRITE_FLUSH_FUA, bio); } -void md_super_wait(mddev_t *mddev) +void md_super_wait(struct mddev *mddev) { /* wait for all superblock writes that were scheduled to complete */ DEFINE_WAIT(wq); @@ -869,7 +873,7 @@ static void bi_complete(struct bio *bio, int error) complete((struct completion*)bio->bi_private); } -int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size, +int sync_page_io(struct md_rdev *rdev, sector_t sector, int size, struct page *page, int rw, bool metadata_op) { struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev); @@ -897,7 +901,7 @@ int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size, } EXPORT_SYMBOL_GPL(sync_page_io); -static int read_disk_sb(mdk_rdev_t * rdev, int size) +static int read_disk_sb(struct md_rdev * rdev, int size) { char b[BDEVNAME_SIZE]; if (!rdev->sb_page) { @@ -1004,7 +1008,7 @@ static unsigned int calc_sb_csum(mdp_super_t * sb) * We rely on user-space to write the initial superblock, and support * reading and updating of superblocks. * Interface methods are: - * int load_super(mdk_rdev_t *dev, mdk_rdev_t *refdev, int minor_version) + * int load_super(struct md_rdev *dev, struct md_rdev *refdev, int minor_version) * loads and validates a superblock on dev. * if refdev != NULL, compare superblocks on both devices * Return: @@ -1014,13 +1018,13 @@ static unsigned int calc_sb_csum(mdp_super_t * sb) * -EINVAL superblock incompatible or invalid * -othererror e.g. -EIO * - * int validate_super(mddev_t *mddev, mdk_rdev_t *dev) + * int validate_super(struct mddev *mddev, struct md_rdev *dev) * Verify that dev is acceptable into mddev. * The first time, mddev->raid_disks will be 0, and data from * dev should be merged in. Subsequent calls check that dev * is new enough. Return 0 or -EINVAL * - * void sync_super(mddev_t *mddev, mdk_rdev_t *dev) + * void sync_super(struct mddev *mddev, struct md_rdev *dev) * Update the superblock for rdev with data in mddev * This does not write to disc. * @@ -1029,11 +1033,11 @@ static unsigned int calc_sb_csum(mdp_super_t * sb) struct super_type { char *name; struct module *owner; - int (*load_super)(mdk_rdev_t *rdev, mdk_rdev_t *refdev, + int (*load_super)(struct md_rdev *rdev, struct md_rdev *refdev, int minor_version); - int (*validate_super)(mddev_t *mddev, mdk_rdev_t *rdev); - void (*sync_super)(mddev_t *mddev, mdk_rdev_t *rdev); - unsigned long long (*rdev_size_change)(mdk_rdev_t *rdev, + int (*validate_super)(struct mddev *mddev, struct md_rdev *rdev); + void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); + unsigned long long (*rdev_size_change)(struct md_rdev *rdev, sector_t num_sectors); }; @@ -1045,7 +1049,7 @@ struct super_type { * has a bitmap. Otherwise, it returns 0. * */ -int md_check_no_bitmap(mddev_t *mddev) +int md_check_no_bitmap(struct mddev *mddev) { if (!mddev->bitmap_info.file && !mddev->bitmap_info.offset) return 0; @@ -1058,7 +1062,7 @@ EXPORT_SYMBOL(md_check_no_bitmap); /* * load_super for 0.90.0 */ -static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) +static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_version) { char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; mdp_super_t *sb; @@ -1138,8 +1142,11 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version ret = 0; } rdev->sectors = rdev->sb_start; + /* Limit to 4TB as metadata cannot record more than that */ + if (rdev->sectors >= (2ULL << 32)) + rdev->sectors = (2ULL << 32) - 2; - if (rdev->sectors < sb->size * 2 && sb->level > 1) + if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) /* "this cannot possibly happen" ... */ ret = -EINVAL; @@ -1150,7 +1157,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version /* * validate_super for 0.90.0 */ -static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) +static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) { mdp_disk_t *desc; mdp_super_t *sb = page_address(rdev->sb_page); @@ -1173,7 +1180,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->clevel[0] = 0; mddev->layout = sb->layout; mddev->raid_disks = sb->raid_disks; - mddev->dev_sectors = sb->size * 2; + mddev->dev_sectors = ((sector_t)sb->size) * 2; mddev->events = ev1; mddev->bitmap_info.offset = 0; mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; @@ -1262,10 +1269,10 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) /* * sync_super for 0.90.0 */ -static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) +static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev) { mdp_super_t *sb; - mdk_rdev_t *rdev2; + struct md_rdev *rdev2; int next_spare = mddev->raid_disks; @@ -1406,7 +1413,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) * rdev_size_change for 0.90.0 */ static unsigned long long -super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) +super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) { if (num_sectors && num_sectors < rdev->mddev->dev_sectors) return 0; /* component must fit device */ @@ -1415,6 +1422,11 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) rdev->sb_start = calc_dev_sboffset(rdev); if (!num_sectors || num_sectors > rdev->sb_start) num_sectors = rdev->sb_start; + /* Limit to 4TB as metadata cannot record more than that. + * 4TB == 2^32 KB, or 2*2^32 sectors. + */ + if (num_sectors >= (2ULL << 32)) + num_sectors = (2ULL << 32) - 2; md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); @@ -1451,7 +1463,7 @@ static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb) static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, int acknowledged); -static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) +static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_version) { struct mdp_superblock_1 *sb; int ret; @@ -1607,7 +1619,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) return ret; } -static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) +static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) { struct mdp_superblock_1 *sb = page_address(rdev->sb_page); __u64 ev1 = le64_to_cpu(sb->events); @@ -1708,10 +1720,10 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) return 0; } -static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) +static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) { struct mdp_superblock_1 *sb; - mdk_rdev_t *rdev2; + struct md_rdev *rdev2; int max_dev, i; /* make rdev->sb match mddev and rdev data. */ @@ -1738,6 +1750,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->level = cpu_to_le32(mddev->level); sb->layout = cpu_to_le32(mddev->layout); + if (test_bit(WriteMostly, &rdev->flags)) + sb->devflags |= WriteMostly1; + else + sb->devflags &= ~WriteMostly1; + if (mddev->bitmap && mddev->bitmap_info.file == NULL) { sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); @@ -1784,13 +1801,13 @@ retry: | BB_LEN(internal_bb)); *bbp++ = cpu_to_le64(store_bb); } + bb->changed = 0; if (read_seqretry(&bb->lock, seq)) goto retry; bb->sector = (rdev->sb_start + (int)le32_to_cpu(sb->bblog_offset)); bb->size = le16_to_cpu(sb->bblog_size); - bb->changed = 0; } } @@ -1828,7 +1845,7 @@ retry: } static unsigned long long -super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) +super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) { struct mdp_superblock_1 *sb; sector_t max_sectors; @@ -1882,7 +1899,7 @@ static struct super_type super_types[] = { }, }; -static void sync_super(mddev_t *mddev, mdk_rdev_t *rdev) +static void sync_super(struct mddev *mddev, struct md_rdev *rdev) { if (mddev->sync_super) { mddev->sync_super(mddev, rdev); @@ -1894,9 +1911,9 @@ static void sync_super(mddev_t *mddev, mdk_rdev_t *rdev) super_types[mddev->major_version].sync_super(mddev, rdev); } -static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2) +static int match_mddev_units(struct mddev *mddev1, struct mddev *mddev2) { - mdk_rdev_t *rdev, *rdev2; + struct md_rdev *rdev, *rdev2; rcu_read_lock(); rdev_for_each_rcu(rdev, mddev1) @@ -1919,9 +1936,9 @@ static LIST_HEAD(pending_raid_disks); * from the array. It only succeeds if all working and active component devices * are integrity capable with matching profiles. */ -int md_integrity_register(mddev_t *mddev) +int md_integrity_register(struct mddev *mddev) { - mdk_rdev_t *rdev, *reference = NULL; + struct md_rdev *rdev, *reference = NULL; if (list_empty(&mddev->disks)) return 0; /* nothing to do */ @@ -1966,7 +1983,7 @@ int md_integrity_register(mddev_t *mddev) EXPORT_SYMBOL(md_integrity_register); /* Disable data integrity if non-capable/non-matching disk is being added */ -void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev) +void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev) { struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev); struct blk_integrity *bi_mddev = blk_get_integrity(mddev->gendisk); @@ -1983,7 +2000,7 @@ void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev) } EXPORT_SYMBOL(md_integrity_add_rdev); -static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) +static int bind_rdev_to_array(struct md_rdev * rdev, struct mddev * mddev) { char b[BDEVNAME_SIZE]; struct kobject *ko; @@ -2063,12 +2080,12 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) static void md_delayed_delete(struct work_struct *ws) { - mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work); + struct md_rdev *rdev = container_of(ws, struct md_rdev, del_work); kobject_del(&rdev->kobj); kobject_put(&rdev->kobj); } -static void unbind_rdev_from_array(mdk_rdev_t * rdev) +static void unbind_rdev_from_array(struct md_rdev * rdev) { char b[BDEVNAME_SIZE]; if (!rdev->mddev) { @@ -2100,14 +2117,14 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) * otherwise reused by a RAID array (or any other kernel * subsystem), by bd_claiming the device. */ -static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) +static int lock_rdev(struct md_rdev *rdev, dev_t dev, int shared) { int err = 0; struct block_device *bdev; char b[BDEVNAME_SIZE]; bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, - shared ? (mdk_rdev_t *)lock_rdev : rdev); + shared ? (struct md_rdev *)lock_rdev : rdev); if (IS_ERR(bdev)) { printk(KERN_ERR "md: could not open %s.\n", __bdevname(dev, b)); @@ -2117,7 +2134,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) return err; } -static void unlock_rdev(mdk_rdev_t *rdev) +static void unlock_rdev(struct md_rdev *rdev) { struct block_device *bdev = rdev->bdev; rdev->bdev = NULL; @@ -2128,7 +2145,7 @@ static void unlock_rdev(mdk_rdev_t *rdev) void md_autodetect_dev(dev_t dev); -static void export_rdev(mdk_rdev_t * rdev) +static void export_rdev(struct md_rdev * rdev) { char b[BDEVNAME_SIZE]; printk(KERN_INFO "md: export_rdev(%s)\n", @@ -2144,15 +2161,15 @@ static void export_rdev(mdk_rdev_t * rdev) kobject_put(&rdev->kobj); } -static void kick_rdev_from_array(mdk_rdev_t * rdev) +static void kick_rdev_from_array(struct md_rdev * rdev) { unbind_rdev_from_array(rdev); export_rdev(rdev); } -static void export_array(mddev_t *mddev) +static void export_array(struct mddev *mddev) { - mdk_rdev_t *rdev, *tmp; + struct md_rdev *rdev, *tmp; rdev_for_each(rdev, tmp, mddev) { if (!rdev->mddev) { @@ -2248,7 +2265,7 @@ static void print_sb_1(struct mdp_superblock_1 *sb) ); } -static void print_rdev(mdk_rdev_t *rdev, int major_version) +static void print_rdev(struct md_rdev *rdev, int major_version) { char b[BDEVNAME_SIZE]; printk(KERN_INFO "md: rdev %s, Sect:%08llu F:%d S:%d DN:%u\n", @@ -2272,8 +2289,8 @@ static void print_rdev(mdk_rdev_t *rdev, int major_version) static void md_print_devices(void) { struct list_head *tmp; - mdk_rdev_t *rdev; - mddev_t *mddev; + struct md_rdev *rdev; + struct mddev *mddev; char b[BDEVNAME_SIZE]; printk("\n"); @@ -2298,7 +2315,7 @@ static void md_print_devices(void) } -static void sync_sbs(mddev_t * mddev, int nospares) +static void sync_sbs(struct mddev * mddev, int nospares) { /* Update each superblock (in-memory image), but * if we are allowed to, skip spares which already @@ -2306,7 +2323,7 @@ static void sync_sbs(mddev_t * mddev, int nospares) * (which would mean they aren't being marked as dirty * with the rest of the array) */ - mdk_rdev_t *rdev; + struct md_rdev *rdev; list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->sb_events == mddev->events || (nospares && @@ -2321,9 +2338,9 @@ static void sync_sbs(mddev_t * mddev, int nospares) } } -static void md_update_sb(mddev_t * mddev, int force_change) +static void md_update_sb(struct mddev * mddev, int force_change) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; int sync_req; int nospares = 0; int any_badblocks_changed = 0; @@ -2341,8 +2358,19 @@ repeat: if (!mddev->persistent) { clear_bit(MD_CHANGE_CLEAN, &mddev->flags); clear_bit(MD_CHANGE_DEVS, &mddev->flags); - if (!mddev->external) + if (!mddev->external) { clear_bit(MD_CHANGE_PENDING, &mddev->flags); + list_for_each_entry(rdev, &mddev->disks, same_set) { + if (rdev->badblocks.changed) { + rdev->badblocks.changed = 0; + md_ack_all_badblocks(&rdev->badblocks); + md_error(mddev, rdev); + } + clear_bit(Blocked, &rdev->flags); + clear_bit(BlockedBadBlocks, &rdev->flags); + wake_up(&rdev->blocked_wait); + } + } wake_up(&mddev->sb_wait); return; } @@ -2399,34 +2427,34 @@ repeat: mddev->events --; } - list_for_each_entry(rdev, &mddev->disks, same_set) + list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->badblocks.changed) any_badblocks_changed++; + if (test_bit(Faulty, &rdev->flags)) + set_bit(FaultRecorded, &rdev->flags); + } sync_sbs(mddev, nospares); spin_unlock_irq(&mddev->write_lock); - dprintk(KERN_INFO - "md: updating %s RAID superblock on device (in sync %d)\n", - mdname(mddev),mddev->in_sync); + pr_debug("md: updating %s RAID superblock on device (in sync %d)\n", + mdname(mddev), mddev->in_sync); bitmap_update_sb(mddev->bitmap); list_for_each_entry(rdev, &mddev->disks, same_set) { char b[BDEVNAME_SIZE]; - dprintk(KERN_INFO "md: "); + if (rdev->sb_loaded != 1) continue; /* no noise on spare devices */ - if (test_bit(Faulty, &rdev->flags)) - dprintk("(skipping faulty "); - dprintk("%s ", bdevname(rdev->bdev,b)); - if (!test_bit(Faulty, &rdev->flags)) { + if (!test_bit(Faulty, &rdev->flags) && + rdev->saved_raid_disk == -1) { md_super_write(mddev,rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); - dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", - bdevname(rdev->bdev,b), - (unsigned long long)rdev->sb_start); + pr_debug("md: (write) %s's sb offset: %llu\n", + bdevname(rdev->bdev, b), + (unsigned long long)rdev->sb_start); rdev->sb_events = mddev->events; if (rdev->badblocks.size) { md_super_write(mddev, rdev, @@ -2436,8 +2464,12 @@ repeat: rdev->badblocks.size = 0; } - } else - dprintk(")\n"); + } else if (test_bit(Faulty, &rdev->flags)) + pr_debug("md: %s (skipping faulty)\n", + bdevname(rdev->bdev, b)); + else + pr_debug("(skipping incremental s/r "); + if (mddev->level == LEVEL_MULTIPATH) /* only need to write one superblock... */ break; @@ -2458,9 +2490,15 @@ repeat: if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) sysfs_notify(&mddev->kobj, NULL, "sync_completed"); - if (any_badblocks_changed) - list_for_each_entry(rdev, &mddev->disks, same_set) + list_for_each_entry(rdev, &mddev->disks, same_set) { + if (test_and_clear_bit(FaultRecorded, &rdev->flags)) + clear_bit(Blocked, &rdev->flags); + + if (any_badblocks_changed) md_ack_all_badblocks(&rdev->badblocks); + clear_bit(BlockedBadBlocks, &rdev->flags); + wake_up(&rdev->blocked_wait); + } } /* words written to sysfs files may, or may not, be \n terminated. @@ -2485,17 +2523,18 @@ static int cmd_match(const char *cmd, const char *str) struct rdev_sysfs_entry { struct attribute attr; - ssize_t (*show)(mdk_rdev_t *, char *); - ssize_t (*store)(mdk_rdev_t *, const char *, size_t); + ssize_t (*show)(struct md_rdev *, char *); + ssize_t (*store)(struct md_rdev *, const char *, size_t); }; static ssize_t -state_show(mdk_rdev_t *rdev, char *page) +state_show(struct md_rdev *rdev, char *page) { char *sep = ""; size_t len = 0; - if (test_bit(Faulty, &rdev->flags)) { + if (test_bit(Faulty, &rdev->flags) || + rdev->badblocks.unacked_exist) { len+= sprintf(page+len, "%sfaulty",sep); sep = ","; } @@ -2507,7 +2546,9 @@ state_show(mdk_rdev_t *rdev, char *page) len += sprintf(page+len, "%swrite_mostly",sep); sep = ","; } - if (test_bit(Blocked, &rdev->flags)) { + if (test_bit(Blocked, &rdev->flags) || + (rdev->badblocks.unacked_exist + && !test_bit(Faulty, &rdev->flags))) { len += sprintf(page+len, "%sblocked", sep); sep = ","; } @@ -2524,15 +2565,15 @@ state_show(mdk_rdev_t *rdev, char *page) } static ssize_t -state_store(mdk_rdev_t *rdev, const char *buf, size_t len) +state_store(struct md_rdev *rdev, const char *buf, size_t len) { /* can write - * faulty - simulates and error + * faulty - simulates an error * remove - disconnects the device * writemostly - sets write_mostly * -writemostly - clears write_mostly - * blocked - sets the Blocked flag - * -blocked - clears the Blocked flag + * blocked - sets the Blocked flags + * -blocked - clears the Blocked and possibly simulates an error * insync - sets Insync providing device isn't active * write_error - sets WriteErrorSeen * -write_error - clears WriteErrorSeen @@ -2540,12 +2581,15 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) int err = -EINVAL; if (cmd_match(buf, "faulty") && rdev->mddev->pers) { md_error(rdev->mddev, rdev); - err = 0; + if (test_bit(Faulty, &rdev->flags)) + err = 0; + else + err = -EBUSY; } else if (cmd_match(buf, "remove")) { if (rdev->raid_disk >= 0) err = -EBUSY; else { - mddev_t *mddev = rdev->mddev; + struct mddev *mddev = rdev->mddev; kick_rdev_from_array(rdev); if (mddev->pers) md_update_sb(mddev, 1); @@ -2562,7 +2606,15 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) set_bit(Blocked, &rdev->flags); err = 0; } else if (cmd_match(buf, "-blocked")) { + if (!test_bit(Faulty, &rdev->flags) && + rdev->badblocks.unacked_exist) { + /* metadata handler doesn't understand badblocks, + * so we need to fail the device + */ + md_error(rdev->mddev, rdev); + } clear_bit(Blocked, &rdev->flags); + clear_bit(BlockedBadBlocks, &rdev->flags); wake_up(&rdev->blocked_wait); set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); md_wakeup_thread(rdev->mddev->thread); @@ -2586,13 +2638,13 @@ static struct rdev_sysfs_entry rdev_state = __ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store); static ssize_t -errors_show(mdk_rdev_t *rdev, char *page) +errors_show(struct md_rdev *rdev, char *page) { return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors)); } static ssize_t -errors_store(mdk_rdev_t *rdev, const char *buf, size_t len) +errors_store(struct md_rdev *rdev, const char *buf, size_t len) { char *e; unsigned long n = simple_strtoul(buf, &e, 10); @@ -2606,7 +2658,7 @@ static struct rdev_sysfs_entry rdev_errors = __ATTR(errors, S_IRUGO|S_IWUSR, errors_show, errors_store); static ssize_t -slot_show(mdk_rdev_t *rdev, char *page) +slot_show(struct md_rdev *rdev, char *page) { if (rdev->raid_disk < 0) return sprintf(page, "none\n"); @@ -2615,7 +2667,7 @@ slot_show(mdk_rdev_t *rdev, char *page) } static ssize_t -slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) +slot_store(struct md_rdev *rdev, const char *buf, size_t len) { char *e; int err; @@ -2646,7 +2698,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); md_wakeup_thread(rdev->mddev->thread); } else if (rdev->mddev->pers) { - mdk_rdev_t *rdev2; + struct md_rdev *rdev2; /* Activating a spare .. or possibly reactivating * if we ever get bitmaps working here. */ @@ -2673,6 +2725,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) rdev->saved_raid_disk = slot; else rdev->saved_raid_disk = -1; + clear_bit(In_sync, &rdev->flags); err = rdev->mddev->pers-> hot_add_disk(rdev->mddev, rdev); if (err) { @@ -2702,13 +2755,13 @@ static struct rdev_sysfs_entry rdev_slot = __ATTR(slot, S_IRUGO|S_IWUSR, slot_show, slot_store); static ssize_t -offset_show(mdk_rdev_t *rdev, char *page) +offset_show(struct md_rdev *rdev, char *page) { return sprintf(page, "%llu\n", (unsigned long long)rdev->data_offset); } static ssize_t -offset_store(mdk_rdev_t *rdev, const char *buf, size_t len) +offset_store(struct md_rdev *rdev, const char *buf, size_t len) { char *e; unsigned long long offset = simple_strtoull(buf, &e, 10); @@ -2728,7 +2781,7 @@ static struct rdev_sysfs_entry rdev_offset = __ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store); static ssize_t -rdev_size_show(mdk_rdev_t *rdev, char *page) +rdev_size_show(struct md_rdev *rdev, char *page) { return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2); } @@ -2763,9 +2816,9 @@ static int strict_blocks_to_sectors(const char *buf, sector_t *sectors) } static ssize_t -rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) +rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len) { - mddev_t *my_mddev = rdev->mddev; + struct mddev *my_mddev = rdev->mddev; sector_t oldsectors = rdev->sectors; sector_t sectors; @@ -2791,13 +2844,13 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) * a deadlock. We have already changed rdev->sectors, and if * we have to change it back, we will have the lock again. */ - mddev_t *mddev; + struct mddev *mddev; int overlap = 0; struct list_head *tmp; mddev_unlock(my_mddev); for_each_mddev(mddev, tmp) { - mdk_rdev_t *rdev2; + struct md_rdev *rdev2; mddev_lock(mddev); list_for_each_entry(rdev2, &mddev->disks, same_set) @@ -2834,7 +2887,7 @@ static struct rdev_sysfs_entry rdev_size = __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store); -static ssize_t recovery_start_show(mdk_rdev_t *rdev, char *page) +static ssize_t recovery_start_show(struct md_rdev *rdev, char *page) { unsigned long long recovery_start = rdev->recovery_offset; @@ -2845,7 +2898,7 @@ static ssize_t recovery_start_show(mdk_rdev_t *rdev, char *page) return sprintf(page, "%llu\n", recovery_start); } -static ssize_t recovery_start_store(mdk_rdev_t *rdev, const char *buf, size_t len) +static ssize_t recovery_start_store(struct md_rdev *rdev, const char *buf, size_t len) { unsigned long long recovery_start; @@ -2875,23 +2928,27 @@ badblocks_show(struct badblocks *bb, char *page, int unack); static ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack); -static ssize_t bb_show(mdk_rdev_t *rdev, char *page) +static ssize_t bb_show(struct md_rdev *rdev, char *page) { return badblocks_show(&rdev->badblocks, page, 0); } -static ssize_t bb_store(mdk_rdev_t *rdev, const char *page, size_t len) +static ssize_t bb_store(struct md_rdev *rdev, const char *page, size_t len) { - return badblocks_store(&rdev->badblocks, page, len, 0); + int rv = badblocks_store(&rdev->badblocks, page, len, 0); + /* Maybe that ack was all we needed */ + if (test_and_clear_bit(BlockedBadBlocks, &rdev->flags)) + wake_up(&rdev->blocked_wait); + return rv; } static struct rdev_sysfs_entry rdev_bad_blocks = __ATTR(bad_blocks, S_IRUGO|S_IWUSR, bb_show, bb_store); -static ssize_t ubb_show(mdk_rdev_t *rdev, char *page) +static ssize_t ubb_show(struct md_rdev *rdev, char *page) { return badblocks_show(&rdev->badblocks, page, 1); } -static ssize_t ubb_store(mdk_rdev_t *rdev, const char *page, size_t len) +static ssize_t ubb_store(struct md_rdev *rdev, const char *page, size_t len) { return badblocks_store(&rdev->badblocks, page, len, 1); } @@ -2913,8 +2970,8 @@ static ssize_t rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page) { struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); - mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); - mddev_t *mddev = rdev->mddev; + struct md_rdev *rdev = container_of(kobj, struct md_rdev, kobj); + struct mddev *mddev = rdev->mddev; ssize_t rv; if (!entry->show) @@ -2936,9 +2993,9 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, const char *page, size_t length) { struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); - mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); + struct md_rdev *rdev = container_of(kobj, struct md_rdev, kobj); ssize_t rv; - mddev_t *mddev = rdev->mddev; + struct mddev *mddev = rdev->mddev; if (!entry->store) return -EIO; @@ -2957,7 +3014,7 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, static void rdev_free(struct kobject *ko) { - mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj); + struct md_rdev *rdev = container_of(ko, struct md_rdev, kobj); kfree(rdev); } static const struct sysfs_ops rdev_sysfs_ops = { @@ -2970,7 +3027,7 @@ static struct kobj_type rdev_ktype = { .default_attrs = rdev_default_attrs, }; -int md_rdev_init(mdk_rdev_t *rdev) +int md_rdev_init(struct md_rdev *rdev) { rdev->desc_nr = -1; rdev->saved_raid_disk = -1; @@ -3013,11 +3070,11 @@ EXPORT_SYMBOL_GPL(md_rdev_init); * * a faulty rdev _never_ has rdev->sb set. */ -static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_minor) +static struct md_rdev *md_import_device(dev_t newdev, int super_format, int super_minor) { char b[BDEVNAME_SIZE]; int err; - mdk_rdev_t *rdev; + struct md_rdev *rdev; sector_t size; rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); @@ -3086,10 +3143,10 @@ abort_free: */ -static void analyze_sbs(mddev_t * mddev) +static void analyze_sbs(struct mddev * mddev) { int i; - mdk_rdev_t *rdev, *freshest, *tmp; + struct md_rdev *rdev, *freshest, *tmp; char b[BDEVNAME_SIZE]; freshest = NULL; @@ -3189,13 +3246,13 @@ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale) static void md_safemode_timeout(unsigned long data); static ssize_t -safe_delay_show(mddev_t *mddev, char *page) +safe_delay_show(struct mddev *mddev, char *page) { int msec = (mddev->safemode_delay*1000)/HZ; return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); } static ssize_t -safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) +safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) { unsigned long msec; @@ -3217,9 +3274,9 @@ static struct md_sysfs_entry md_safe_delay = __ATTR(safe_mode_delay, S_IRUGO|S_IWUSR,safe_delay_show, safe_delay_store); static ssize_t -level_show(mddev_t *mddev, char *page) +level_show(struct mddev *mddev, char *page) { - struct mdk_personality *p = mddev->pers; + struct md_personality *p = mddev->pers; if (p) return sprintf(page, "%s\n", p->name); else if (mddev->clevel[0]) @@ -3231,14 +3288,14 @@ level_show(mddev_t *mddev, char *page) } static ssize_t -level_store(mddev_t *mddev, const char *buf, size_t len) +level_store(struct mddev *mddev, const char *buf, size_t len) { char clevel[16]; ssize_t rv = len; - struct mdk_personality *pers; + struct md_personality *pers; long level; void *priv; - mdk_rdev_t *rdev; + struct md_rdev *rdev; if (mddev->pers == NULL) { if (len == 0) @@ -3412,7 +3469,7 @@ __ATTR(level, S_IRUGO|S_IWUSR, level_show, level_store); static ssize_t -layout_show(mddev_t *mddev, char *page) +layout_show(struct mddev *mddev, char *page) { /* just a number, not meaningful for all levels */ if (mddev->reshape_position != MaxSector && @@ -3423,7 +3480,7 @@ layout_show(mddev_t *mddev, char *page) } static ssize_t -layout_store(mddev_t *mddev, const char *buf, size_t len) +layout_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long n = simple_strtoul(buf, &e, 10); @@ -3453,7 +3510,7 @@ __ATTR(layout, S_IRUGO|S_IWUSR, layout_show, layout_store); static ssize_t -raid_disks_show(mddev_t *mddev, char *page) +raid_disks_show(struct mddev *mddev, char *page) { if (mddev->raid_disks == 0) return 0; @@ -3464,10 +3521,10 @@ raid_disks_show(mddev_t *mddev, char *page) return sprintf(page, "%d\n", mddev->raid_disks); } -static int update_raid_disks(mddev_t *mddev, int raid_disks); +static int update_raid_disks(struct mddev *mddev, int raid_disks); static ssize_t -raid_disks_store(mddev_t *mddev, const char *buf, size_t len) +raid_disks_store(struct mddev *mddev, const char *buf, size_t len) { char *e; int rv = 0; @@ -3490,7 +3547,7 @@ static struct md_sysfs_entry md_raid_disks = __ATTR(raid_disks, S_IRUGO|S_IWUSR, raid_disks_show, raid_disks_store); static ssize_t -chunk_size_show(mddev_t *mddev, char *page) +chunk_size_show(struct mddev *mddev, char *page) { if (mddev->reshape_position != MaxSector && mddev->chunk_sectors != mddev->new_chunk_sectors) @@ -3501,7 +3558,7 @@ chunk_size_show(mddev_t *mddev, char *page) } static ssize_t -chunk_size_store(mddev_t *mddev, const char *buf, size_t len) +chunk_size_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long n = simple_strtoul(buf, &e, 10); @@ -3530,7 +3587,7 @@ static struct md_sysfs_entry md_chunk_size = __ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store); static ssize_t -resync_start_show(mddev_t *mddev, char *page) +resync_start_show(struct mddev *mddev, char *page) { if (mddev->recovery_cp == MaxSector) return sprintf(page, "none\n"); @@ -3538,7 +3595,7 @@ resync_start_show(mddev_t *mddev, char *page) } static ssize_t -resync_start_store(mddev_t *mddev, const char *buf, size_t len) +resync_start_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long long n = simple_strtoull(buf, &e, 10); @@ -3608,7 +3665,7 @@ static int match_word(const char *word, char **list) } static ssize_t -array_state_show(mddev_t *mddev, char *page) +array_state_show(struct mddev *mddev, char *page) { enum array_state st = inactive; @@ -3641,13 +3698,13 @@ array_state_show(mddev_t *mddev, char *page) return sprintf(page, "%s\n", array_states[st]); } -static int do_md_stop(mddev_t * mddev, int ro, int is_open); -static int md_set_readonly(mddev_t * mddev, int is_open); -static int do_md_run(mddev_t * mddev); -static int restart_array(mddev_t *mddev); +static int do_md_stop(struct mddev * mddev, int ro, int is_open); +static int md_set_readonly(struct mddev * mddev, int is_open); +static int do_md_run(struct mddev * mddev); +static int restart_array(struct mddev *mddev); static ssize_t -array_state_store(mddev_t *mddev, const char *buf, size_t len) +array_state_store(struct mddev *mddev, const char *buf, size_t len) { int err = -EINVAL; enum array_state st = match_word(buf, array_states); @@ -3733,6 +3790,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) if (err) return err; else { + if (mddev->hold_active == UNTIL_IOCTL) + mddev->hold_active = 0; sysfs_notify_dirent_safe(mddev->sysfs_state); return len; } @@ -3741,13 +3800,13 @@ static struct md_sysfs_entry md_array_state = __ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store); static ssize_t -max_corrected_read_errors_show(mddev_t *mddev, char *page) { +max_corrected_read_errors_show(struct mddev *mddev, char *page) { return sprintf(page, "%d\n", atomic_read(&mddev->max_corr_read_errors)); } static ssize_t -max_corrected_read_errors_store(mddev_t *mddev, const char *buf, size_t len) +max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long n = simple_strtoul(buf, &e, 10); @@ -3764,13 +3823,13 @@ __ATTR(max_read_errors, S_IRUGO|S_IWUSR, max_corrected_read_errors_show, max_corrected_read_errors_store); static ssize_t -null_show(mddev_t *mddev, char *page) +null_show(struct mddev *mddev, char *page) { return -EINVAL; } static ssize_t -new_dev_store(mddev_t *mddev, const char *buf, size_t len) +new_dev_store(struct mddev *mddev, const char *buf, size_t len) { /* buf must be %d:%d\n? giving major and minor numbers */ /* The new device is added to the array. @@ -3783,7 +3842,7 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len) int major = simple_strtoul(buf, &e, 10); int minor; dev_t dev; - mdk_rdev_t *rdev; + struct md_rdev *rdev; int err; if (!*buf || *e != ':' || !e[1] || e[1] == '\n') @@ -3801,8 +3860,9 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len) rdev = md_import_device(dev, mddev->major_version, mddev->minor_version); if (!IS_ERR(rdev) && !list_empty(&mddev->disks)) { - mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, - mdk_rdev_t, same_set); + struct md_rdev *rdev0 + = list_entry(mddev->disks.next, + struct md_rdev, same_set); err = super_types[mddev->major_version] .load_super(rdev, rdev0, mddev->minor_version); if (err < 0) @@ -3826,7 +3886,7 @@ static struct md_sysfs_entry md_new_device = __ATTR(new_dev, S_IWUSR, null_show, new_dev_store); static ssize_t -bitmap_store(mddev_t *mddev, const char *buf, size_t len) +bitmap_store(struct mddev *mddev, const char *buf, size_t len) { char *end; unsigned long chunk, end_chunk; @@ -3855,16 +3915,16 @@ static struct md_sysfs_entry md_bitmap = __ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store); static ssize_t -size_show(mddev_t *mddev, char *page) +size_show(struct mddev *mddev, char *page) { return sprintf(page, "%llu\n", (unsigned long long)mddev->dev_sectors / 2); } -static int update_size(mddev_t *mddev, sector_t num_sectors); +static int update_size(struct mddev *mddev, sector_t num_sectors); static ssize_t -size_store(mddev_t *mddev, const char *buf, size_t len) +size_store(struct mddev *mddev, const char *buf, size_t len) { /* If array is inactive, we can reduce the component size, but * not increase it (except from 0). @@ -3899,7 +3959,7 @@ __ATTR(component_size, S_IRUGO|S_IWUSR, size_show, size_store); * or N.M for internally known formats */ static ssize_t -metadata_show(mddev_t *mddev, char *page) +metadata_show(struct mddev *mddev, char *page) { if (mddev->persistent) return sprintf(page, "%d.%d\n", @@ -3911,7 +3971,7 @@ metadata_show(mddev_t *mddev, char *page) } static ssize_t -metadata_store(mddev_t *mddev, const char *buf, size_t len) +metadata_store(struct mddev *mddev, const char *buf, size_t len) { int major, minor; char *e; @@ -3965,7 +4025,7 @@ static struct md_sysfs_entry md_metadata = __ATTR(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store); static ssize_t -action_show(mddev_t *mddev, char *page) +action_show(struct mddev *mddev, char *page) { char *type = "idle"; if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) @@ -3987,10 +4047,10 @@ action_show(mddev_t *mddev, char *page) return sprintf(page, "%s\n", type); } -static void reap_sync_thread(mddev_t *mddev); +static void reap_sync_thread(struct mddev *mddev); static ssize_t -action_store(mddev_t *mddev, const char *page, size_t len) +action_store(struct mddev *mddev, const char *page, size_t len) { if (!mddev->pers || !mddev->pers->sync_request) return -EINVAL; @@ -4036,7 +4096,7 @@ action_store(mddev_t *mddev, const char *page, size_t len) } static ssize_t -mismatch_cnt_show(mddev_t *mddev, char *page) +mismatch_cnt_show(struct mddev *mddev, char *page) { return sprintf(page, "%llu\n", (unsigned long long) mddev->resync_mismatches); @@ -4049,14 +4109,14 @@ __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store); static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt); static ssize_t -sync_min_show(mddev_t *mddev, char *page) +sync_min_show(struct mddev *mddev, char *page) { return sprintf(page, "%d (%s)\n", speed_min(mddev), mddev->sync_speed_min ? "local": "system"); } static ssize_t -sync_min_store(mddev_t *mddev, const char *buf, size_t len) +sync_min_store(struct mddev *mddev, const char *buf, size_t len) { int min; char *e; @@ -4075,14 +4135,14 @@ static struct md_sysfs_entry md_sync_min = __ATTR(sync_speed_min, S_IRUGO|S_IWUSR, sync_min_show, sync_min_store); static ssize_t -sync_max_show(mddev_t *mddev, char *page) +sync_max_show(struct mddev *mddev, char *page) { return sprintf(page, "%d (%s)\n", speed_max(mddev), mddev->sync_speed_max ? "local": "system"); } static ssize_t -sync_max_store(mddev_t *mddev, const char *buf, size_t len) +sync_max_store(struct mddev *mddev, const char *buf, size_t len) { int max; char *e; @@ -4101,20 +4161,20 @@ static struct md_sysfs_entry md_sync_max = __ATTR(sync_speed_max, S_IRUGO|S_IWUSR, sync_max_show, sync_max_store); static ssize_t -degraded_show(mddev_t *mddev, char *page) +degraded_show(struct mddev *mddev, char *page) { return sprintf(page, "%d\n", mddev->degraded); } static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); static ssize_t -sync_force_parallel_show(mddev_t *mddev, char *page) +sync_force_parallel_show(struct mddev *mddev, char *page) { return sprintf(page, "%d\n", mddev->parallel_resync); } static ssize_t -sync_force_parallel_store(mddev_t *mddev, const char *buf, size_t len) +sync_force_parallel_store(struct mddev *mddev, const char *buf, size_t len) { long n; @@ -4138,7 +4198,7 @@ __ATTR(sync_force_parallel, S_IRUGO|S_IWUSR, sync_force_parallel_show, sync_force_parallel_store); static ssize_t -sync_speed_show(mddev_t *mddev, char *page) +sync_speed_show(struct mddev *mddev, char *page) { unsigned long resync, dt, db; if (mddev->curr_resync == 0) @@ -4153,7 +4213,7 @@ sync_speed_show(mddev_t *mddev, char *page) static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed); static ssize_t -sync_completed_show(mddev_t *mddev, char *page) +sync_completed_show(struct mddev *mddev, char *page) { unsigned long long max_sectors, resync; @@ -4172,13 +4232,13 @@ sync_completed_show(mddev_t *mddev, char *page) static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); static ssize_t -min_sync_show(mddev_t *mddev, char *page) +min_sync_show(struct mddev *mddev, char *page) { return sprintf(page, "%llu\n", (unsigned long long)mddev->resync_min); } static ssize_t -min_sync_store(mddev_t *mddev, const char *buf, size_t len) +min_sync_store(struct mddev *mddev, const char *buf, size_t len) { unsigned long long min; if (strict_strtoull(buf, 10, &min)) @@ -4203,7 +4263,7 @@ static struct md_sysfs_entry md_min_sync = __ATTR(sync_min, S_IRUGO|S_IWUSR, min_sync_show, min_sync_store); static ssize_t -max_sync_show(mddev_t *mddev, char *page) +max_sync_show(struct mddev *mddev, char *page) { if (mddev->resync_max == MaxSector) return sprintf(page, "max\n"); @@ -4212,7 +4272,7 @@ max_sync_show(mddev_t *mddev, char *page) (unsigned long long)mddev->resync_max); } static ssize_t -max_sync_store(mddev_t *mddev, const char *buf, size_t len) +max_sync_store(struct mddev *mddev, const char *buf, size_t len) { if (strncmp(buf, "max", 3) == 0) mddev->resync_max = MaxSector; @@ -4243,13 +4303,13 @@ static struct md_sysfs_entry md_max_sync = __ATTR(sync_max, S_IRUGO|S_IWUSR, max_sync_show, max_sync_store); static ssize_t -suspend_lo_show(mddev_t *mddev, char *page) +suspend_lo_show(struct mddev *mddev, char *page) { return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo); } static ssize_t -suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) +suspend_lo_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long long new = simple_strtoull(buf, &e, 10); @@ -4277,13 +4337,13 @@ __ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store); static ssize_t -suspend_hi_show(mddev_t *mddev, char *page) +suspend_hi_show(struct mddev *mddev, char *page) { return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_hi); } static ssize_t -suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) +suspend_hi_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long long new = simple_strtoull(buf, &e, 10); @@ -4310,7 +4370,7 @@ static struct md_sysfs_entry md_suspend_hi = __ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); static ssize_t -reshape_position_show(mddev_t *mddev, char *page) +reshape_position_show(struct mddev *mddev, char *page) { if (mddev->reshape_position != MaxSector) return sprintf(page, "%llu\n", @@ -4320,7 +4380,7 @@ reshape_position_show(mddev_t *mddev, char *page) } static ssize_t -reshape_position_store(mddev_t *mddev, const char *buf, size_t len) +reshape_position_store(struct mddev *mddev, const char *buf, size_t len) { char *e; unsigned long long new = simple_strtoull(buf, &e, 10); @@ -4341,7 +4401,7 @@ __ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show, reshape_position_store); static ssize_t -array_size_show(mddev_t *mddev, char *page) +array_size_show(struct mddev *mddev, char *page) { if (mddev->external_size) return sprintf(page, "%llu\n", @@ -4351,7 +4411,7 @@ array_size_show(mddev_t *mddev, char *page) } static ssize_t -array_size_store(mddev_t *mddev, const char *buf, size_t len) +array_size_store(struct mddev *mddev, const char *buf, size_t len) { sector_t sectors; @@ -4426,16 +4486,25 @@ static ssize_t md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) { struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr); - mddev_t *mddev = container_of(kobj, struct mddev_s, kobj); + struct mddev *mddev = container_of(kobj, struct mddev, kobj); ssize_t rv; if (!entry->show) return -EIO; + spin_lock(&all_mddevs_lock); + if (list_empty(&mddev->all_mddevs)) { + spin_unlock(&all_mddevs_lock); + return -EBUSY; + } + mddev_get(mddev); + spin_unlock(&all_mddevs_lock); + rv = mddev_lock(mddev); if (!rv) { rv = entry->show(mddev, page); mddev_unlock(mddev); } + mddev_put(mddev); return rv; } @@ -4444,26 +4513,32 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, const char *page, size_t length) { struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr); - mddev_t *mddev = container_of(kobj, struct mddev_s, kobj); + struct mddev *mddev = container_of(kobj, struct mddev, kobj); ssize_t rv; if (!entry->store) return -EIO; if (!capable(CAP_SYS_ADMIN)) return -EACCES; + spin_lock(&all_mddevs_lock); + if (list_empty(&mddev->all_mddevs)) { + spin_unlock(&all_mddevs_lock); + return -EBUSY; + } + mddev_get(mddev); + spin_unlock(&all_mddevs_lock); rv = mddev_lock(mddev); - if (mddev->hold_active == UNTIL_IOCTL) - mddev->hold_active = 0; if (!rv) { rv = entry->store(mddev, page, length); mddev_unlock(mddev); } + mddev_put(mddev); return rv; } static void md_free(struct kobject *ko) { - mddev_t *mddev = container_of(ko, mddev_t, kobj); + struct mddev *mddev = container_of(ko, struct mddev, kobj); if (mddev->sysfs_state) sysfs_put(mddev->sysfs_state); @@ -4492,7 +4567,7 @@ int mdp_major = 0; static void mddev_delayed_delete(struct work_struct *ws) { - mddev_t *mddev = container_of(ws, mddev_t, del_work); + struct mddev *mddev = container_of(ws, struct mddev, del_work); sysfs_remove_group(&mddev->kobj, &md_bitmap_group); kobject_del(&mddev->kobj); @@ -4502,7 +4577,7 @@ static void mddev_delayed_delete(struct work_struct *ws) static int md_alloc(dev_t dev, char *name) { static DEFINE_MUTEX(disks_mutex); - mddev_t *mddev = mddev_find(dev); + struct mddev *mddev = mddev_find(dev); struct gendisk *disk; int partitioned; int shift; @@ -4529,7 +4604,7 @@ static int md_alloc(dev_t dev, char *name) if (name) { /* Need to ensure that 'name' is not a duplicate. */ - mddev_t *mddev2; + struct mddev *mddev2; spin_lock(&all_mddevs_lock); list_for_each_entry(mddev2, &all_mddevs, all_mddevs) @@ -4630,7 +4705,7 @@ static int add_named_array(const char *val, struct kernel_param *kp) static void md_safemode_timeout(unsigned long data) { - mddev_t *mddev = (mddev_t *) data; + struct mddev *mddev = (struct mddev *) data; if (!atomic_read(&mddev->writes_pending)) { mddev->safemode = 1; @@ -4642,11 +4717,11 @@ static void md_safemode_timeout(unsigned long data) static int start_dirty_degraded; -int md_run(mddev_t *mddev) +int md_run(struct mddev *mddev) { int err; - mdk_rdev_t *rdev; - struct mdk_personality *pers; + struct md_rdev *rdev; + struct md_personality *pers; if (list_empty(&mddev->disks)) /* cannot run an array with no devices.. */ @@ -4710,7 +4785,7 @@ int md_run(mddev_t *mddev) if (mddev->bio_set == NULL) mddev->bio_set = bioset_create(BIO_POOL_SIZE, - sizeof(mddev_t *)); + sizeof(struct mddev *)); spin_lock(&pers_lock); pers = find_pers(mddev->level, mddev->clevel); @@ -4745,7 +4820,7 @@ int md_run(mddev_t *mddev) * configuration. */ char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; - mdk_rdev_t *rdev2; + struct md_rdev *rdev2; int warned = 0; list_for_each_entry(rdev, &mddev->disks, same_set) @@ -4844,7 +4919,7 @@ int md_run(mddev_t *mddev) } EXPORT_SYMBOL_GPL(md_run); -static int do_md_run(mddev_t *mddev) +static int do_md_run(struct mddev *mddev) { int err; @@ -4868,7 +4943,7 @@ out: return err; } -static int restart_array(mddev_t *mddev) +static int restart_array(struct mddev *mddev) { struct gendisk *disk = mddev->gendisk; @@ -4918,7 +4993,7 @@ void restore_bitmap_write_access(struct file *file) spin_unlock(&inode->i_lock); } -static void md_clean(mddev_t *mddev) +static void md_clean(struct mddev *mddev) { mddev->array_sectors = 0; mddev->external_size = 0; @@ -4961,7 +5036,7 @@ static void md_clean(mddev_t *mddev) mddev->bitmap_info.max_write_behind = 0; } -static void __md_stop_writes(mddev_t *mddev) +static void __md_stop_writes(struct mddev *mddev) { if (mddev->sync_thread) { set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); @@ -4981,7 +5056,7 @@ static void __md_stop_writes(mddev_t *mddev) } } -void md_stop_writes(mddev_t *mddev) +void md_stop_writes(struct mddev *mddev) { mddev_lock(mddev); __md_stop_writes(mddev); @@ -4989,7 +5064,7 @@ void md_stop_writes(mddev_t *mddev) } EXPORT_SYMBOL_GPL(md_stop_writes); -void md_stop(mddev_t *mddev) +void md_stop(struct mddev *mddev) { mddev->ready = 0; mddev->pers->stop(mddev); @@ -5001,7 +5076,7 @@ void md_stop(mddev_t *mddev) } EXPORT_SYMBOL_GPL(md_stop); -static int md_set_readonly(mddev_t *mddev, int is_open) +static int md_set_readonly(struct mddev *mddev, int is_open) { int err = 0; mutex_lock(&mddev->open_mutex); @@ -5031,10 +5106,10 @@ out: * 0 - completely stop and dis-assemble array * 2 - stop but do not disassemble array */ -static int do_md_stop(mddev_t * mddev, int mode, int is_open) +static int do_md_stop(struct mddev * mddev, int mode, int is_open) { struct gendisk *disk = mddev->gendisk; - mdk_rdev_t *rdev; + struct md_rdev *rdev; mutex_lock(&mddev->open_mutex); if (atomic_read(&mddev->openers) > is_open || @@ -5097,9 +5172,9 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) } #ifndef MODULE -static void autorun_array(mddev_t *mddev) +static void autorun_array(struct mddev *mddev) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; int err; if (list_empty(&mddev->disks)) @@ -5134,8 +5209,8 @@ static void autorun_array(mddev_t *mddev) */ static void autorun_devices(int part) { - mdk_rdev_t *rdev0, *rdev, *tmp; - mddev_t *mddev; + struct md_rdev *rdev0, *rdev, *tmp; + struct mddev *mddev; char b[BDEVNAME_SIZE]; printk(KERN_INFO "md: autorun ...\n"); @@ -5144,7 +5219,7 @@ static void autorun_devices(int part) dev_t dev; LIST_HEAD(candidates); rdev0 = list_entry(pending_raid_disks.next, - mdk_rdev_t, same_set); + struct md_rdev, same_set); printk(KERN_INFO "md: considering %s ...\n", bdevname(rdev0->bdev,b)); @@ -5230,11 +5305,11 @@ static int get_version(void __user * arg) return 0; } -static int get_array_info(mddev_t * mddev, void __user * arg) +static int get_array_info(struct mddev * mddev, void __user * arg) { mdu_array_info_t info; int nr,working,insync,failed,spare; - mdk_rdev_t *rdev; + struct md_rdev *rdev; nr=working=insync=failed=spare=0; list_for_each_entry(rdev, &mddev->disks, same_set) { @@ -5283,7 +5358,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) return 0; } -static int get_bitmap_file(mddev_t * mddev, void __user * arg) +static int get_bitmap_file(struct mddev * mddev, void __user * arg) { mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */ char *ptr, *buf = NULL; @@ -5323,10 +5398,10 @@ out: return err; } -static int get_disk_info(mddev_t * mddev, void __user * arg) +static int get_disk_info(struct mddev * mddev, void __user * arg) { mdu_disk_info_t info; - mdk_rdev_t *rdev; + struct md_rdev *rdev; if (copy_from_user(&info, arg, sizeof(info))) return -EFAULT; @@ -5357,10 +5432,10 @@ static int get_disk_info(mddev_t * mddev, void __user * arg) return 0; } -static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) +static int add_new_disk(struct mddev * mddev, mdu_disk_info_t *info) { char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; - mdk_rdev_t *rdev; + struct md_rdev *rdev; dev_t dev = MKDEV(info->major,info->minor); if (info->major != MAJOR(dev) || info->minor != MINOR(dev)) @@ -5377,8 +5452,9 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) return PTR_ERR(rdev); } if (!list_empty(&mddev->disks)) { - mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, - mdk_rdev_t, same_set); + struct md_rdev *rdev0 + = list_entry(mddev->disks.next, + struct md_rdev, same_set); err = super_types[mddev->major_version] .load_super(rdev, rdev0, mddev->minor_version); if (err < 0) { @@ -5528,10 +5604,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) return 0; } -static int hot_remove_disk(mddev_t * mddev, dev_t dev) +static int hot_remove_disk(struct mddev * mddev, dev_t dev) { char b[BDEVNAME_SIZE]; - mdk_rdev_t *rdev; + struct md_rdev *rdev; rdev = find_rdev(mddev, dev); if (!rdev) @@ -5551,11 +5627,11 @@ busy: return -EBUSY; } -static int hot_add_disk(mddev_t * mddev, dev_t dev) +static int hot_add_disk(struct mddev * mddev, dev_t dev) { char b[BDEVNAME_SIZE]; int err; - mdk_rdev_t *rdev; + struct md_rdev *rdev; if (!mddev->pers) return -ENODEV; @@ -5625,7 +5701,7 @@ abort_export: return err; } -static int set_bitmap_file(mddev_t *mddev, int fd) +static int set_bitmap_file(struct mddev *mddev, int fd) { int err; @@ -5698,7 +5774,7 @@ static int set_bitmap_file(mddev_t *mddev, int fd) * The minor and patch _version numbers are also kept incase the * super_block handler wishes to interpret them. */ -static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) +static int set_array_info(struct mddev * mddev, mdu_array_info_t *info) { if (info->raid_disks == 0) { @@ -5768,7 +5844,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) return 0; } -void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors) +void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors) { WARN(!mddev_is_locked(mddev), "%s: unlocked mddev!\n", __func__); @@ -5779,9 +5855,9 @@ void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors) } EXPORT_SYMBOL(md_set_array_sectors); -static int update_size(mddev_t *mddev, sector_t num_sectors) +static int update_size(struct mddev *mddev, sector_t num_sectors) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; int rv; int fit = (num_sectors == 0); @@ -5817,7 +5893,7 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) return rv; } -static int update_raid_disks(mddev_t *mddev, int raid_disks) +static int update_raid_disks(struct mddev *mddev, int raid_disks) { int rv; /* change the number of raid disks */ @@ -5845,7 +5921,7 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) * Any differences that cannot be handled will cause an error. * Normally, only one change can be managed at a time. */ -static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) +static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) { int rv = 0; int cnt = 0; @@ -5938,9 +6014,9 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) return rv; } -static int set_disk_faulty(mddev_t *mddev, dev_t dev) +static int set_disk_faulty(struct mddev *mddev, dev_t dev) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; if (mddev->pers == NULL) return -ENODEV; @@ -5950,6 +6026,8 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) return -ENODEV; md_error(mddev, rdev); + if (!test_bit(Faulty, &rdev->flags)) + return -EBUSY; return 0; } @@ -5961,7 +6039,7 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) */ static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo) { - mddev_t *mddev = bdev->bd_disk->private_data; + struct mddev *mddev = bdev->bd_disk->private_data; geo->heads = 2; geo->sectors = 4; @@ -5974,7 +6052,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, { int err = 0; void __user *argp = (void __user *)arg; - mddev_t *mddev = NULL; + struct mddev *mddev = NULL; int ro; if (!capable(CAP_SYS_ADMIN)) @@ -6237,7 +6315,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) * Succeed if we can lock the mddev, which confirms that * it isn't being stopped right now. */ - mddev_t *mddev = mddev_find(bdev->bd_dev); + struct mddev *mddev = mddev_find(bdev->bd_dev); int err; if (mddev->gendisk != bdev->bd_disk) { @@ -6266,7 +6344,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) static int md_release(struct gendisk *disk, fmode_t mode) { - mddev_t *mddev = disk->private_data; + struct mddev *mddev = disk->private_data; BUG_ON(!mddev); atomic_dec(&mddev->openers); @@ -6277,14 +6355,14 @@ static int md_release(struct gendisk *disk, fmode_t mode) static int md_media_changed(struct gendisk *disk) { - mddev_t *mddev = disk->private_data; + struct mddev *mddev = disk->private_data; return mddev->changed; } static int md_revalidate(struct gendisk *disk) { - mddev_t *mddev = disk->private_data; + struct mddev *mddev = disk->private_data; mddev->changed = 0; return 0; @@ -6305,7 +6383,7 @@ static const struct block_device_operations md_fops = static int md_thread(void * arg) { - mdk_thread_t *thread = arg; + struct md_thread *thread = arg; /* * md_thread is a 'system-thread', it's priority should be very @@ -6344,21 +6422,21 @@ static int md_thread(void * arg) return 0; } -void md_wakeup_thread(mdk_thread_t *thread) +void md_wakeup_thread(struct md_thread *thread) { if (thread) { - dprintk("md: waking up MD thread %s.\n", thread->tsk->comm); + pr_debug("md: waking up MD thread %s.\n", thread->tsk->comm); set_bit(THREAD_WAKEUP, &thread->flags); wake_up(&thread->wqueue); } } -mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, +struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev *mddev, const char *name) { - mdk_thread_t *thread; + struct md_thread *thread; - thread = kzalloc(sizeof(mdk_thread_t), GFP_KERNEL); + thread = kzalloc(sizeof(struct md_thread), GFP_KERNEL); if (!thread) return NULL; @@ -6378,17 +6456,24 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, return thread; } -void md_unregister_thread(mdk_thread_t *thread) +void md_unregister_thread(struct md_thread **threadp) { + struct md_thread *thread = *threadp; if (!thread) return; - dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); + pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); + /* Locking ensures that mddev_unlock does not wake_up a + * non-existent thread + */ + spin_lock(&pers_lock); + *threadp = NULL; + spin_unlock(&pers_lock); kthread_stop(thread->tsk); kfree(thread); } -void md_error(mddev_t *mddev, mdk_rdev_t *rdev) +void md_error(struct mddev *mddev, struct md_rdev *rdev) { if (!mddev) { MD_BUG(); @@ -6398,18 +6483,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) if (!rdev || test_bit(Faulty, &rdev->flags)) return; - if (mddev->external) - set_bit(Blocked, &rdev->flags); -/* - dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", - mdname(mddev), - MAJOR(rdev->bdev->bd_dev), MINOR(rdev->bdev->bd_dev), - __builtin_return_address(0),__builtin_return_address(1), - __builtin_return_address(2),__builtin_return_address(3)); -*/ - if (!mddev->pers) - return; - if (!mddev->pers->error_handler) + if (!mddev->pers || !mddev->pers->error_handler) return; mddev->pers->error_handler(mddev,rdev); if (mddev->degraded) @@ -6428,7 +6502,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) static void status_unused(struct seq_file *seq) { int i = 0; - mdk_rdev_t *rdev; + struct md_rdev *rdev; seq_printf(seq, "unused devices: "); @@ -6445,7 +6519,7 @@ static void status_unused(struct seq_file *seq) } -static void status_resync(struct seq_file *seq, mddev_t * mddev) +static void status_resync(struct seq_file *seq, struct mddev * mddev) { sector_t max_sectors, resync, res; unsigned long dt, db; @@ -6536,7 +6610,7 @@ static void *md_seq_start(struct seq_file *seq, loff_t *pos) { struct list_head *tmp; loff_t l = *pos; - mddev_t *mddev; + struct mddev *mddev; if (l >= 0x10000) return NULL; @@ -6547,7 +6621,7 @@ static void *md_seq_start(struct seq_file *seq, loff_t *pos) spin_lock(&all_mddevs_lock); list_for_each(tmp,&all_mddevs) if (!l--) { - mddev = list_entry(tmp, mddev_t, all_mddevs); + mddev = list_entry(tmp, struct mddev, all_mddevs); mddev_get(mddev); spin_unlock(&all_mddevs_lock); return mddev; @@ -6561,7 +6635,7 @@ static void *md_seq_start(struct seq_file *seq, loff_t *pos) static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct list_head *tmp; - mddev_t *next_mddev, *mddev = v; + struct mddev *next_mddev, *mddev = v; ++*pos; if (v == (void*)2) @@ -6573,7 +6647,7 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) else tmp = mddev->all_mddevs.next; if (tmp != &all_mddevs) - next_mddev = mddev_get(list_entry(tmp,mddev_t,all_mddevs)); + next_mddev = mddev_get(list_entry(tmp,struct mddev,all_mddevs)); else { next_mddev = (void*)2; *pos = 0x10000; @@ -6588,26 +6662,21 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void md_seq_stop(struct seq_file *seq, void *v) { - mddev_t *mddev = v; + struct mddev *mddev = v; if (mddev && v != (void*)1 && v != (void*)2) mddev_put(mddev); } -struct mdstat_info { - int event; -}; - static int md_seq_show(struct seq_file *seq, void *v) { - mddev_t *mddev = v; + struct mddev *mddev = v; sector_t sectors; - mdk_rdev_t *rdev; - struct mdstat_info *mi = seq->private; + struct md_rdev *rdev; struct bitmap *bitmap; if (v == (void*)1) { - struct mdk_personality *pers; + struct md_personality *pers; seq_printf(seq, "Personalities : "); spin_lock(&pers_lock); list_for_each_entry(pers, &pers_list, list) @@ -6615,7 +6684,7 @@ static int md_seq_show(struct seq_file *seq, void *v) spin_unlock(&pers_lock); seq_printf(seq, "\n"); - mi->event = atomic_read(&md_event_count); + seq->poll_event = atomic_read(&md_event_count); return 0; } if (v == (void*)2) { @@ -6727,26 +6796,21 @@ static const struct seq_operations md_seq_ops = { static int md_seq_open(struct inode *inode, struct file *file) { + struct seq_file *seq; int error; - struct mdstat_info *mi = kmalloc(sizeof(*mi), GFP_KERNEL); - if (mi == NULL) - return -ENOMEM; error = seq_open(file, &md_seq_ops); if (error) - kfree(mi); - else { - struct seq_file *p = file->private_data; - p->private = mi; - mi->event = atomic_read(&md_event_count); - } + return error; + + seq = file->private_data; + seq->poll_event = atomic_read(&md_event_count); return error; } static unsigned int mdstat_poll(struct file *filp, poll_table *wait) { - struct seq_file *m = filp->private_data; - struct mdstat_info *mi = m->private; + struct seq_file *seq = filp->private_data; int mask; poll_wait(filp, &md_event_waiters, wait); @@ -6754,7 +6818,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait) /* always allow read */ mask = POLLIN | POLLRDNORM; - if (mi->event != atomic_read(&md_event_count)) + if (seq->poll_event != atomic_read(&md_event_count)) mask |= POLLERR | POLLPRI; return mask; } @@ -6768,7 +6832,7 @@ static const struct file_operations md_seq_fops = { .poll = mdstat_poll, }; -int register_md_personality(struct mdk_personality *p) +int register_md_personality(struct md_personality *p) { spin_lock(&pers_lock); list_add_tail(&p->list, &pers_list); @@ -6777,7 +6841,7 @@ int register_md_personality(struct mdk_personality *p) return 0; } -int unregister_md_personality(struct mdk_personality *p) +int unregister_md_personality(struct md_personality *p) { printk(KERN_INFO "md: %s personality unregistered\n", p->name); spin_lock(&pers_lock); @@ -6786,9 +6850,9 @@ int unregister_md_personality(struct mdk_personality *p) return 0; } -static int is_mddev_idle(mddev_t *mddev, int init) +static int is_mddev_idle(struct mddev *mddev, int init) { - mdk_rdev_t * rdev; + struct md_rdev * rdev; int idle; int curr_events; @@ -6830,7 +6894,7 @@ static int is_mddev_idle(mddev_t *mddev, int init) return idle; } -void md_done_sync(mddev_t *mddev, int blocks, int ok) +void md_done_sync(struct mddev *mddev, int blocks, int ok) { /* another "blocks" (512byte) blocks have been synced */ atomic_sub(blocks, &mddev->recovery_active); @@ -6848,7 +6912,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) * in superblock) before writing, schedule a superblock update * and wait for it to complete. */ -void md_write_start(mddev_t *mddev, struct bio *bi) +void md_write_start(struct mddev *mddev, struct bio *bi) { int did_change = 0; if (bio_data_dir(bi) != WRITE) @@ -6883,7 +6947,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) !test_bit(MD_CHANGE_PENDING, &mddev->flags)); } -void md_write_end(mddev_t *mddev) +void md_write_end(struct mddev *mddev) { if (atomic_dec_and_test(&mddev->writes_pending)) { if (mddev->safemode == 2) @@ -6902,7 +6966,7 @@ void md_write_end(mddev_t *mddev) * In the ->external case MD_CHANGE_CLEAN can not be cleared until mddev->lock * is dropped, so return -EAGAIN after notifying userspace. */ -int md_allow_write(mddev_t *mddev) +int md_allow_write(struct mddev *mddev) { if (!mddev->pers) return 0; @@ -6934,9 +6998,9 @@ EXPORT_SYMBOL_GPL(md_allow_write); #define SYNC_MARKS 10 #define SYNC_MARK_STEP (3*HZ) -void md_do_sync(mddev_t *mddev) +void md_do_sync(struct mddev *mddev) { - mddev_t *mddev2; + struct mddev *mddev2; unsigned int currspeed = 0, window; sector_t max_sectors,j, io_sectors; @@ -6946,7 +7010,7 @@ void md_do_sync(mddev_t *mddev) struct list_head *tmp; sector_t last_check; int skipped = 0; - mdk_rdev_t *rdev; + struct md_rdev *rdev; char *desc; /* just incase thread restarts... */ @@ -7143,11 +7207,14 @@ void md_do_sync(mddev_t *mddev) atomic_add(sectors, &mddev->recovery_active); } + if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) + break; + j += sectors; if (j>1) mddev->curr_resync = j; mddev->curr_mark_cnt = io_sectors; if (last_check == 0) - /* this is the earliers that rebuilt will be + /* this is the earliest that rebuild will be * visible in /proc/mdstat */ md_new_event(mddev); @@ -7156,10 +7223,6 @@ void md_do_sync(mddev_t *mddev) continue; last_check = io_sectors; - - if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) - break; - repeat: if (time_after_eq(jiffies, mark[last_mark] + SYNC_MARK_STEP )) { /* step marks */ @@ -7262,9 +7325,9 @@ void md_do_sync(mddev_t *mddev) } EXPORT_SYMBOL_GPL(md_do_sync); -static int remove_and_add_spares(mddev_t *mddev) +static int remove_and_add_spares(struct mddev *mddev) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; int spares = 0; mddev->curr_resync_completed = 0; @@ -7286,8 +7349,7 @@ static int remove_and_add_spares(mddev_t *mddev) list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->raid_disk >= 0 && !test_bit(In_sync, &rdev->flags) && - !test_bit(Faulty, &rdev->flags) && - !test_bit(Blocked, &rdev->flags)) + !test_bit(Faulty, &rdev->flags)) spares++; if (rdev->raid_disk < 0 && !test_bit(Faulty, &rdev->flags)) { @@ -7299,21 +7361,19 @@ static int remove_and_add_spares(mddev_t *mddev) spares++; md_new_event(mddev); set_bit(MD_CHANGE_DEVS, &mddev->flags); - } else - break; + } } } } return spares; } -static void reap_sync_thread(mddev_t *mddev) +static void reap_sync_thread(struct mddev *mddev) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; /* resync has finished, collect result */ - md_unregister_thread(mddev->sync_thread); - mddev->sync_thread = NULL; + md_unregister_thread(&mddev->sync_thread); if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { /* success...*/ @@ -7325,15 +7385,19 @@ static void reap_sync_thread(mddev_t *mddev) if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && mddev->pers->finish_reshape) mddev->pers->finish_reshape(mddev); - md_update_sb(mddev, 1); - /* if array is no-longer degraded, then any saved_raid_disk - * information must be scrapped + /* If array is no-longer degraded, then any saved_raid_disk + * information must be scrapped. Also if any device is now + * In_sync we must scrape the saved_raid_disk for that device + * do the superblock for an incrementally recovered device + * written out. */ - if (!mddev->degraded) - list_for_each_entry(rdev, &mddev->disks, same_set) + list_for_each_entry(rdev, &mddev->disks, same_set) + if (!mddev->degraded || + test_bit(In_sync, &rdev->flags)) rdev->saved_raid_disk = -1; + md_update_sb(mddev, 1); clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); @@ -7369,7 +7433,7 @@ static void reap_sync_thread(mddev_t *mddev) * 5/ If array is degraded, try to add spares devices * 6/ If array has spares or is not in-sync, start a resync thread. */ -void md_check_recovery(mddev_t *mddev) +void md_check_recovery(struct mddev *mddev) { if (mddev->suspended) return; @@ -7405,7 +7469,7 @@ void md_check_recovery(mddev_t *mddev) /* Only thing we do on a ro array is remove * failed devices. */ - mdk_rdev_t *rdev; + struct md_rdev *rdev; list_for_each_entry(rdev, &mddev->disks, same_set) if (rdev->raid_disk >= 0 && !test_bit(Blocked, &rdev->flags) && @@ -7529,11 +7593,12 @@ void md_check_recovery(mddev_t *mddev) } } -void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev) +void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev) { sysfs_notify_dirent_safe(rdev->sysfs_state); wait_event_timeout(rdev->blocked_wait, - !test_bit(Blocked, &rdev->flags), + !test_bit(Blocked, &rdev->flags) && + !test_bit(BlockedBadBlocks, &rdev->flags), msecs_to_jiffies(5000)); rdev_dec_pending(rdev, mddev); } @@ -7779,18 +7844,21 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, } bb->changed = 1; + if (!acknowledged) + bb->unacked_exist = 1; write_sequnlock_irq(&bb->lock); return rv; } -int rdev_set_badblocks(mdk_rdev_t *rdev, sector_t s, int sectors, +int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, int acknowledged) { int rv = md_set_badblocks(&rdev->badblocks, s + rdev->data_offset, sectors, acknowledged); if (rv) { /* Make sure they get written out promptly */ + sysfs_notify_dirent_safe(rdev->sysfs_state); set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); md_wakeup_thread(rdev->mddev->thread); } @@ -7893,7 +7961,7 @@ out: return rv; } -int rdev_clear_badblocks(mdk_rdev_t *rdev, sector_t s, int sectors) +int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors) { return md_clear_badblocks(&rdev->badblocks, s + rdev->data_offset, @@ -7923,6 +7991,7 @@ void md_ack_all_badblocks(struct badblocks *bb) p[i] = BB_MAKE(start, len, 1); } } + bb->unacked_exist = 0; } write_sequnlock_irq(&bb->lock); } @@ -7970,6 +8039,8 @@ retry: (unsigned long long)s << bb->shift, length << bb->shift); } + if (unack && len == 0) + bb->unacked_exist = 0; if (read_seqretry(&bb->lock, seq)) goto retry; @@ -8024,29 +8095,27 @@ static int md_notify_reboot(struct notifier_block *this, unsigned long code, void *x) { struct list_head *tmp; - mddev_t *mddev; + struct mddev *mddev; + int need_delay = 0; - if ((code == SYS_DOWN) || (code == SYS_HALT) || (code == SYS_POWER_OFF)) { - - printk(KERN_INFO "md: stopping all md devices.\n"); - - for_each_mddev(mddev, tmp) - if (mddev_trylock(mddev)) { - /* Force a switch to readonly even array - * appears to still be in use. Hence - * the '100'. - */ - md_set_readonly(mddev, 100); - mddev_unlock(mddev); - } - /* - * certain more exotic SCSI devices are known to be - * volatile wrt too early system reboots. While the - * right place to handle this issue is the given - * driver, we do want to have a safe RAID driver ... - */ - mdelay(1000*1); + for_each_mddev(mddev, tmp) { + if (mddev_trylock(mddev)) { + if (mddev->pers) + __md_stop_writes(mddev); + mddev->safemode = 2; + mddev_unlock(mddev); + } + need_delay = 1; } + /* + * certain more exotic SCSI devices are known to be + * volatile wrt too early system reboots. While the + * right place to handle this issue is the given + * driver, we do want to have a safe RAID driver ... + */ + if (need_delay) + mdelay(1000*1); + return NOTIFY_DONE; } @@ -8058,7 +8127,7 @@ static struct notifier_block md_notifier = { static void md_geninit(void) { - dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); + pr_debug("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); proc_create("mdstat", S_IRUGO, NULL, &md_seq_fops); } @@ -8133,7 +8202,7 @@ void md_autodetect_dev(dev_t dev) static void autostart_arrays(int part) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; struct detected_devices_node *node_detected_dev; dev_t dev; int i_scanned, i_passed; @@ -8173,7 +8242,7 @@ static void autostart_arrays(int part) static __exit void md_exit(void) { - mddev_t *mddev; + struct mddev *mddev; struct list_head *tmp; blk_unregister_region(MKDEV(MD_MAJOR,0), 1U << MINORBITS);