diff options
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/dm-log.c | 3 | ||||
| -rw-r--r-- | drivers/md/md.c | 32 | ||||
| -rw-r--r-- | drivers/md/raid6main.c | 149 |
3 files changed, 129 insertions, 55 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 74039db846ba..d73779a42417 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
| @@ -545,7 +545,8 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region) | |||
| 545 | return 0; | 545 | return 0; |
| 546 | 546 | ||
| 547 | do { | 547 | do { |
| 548 | *region = find_next_zero_bit((unsigned long *) lc->sync_bits, | 548 | *region = ext2_find_next_zero_bit( |
| 549 | (unsigned long *) lc->sync_bits, | ||
| 549 | lc->region_count, | 550 | lc->region_count, |
| 550 | lc->sync_search); | 551 | lc->sync_search); |
| 551 | lc->sync_search = *region + 1; | 552 | lc->sync_search = *region + 1; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7145cd150f7b..653d4dcbee23 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1161,6 +1161,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1161 | 1161 | ||
| 1162 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); | 1162 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); |
| 1163 | 1163 | ||
| 1164 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); | ||
| 1165 | sb->size = cpu_to_le64(mddev->size); | ||
| 1166 | |||
| 1164 | if (mddev->bitmap && mddev->bitmap_file == NULL) { | 1167 | if (mddev->bitmap && mddev->bitmap_file == NULL) { |
| 1165 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); | 1168 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); |
| 1166 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | 1169 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); |
| @@ -2686,14 +2689,6 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
| 2686 | set_disk_ro(disk, 1); | 2689 | set_disk_ro(disk, 1); |
| 2687 | } | 2690 | } |
| 2688 | 2691 | ||
| 2689 | bitmap_destroy(mddev); | ||
| 2690 | if (mddev->bitmap_file) { | ||
| 2691 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | ||
| 2692 | fput(mddev->bitmap_file); | ||
| 2693 | mddev->bitmap_file = NULL; | ||
| 2694 | } | ||
| 2695 | mddev->bitmap_offset = 0; | ||
| 2696 | |||
| 2697 | /* | 2692 | /* |
| 2698 | * Free resources if final stop | 2693 | * Free resources if final stop |
| 2699 | */ | 2694 | */ |
| @@ -2703,6 +2698,14 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
| 2703 | struct gendisk *disk; | 2698 | struct gendisk *disk; |
| 2704 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); | 2699 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); |
| 2705 | 2700 | ||
| 2701 | bitmap_destroy(mddev); | ||
| 2702 | if (mddev->bitmap_file) { | ||
| 2703 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | ||
| 2704 | fput(mddev->bitmap_file); | ||
| 2705 | mddev->bitmap_file = NULL; | ||
| 2706 | } | ||
| 2707 | mddev->bitmap_offset = 0; | ||
| 2708 | |||
| 2706 | ITERATE_RDEV(mddev,rdev,tmp) | 2709 | ITERATE_RDEV(mddev,rdev,tmp) |
| 2707 | if (rdev->raid_disk >= 0) { | 2710 | if (rdev->raid_disk >= 0) { |
| 2708 | char nm[20]; | 2711 | char nm[20]; |
| @@ -3465,7 +3468,7 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
| 3465 | bdev = bdget_disk(mddev->gendisk, 0); | 3468 | bdev = bdget_disk(mddev->gendisk, 0); |
| 3466 | if (bdev) { | 3469 | if (bdev) { |
| 3467 | mutex_lock(&bdev->bd_inode->i_mutex); | 3470 | mutex_lock(&bdev->bd_inode->i_mutex); |
| 3468 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | 3471 | i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10); |
| 3469 | mutex_unlock(&bdev->bd_inode->i_mutex); | 3472 | mutex_unlock(&bdev->bd_inode->i_mutex); |
| 3470 | bdput(bdev); | 3473 | bdput(bdev); |
| 3471 | } | 3474 | } |
| @@ -3485,17 +3488,6 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) | |||
| 3485 | if (mddev->sync_thread) | 3488 | if (mddev->sync_thread) |
| 3486 | return -EBUSY; | 3489 | return -EBUSY; |
| 3487 | rv = mddev->pers->reshape(mddev, raid_disks); | 3490 | rv = mddev->pers->reshape(mddev, raid_disks); |
| 3488 | if (!rv) { | ||
| 3489 | struct block_device *bdev; | ||
| 3490 | |||
| 3491 | bdev = bdget_disk(mddev->gendisk, 0); | ||
| 3492 | if (bdev) { | ||
| 3493 | mutex_lock(&bdev->bd_inode->i_mutex); | ||
| 3494 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | ||
| 3495 | mutex_unlock(&bdev->bd_inode->i_mutex); | ||
| 3496 | bdput(bdev); | ||
| 3497 | } | ||
| 3498 | } | ||
| 3499 | return rv; | 3491 | return rv; |
| 3500 | } | 3492 | } |
| 3501 | 3493 | ||
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index f618a53b98be..ed2abb2e2e2d 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
| @@ -115,7 +115,7 @@ static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh) | |||
| 115 | list_add_tail(&sh->lru, &conf->inactive_list); | 115 | list_add_tail(&sh->lru, &conf->inactive_list); |
| 116 | atomic_dec(&conf->active_stripes); | 116 | atomic_dec(&conf->active_stripes); |
| 117 | if (!conf->inactive_blocked || | 117 | if (!conf->inactive_blocked || |
| 118 | atomic_read(&conf->active_stripes) < (NR_STRIPES*3/4)) | 118 | atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4)) |
| 119 | wake_up(&conf->wait_for_stripe); | 119 | wake_up(&conf->wait_for_stripe); |
| 120 | } | 120 | } |
| 121 | } | 121 | } |
| @@ -273,7 +273,8 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector | |||
| 273 | conf->inactive_blocked = 1; | 273 | conf->inactive_blocked = 1; |
| 274 | wait_event_lock_irq(conf->wait_for_stripe, | 274 | wait_event_lock_irq(conf->wait_for_stripe, |
| 275 | !list_empty(&conf->inactive_list) && | 275 | !list_empty(&conf->inactive_list) && |
| 276 | (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4) | 276 | (atomic_read(&conf->active_stripes) |
| 277 | < (conf->max_nr_stripes *3/4) | ||
| 277 | || !conf->inactive_blocked), | 278 | || !conf->inactive_blocked), |
| 278 | conf->device_lock, | 279 | conf->device_lock, |
| 279 | unplug_slaves(conf->mddev); | 280 | unplug_slaves(conf->mddev); |
| @@ -302,9 +303,31 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector | |||
| 302 | return sh; | 303 | return sh; |
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | static int grow_stripes(raid6_conf_t *conf, int num) | 306 | static int grow_one_stripe(raid6_conf_t *conf) |
| 306 | { | 307 | { |
| 307 | struct stripe_head *sh; | 308 | struct stripe_head *sh; |
| 309 | sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL); | ||
| 310 | if (!sh) | ||
| 311 | return 0; | ||
| 312 | memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev)); | ||
| 313 | sh->raid_conf = conf; | ||
| 314 | spin_lock_init(&sh->lock); | ||
| 315 | |||
| 316 | if (grow_buffers(sh, conf->raid_disks)) { | ||
| 317 | shrink_buffers(sh, conf->raid_disks); | ||
| 318 | kmem_cache_free(conf->slab_cache, sh); | ||
| 319 | return 0; | ||
| 320 | } | ||
| 321 | /* we just created an active stripe so... */ | ||
| 322 | atomic_set(&sh->count, 1); | ||
| 323 | atomic_inc(&conf->active_stripes); | ||
| 324 | INIT_LIST_HEAD(&sh->lru); | ||
| 325 | release_stripe(sh); | ||
| 326 | return 1; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int grow_stripes(raid6_conf_t *conf, int num) | ||
| 330 | { | ||
| 308 | kmem_cache_t *sc; | 331 | kmem_cache_t *sc; |
| 309 | int devs = conf->raid_disks; | 332 | int devs = conf->raid_disks; |
| 310 | 333 | ||
| @@ -316,44 +339,33 @@ static int grow_stripes(raid6_conf_t *conf, int num) | |||
| 316 | if (!sc) | 339 | if (!sc) |
| 317 | return 1; | 340 | return 1; |
| 318 | conf->slab_cache = sc; | 341 | conf->slab_cache = sc; |
| 319 | while (num--) { | 342 | while (num--) |
| 320 | sh = kmem_cache_alloc(sc, GFP_KERNEL); | 343 | if (!grow_one_stripe(conf)) |
| 321 | if (!sh) | ||
| 322 | return 1; | ||
| 323 | memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev)); | ||
| 324 | sh->raid_conf = conf; | ||
| 325 | spin_lock_init(&sh->lock); | ||
| 326 | |||
| 327 | if (grow_buffers(sh, conf->raid_disks)) { | ||
| 328 | shrink_buffers(sh, conf->raid_disks); | ||
| 329 | kmem_cache_free(sc, sh); | ||
| 330 | return 1; | 344 | return 1; |
| 331 | } | ||
| 332 | /* we just created an active stripe so... */ | ||
| 333 | atomic_set(&sh->count, 1); | ||
| 334 | atomic_inc(&conf->active_stripes); | ||
| 335 | INIT_LIST_HEAD(&sh->lru); | ||
| 336 | release_stripe(sh); | ||
| 337 | } | ||
| 338 | return 0; | 345 | return 0; |
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | static void shrink_stripes(raid6_conf_t *conf) | 348 | static int drop_one_stripe(raid6_conf_t *conf) |
| 342 | { | 349 | { |
| 343 | struct stripe_head *sh; | 350 | struct stripe_head *sh; |
| 351 | spin_lock_irq(&conf->device_lock); | ||
| 352 | sh = get_free_stripe(conf); | ||
| 353 | spin_unlock_irq(&conf->device_lock); | ||
| 354 | if (!sh) | ||
| 355 | return 0; | ||
| 356 | if (atomic_read(&sh->count)) | ||
| 357 | BUG(); | ||
| 358 | shrink_buffers(sh, conf->raid_disks); | ||
| 359 | kmem_cache_free(conf->slab_cache, sh); | ||
| 360 | atomic_dec(&conf->active_stripes); | ||
| 361 | return 1; | ||
| 362 | } | ||
| 363 | |||
| 364 | static void shrink_stripes(raid6_conf_t *conf) | ||
| 365 | { | ||
| 366 | while (drop_one_stripe(conf)) | ||
| 367 | ; | ||
| 344 | 368 | ||
| 345 | while (1) { | ||
| 346 | spin_lock_irq(&conf->device_lock); | ||
| 347 | sh = get_free_stripe(conf); | ||
| 348 | spin_unlock_irq(&conf->device_lock); | ||
| 349 | if (!sh) | ||
| 350 | break; | ||
| 351 | if (atomic_read(&sh->count)) | ||
| 352 | BUG(); | ||
| 353 | shrink_buffers(sh, conf->raid_disks); | ||
| 354 | kmem_cache_free(conf->slab_cache, sh); | ||
| 355 | atomic_dec(&conf->active_stripes); | ||
| 356 | } | ||
| 357 | kmem_cache_destroy(conf->slab_cache); | 369 | kmem_cache_destroy(conf->slab_cache); |
| 358 | conf->slab_cache = NULL; | 370 | conf->slab_cache = NULL; |
| 359 | } | 371 | } |
| @@ -1912,6 +1924,74 @@ static void raid6d (mddev_t *mddev) | |||
| 1912 | PRINTK("--- raid6d inactive\n"); | 1924 | PRINTK("--- raid6d inactive\n"); |
| 1913 | } | 1925 | } |
| 1914 | 1926 | ||
| 1927 | static ssize_t | ||
| 1928 | raid6_show_stripe_cache_size(mddev_t *mddev, char *page) | ||
| 1929 | { | ||
| 1930 | raid6_conf_t *conf = mddev_to_conf(mddev); | ||
| 1931 | if (conf) | ||
| 1932 | return sprintf(page, "%d\n", conf->max_nr_stripes); | ||
| 1933 | else | ||
| 1934 | return 0; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | static ssize_t | ||
| 1938 | raid6_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) | ||
| 1939 | { | ||
| 1940 | raid6_conf_t *conf = mddev_to_conf(mddev); | ||
| 1941 | char *end; | ||
| 1942 | int new; | ||
| 1943 | if (len >= PAGE_SIZE) | ||
| 1944 | return -EINVAL; | ||
| 1945 | if (!conf) | ||
| 1946 | return -ENODEV; | ||
| 1947 | |||
| 1948 | new = simple_strtoul(page, &end, 10); | ||
| 1949 | if (!*page || (*end && *end != '\n') ) | ||
| 1950 | return -EINVAL; | ||
| 1951 | if (new <= 16 || new > 32768) | ||
| 1952 | return -EINVAL; | ||
| 1953 | while (new < conf->max_nr_stripes) { | ||
| 1954 | if (drop_one_stripe(conf)) | ||
| 1955 | conf->max_nr_stripes--; | ||
| 1956 | else | ||
| 1957 | break; | ||
| 1958 | } | ||
| 1959 | while (new > conf->max_nr_stripes) { | ||
| 1960 | if (grow_one_stripe(conf)) | ||
| 1961 | conf->max_nr_stripes++; | ||
| 1962 | else break; | ||
| 1963 | } | ||
| 1964 | return len; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | static struct md_sysfs_entry | ||
| 1968 | raid6_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR, | ||
| 1969 | raid6_show_stripe_cache_size, | ||
| 1970 | raid6_store_stripe_cache_size); | ||
| 1971 | |||
| 1972 | static ssize_t | ||
| 1973 | stripe_cache_active_show(mddev_t *mddev, char *page) | ||
| 1974 | { | ||
| 1975 | raid6_conf_t *conf = mddev_to_conf(mddev); | ||
| 1976 | if (conf) | ||
| 1977 | return sprintf(page, "%d\n", atomic_read(&conf->active_stripes)); | ||
| 1978 | else | ||
| 1979 | return 0; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | static struct md_sysfs_entry | ||
| 1983 | raid6_stripecache_active = __ATTR_RO(stripe_cache_active); | ||
| 1984 | |||
| 1985 | static struct attribute *raid6_attrs[] = { | ||
| 1986 | &raid6_stripecache_size.attr, | ||
| 1987 | &raid6_stripecache_active.attr, | ||
| 1988 | NULL, | ||
| 1989 | }; | ||
| 1990 | static struct attribute_group raid6_attrs_group = { | ||
| 1991 | .name = NULL, | ||
| 1992 | .attrs = raid6_attrs, | ||
| 1993 | }; | ||
| 1994 | |||
| 1915 | static int run(mddev_t *mddev) | 1995 | static int run(mddev_t *mddev) |
| 1916 | { | 1996 | { |
| 1917 | raid6_conf_t *conf; | 1997 | raid6_conf_t *conf; |
| @@ -2095,6 +2175,7 @@ static int stop (mddev_t *mddev) | |||
| 2095 | shrink_stripes(conf); | 2175 | shrink_stripes(conf); |
| 2096 | kfree(conf->stripe_hashtbl); | 2176 | kfree(conf->stripe_hashtbl); |
| 2097 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 2177 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
| 2178 | sysfs_remove_group(&mddev->kobj, &raid6_attrs_group); | ||
| 2098 | kfree(conf); | 2179 | kfree(conf); |
| 2099 | mddev->private = NULL; | 2180 | mddev->private = NULL; |
| 2100 | return 0; | 2181 | return 0; |
