md - 0 of 7 - Introduction
Subsystems (2)
PATCH 1/1 md - 0 of 7 - Introduction
Herewith, 7 more patches for drivers/md and related code.
The first fixes a lock-up that was introduced by a recent patch (as I was worried might happen...).
The fourth makes device IO statistics work for md arrays.
The sixth, which depends on come code rearrangement in the 5th, is the most significant of the patches. It allows md devices to be partitioned (I finally figured out the *right* way to do this).
A second major number is dynamically allocated, and md arrays can be created under this major as well as the traditional '9'. Arrays created under the new major get 64 minor numbers, 63 of which can be used for different partitions.
The arrays assembled under the new major are completely separate from any arrays assembled under the old major (9). (though an array created under one can be shut down and re-assembled under another).
Currently this means that only 4 md arrays can be partitioned. However once user-space catches up with the new 32bit device numbers in the kernel, the limit will be many thousands.
Creating device nodes in /dev is left as a exercise for the reader (as the major number can be different at each reboot). Maybe devfs or udev are solutions.
The allocated major number can be found by looking for "mdp" in /proc/devices.
Partitioned md devices have names like
md_dXpY
in /proc/partitions and /sys/block, are recommended to have names like
/dev/md/dXpY
in /dev (X and Y are numbers).
Finally, the last (7th) patch is more of a sick joke than a serious patch, though I would not object to it being included in the kernel. Currently devices that are not partitionable (e.g. md devices with major '9') do not show up in /proc/partitions, which is a regression
from 2.4. Maybe it is better to remove the "sgp->minors == 1" test,
but as Linus put that in.....
NeilBrown
PATCH 1/1 md - 1 of 7 - Fix possible hang in raid shutdown.
If a raid array was syncing on shutdown, it would hang on shutdown, constantly re-entering md_enter_safemade. This fixes it.
----------- Diffstat output ------------
./drivers/md/md.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +2 -1
@@ -3106,7 +3106,8 @@ static inline void md_enter_safemode(mdd {if (!mddev->safemode)return ;if (mddev->safemode ==2 && - (atomic_read (&mddev->writes_pending) || mddev->in_sync)) + (atomic_read (&mddev->writes_pending) || mddev->in_sync || + mddev->recovery_cp != MaxSector))return ;/* avoid the lock */ mddev_lock_uninterruptible (mddev); if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
PATCH 1/1 md - 2 of 7 - Move the test in preferred_minor to where it is used.
In reply to NeilBrownA RAID superblock can indicate which minor number the array should be assembled under. As this is only meaningful when doing auto-start, we move the test for it being in the valid range to the place where auto-start happens. When an array is started any other way, it doesn't matter what value is here.
----------- Diffstat output ------------
./drivers/md/md.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +4 -7
@@ -512,11 +512,6 @@ static int super_90_load(mdk_rdev_t *rde goto abort; } -if (sb->md_minor >=MAX_MD_DEVS ) { -printk (KERN_ERR "md: %s: invalid raid minor (%x)\n" , - b, sb->md_minor); - goto abort; - }if (sb->raid_disks <=0 ) goto abort;
@@ -1829,7 +1824,7 @@ static void autorun_devices(void)"md: md%d already running, cannot run %s\n" , mdidx(mddev), bdevname(rdev0->bdev,b));mddev_unlock (mddev); - }else { + }else if (rdev0->preferred_minor >=0 && rdev0->preferred_minor <MAX_MD_DEVS ) {printk (KERN_INFO "md: created md%d\n" ,mdidx (mddev)); ITERATE_RDEV_GENERIC(candidates,rdev,tmp) {list_del_init (&rdev->same_set);
@@ -1838,7 +1833,9 @@ static void autorun_devices(void) }autorun_array (mddev);mddev_unlock (mddev); - } + }else +printk (KERN_WARNING "md: %s had invalid preferred minor %d\n" , +bdevname (rdev->bdev, b), rdev0->preferred_minor);/* on success, candidates will be empty, on error * it won't... */
PATCH 1/1 md - 3 of 7 - Fixes to make debuging output nicer.
In reply to NeilBrownThis patch thanks to Paul Clements <[email protected]> and only has effect if md compile with
#define DEBUG 1
----------- Diffstat output ------------
./drivers/md/md.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +8 -7
@@ -2690,7 +2690,7 @@ int md_thread(void * arg)void md_wakeup_thread (mdk_thread_t *thread) {if (thread) { -dprintk ("md: waking up MD thread %p.\n" , thread); +dprintk ("md: waking up MD thread %s.\n" , thread->tsk->comm);set_bit (THREAD_WAKEUP , &thread->flags);wake_up (&thread->wqueue); }
@@ -2751,12 +2751,6 @@ void md_unregister_thread(mdk_thread_t *void md_error (mddev_t *mddev,mdk_rdev_t *rdev) { -dprintk ("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n" , -MD_MAJOR ,mdidx (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) {MD_BUG ();return ;
@@ -2764,6 +2758,13 @@ void md_error(mddev_t *mddev, mdk_rdev_tif (!rdev || rdev->faulty)return ; + +dprintk ("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n" , +MD_MAJOR ,mdidx (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->error_handler)return ; mddev->pers->error_handler (mddev,rdev);
PATCH 1/1 md - 4 of 7 - Collect device IO statistics for MD personalities.
In reply to NeilBrownUpdate {read,write}{s,_sectors} on each request to an MD array.
----------- Diffstat output ------------
./drivers/md/linear.c | 8 ++++++++ ./drivers/md/multipath.c | 7 +++++++ ./drivers/md/raid0.c | 8 ++++++++ ./drivers/md/raid1.c | 8 ++++++++ ./drivers/md/raid5.c | 8 ++++++++ ./drivers/md/raid6main.c | 8 ++++++++ 6 files changed, 47 insertions(+)
drivers/md/linear.c renamed from drivers/md/linear.c~current~ +8 -0
@@ -208,6 +208,14 @@ static int linear_make_request (request_dev_info_t *tmp_dev;sector_t block; +if (bio_data_dir (bio)==WRITE ) { +disk_stat_inc (mddev->gendisk, writes); +disk_stat_add (mddev->gendisk, write_sectors,bio_sectors (bio)); + }else { +disk_stat_inc (mddev->gendisk, reads); +disk_stat_add (mddev->gendisk, read_sectors,bio_sectors (bio)); + } + tmp_dev =which_dev (mddev, bio->bi_sector); block = bio->bi_sector >>1 ;
drivers/md/multipath.c renamed from drivers/md/multipath.c~current~ +7 -0
@@ -167,6 +167,13 @@ static int multipath_make_request (reque mp_bh->master_bio = bio; mp_bh->mddev = mddev; +if (bio_data_dir (bio)==WRITE ) { +disk_stat_inc (mddev->gendisk, writes); +disk_stat_add (mddev->gendisk, write_sectors,bio_sectors (bio)); + }else { +disk_stat_inc (mddev->gendisk, reads); +disk_stat_add (mddev->gendisk, read_sectors,bio_sectors (bio)); + }/* * read balancing logic: */
drivers/md/raid0.c renamed from drivers/md/raid0.c~current~ +8 -0
@@ -365,6 +365,14 @@ static int raid0_make_request (request_qunsigned long chunk;sector_t block, rsect; +if (bio_data_dir (bio)==WRITE ) { +disk_stat_inc (mddev->gendisk, writes); +disk_stat_add (mddev->gendisk, write_sectors,bio_sectors (bio)); + }else { +disk_stat_inc (mddev->gendisk, reads); +disk_stat_add (mddev->gendisk, read_sectors,bio_sectors (bio)); + } + chunk_size = mddev->chunk_size >>10 ; chunk_sects = mddev->chunk_size >>9 ; chunksize_bits =ffz (~chunk_size);
drivers/md/raid1.c renamed from drivers/md/raid1.c~current~ +8 -0
@@ -474,6 +474,14 @@ static int make_request(request_queue_t conf->nr_pending++;spin_unlock_irq (&conf->resync_lock); +if (bio_data_dir (bio)==WRITE ) { +disk_stat_inc (mddev->gendisk, writes); +disk_stat_add (mddev->gendisk, write_sectors,bio_sectors (bio)); + }else { +disk_stat_inc (mddev->gendisk, reads); +disk_stat_add (mddev->gendisk, read_sectors,bio_sectors (bio)); + } +/* * make_request() can abort the operation when READA is being * used and no empty request is available.
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +8 -0
@@ -1326,6 +1326,14 @@ static int make_request (request_queue_tsector_t logical_sector, last_sector;struct stripe_head *sh; +if (bio_data_dir (bi)==WRITE ) { +disk_stat_inc (mddev->gendisk, writes); +disk_stat_add (mddev->gendisk, write_sectors,bio_sectors (bi)); + }else { +disk_stat_inc (mddev->gendisk, reads); +disk_stat_add (mddev->gendisk, read_sectors,bio_sectors (bi)); + } + logical_sector = bi->bi_sector & ~(STRIPE_SECTORS -1 ); last_sector = bi->bi_sector + (bi->bi_size>>9 );
drivers/md/raid6main.c renamed from drivers/md/raid6main.c~current~ +8 -0
@@ -1488,6 +1488,14 @@ static int make_request (request_queue_tsector_t logical_sector, last_sector;struct stripe_head *sh; +if (bio_data_dir (bi)==WRITE ) { +disk_stat_inc (mddev->gendisk, writes); +disk_stat_add (mddev->gendisk, write_sectors,bio_sectors (bi)); + }else { +disk_stat_inc (mddev->gendisk, reads); +disk_stat_add (mddev->gendisk, read_sectors,bio_sectors (bi)); + } + logical_sector = bi->bi_sector & ~(STRIPE_SECTORS -1 ); last_sector = bi->bi_sector + (bi->bi_size>>9 );
PATCH 1/1 md - 5 of 7 - Change the way the name of an md device is printed in error messages.
In reply to NeilBrownInstead of using ("md%d", mdidx(mddev)), we now use
("%s", mdname(mddev)) where mdname is the disk_name field in the associated
gendisk structure. This allows future flexability in naming.
----------- Diffstat output ------------
./drivers/md/md.c | 132 ++++++++++++++++++++++---------------------- ./drivers/md/multipath.c | 30 ++++------ ./drivers/md/raid0.c | 4 - ./drivers/md/raid1.c | 30 +++++----- ./drivers/md/raid5.c | 40 ++++++------- ./drivers/md/raid6main.c | 42 +++++++------- ./include/linux/raid/md_k.h | 4 + 7 files changed, 142 insertions(+), 140 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +66 -66
@@ -994,10 +994,10 @@ static int bind_rdev_to_array(mdk_rdev_t same_pdev =match_dev_unit (mddev, rdev);if (same_pdev)printk (KERN_WARNING -"md%d: WARNING: %s appears to be on the same physical" +"%s: WARNING: %s appears to be on the same physical" " disk as %s. True\n protection against single-disk" " failure might be compromised.\n" , -mdidx (mddev),bdevname (rdev->bdev,b), +mdname (mddev),bdevname (rdev->bdev,b),bdevname (same_pdev->bdev,b2));/* Verify rdev->desc_nr is unique.
@@ -1177,7 +1177,7 @@ void md_print_devices(void)printk ("md: * <COMPLETE RAID STATE PRINTOUT> *\n" );printk ("md: **********************************\n" ); ITERATE_MDDEV(mddev,tmp) { -printk ("md%d: " ,mdidx (mddev)); +printk ("%s: " ,mdname (mddev)); ITERATE_RDEV(mddev,rdev,tmp2)printk ("<%s>" ,bdevname (rdev->bdev,b));
@@ -1257,8 +1257,8 @@ repeat:return ;dprintk (KERN_INFO -"md: updating md%d RAID superblock on device (in sync %d)\n" , -mdidx (mddev),mddev->in_sync); +"md: updating %s RAID superblock on device (in sync %d)\n" , +mdname (mddev),mddev->in_sync); err =0 ; ITERATE_RDEV(mddev,rdev,tmp) {
@@ -1424,8 +1424,8 @@ static int analyze_sbs(mddev_t * mddev)if (mddev->major_version !=MD_MAJOR_VERSION || mddev->minor_version >MD_MINOR_VERSION ) {printk (KERN_ALERT -"md: md%d: unsupported raid array version %d.%d.%d\n" , -mdidx (mddev), mddev->major_version, +"md: %s: unsupported raid array version %d.%d.%d\n" , +mdname (mddev), mddev->major_version, mddev->minor_version, mddev->patch_version); goto abort; }
@@ -1433,9 +1433,9 @@ static int analyze_sbs(mddev_t * mddev)if ((mddev->recovery_cp != MaxSector) && ((mddev->level ==1 ) || ((mddev->level >=4 ) && (mddev->level <=6 )))) -printk (KERN_ERR "md: md%d: raid array is not clean" +printk (KERN_ERR "md: %s: raid array is not clean" " -- starting background reconstruction\n" , -mdidx (mddev)); +mdname (mddev));return 0 ; abort:
@@ -1660,8 +1660,8 @@ static int restart_array(mddev_t *mddev) mddev->ro =0 ;set_disk_ro (disk,0 ); -printk (KERN_INFO "md: md%d switched to read-write mode.\n" , -mdidx (mddev)); +printk (KERN_INFO "md: %s switched to read-write mode.\n" , +mdname (mddev));/* * Kick recovery or resync if necessary */
@@ -1669,8 +1669,8 @@ static int restart_array(mddev_t *mddev)md_wakeup_thread (mddev->thread); err =0 ; }else { -printk (KERN_ERR "md: md%d has no personality assigned.\n" , -mdidx (mddev)); +printk (KERN_ERR "md: %s has no personality assigned.\n" , +mdname (mddev)); err = -EINVAL ; }
@@ -1685,7 +1685,7 @@ static int do_md_stop(mddev_t * mddev, iif (mddev->pers) {if (atomic_read (&mddev->active)>2 ) { -printk ("md: md%d still in use.\n" ,mdidx (mddev)); +printk ("md: %s still in use.\n" ,mdname (mddev));return -EBUSY ; }
@@ -1727,7 +1727,7 @@ static int do_md_stop(mddev_t * mddev, i*/ if (!ro) {struct gendisk *disk; -printk (KERN_INFO "md: md%d stopped.\n" ,mdidx (mddev)); +printk (KERN_INFO "md: %s stopped.\n" ,mdname (mddev));export_array (mddev);
@@ -1736,8 +1736,8 @@ static int do_md_stop(mddev_t * mddev, iif (disk)set_capacity (disk,0 ); }else -printk (KERN_INFO "md: md%d switched to read-only mode.\n" , -mdidx (mddev)); +printk (KERN_INFO "md: %s switched to read-only mode.\n" , +mdname (mddev)); err =0 ; out:return err;
@@ -1816,16 +1816,16 @@ static void autorun_devices(void)break ; }if (mddev_lock (mddev)) -printk (KERN_WARNING "md: md%d locked, cannot run\n" , -mdidx (mddev)); +printk (KERN_WARNING "md: %s locked, cannot run\n" , +mdname (mddev));else if (mddev->raid_disks || mddev->major_version || !list_empty (&mddev->disks)) {printk (KERN_WARNING -"md: md%d already running, cannot run %s\n" , -mdidx (mddev),bdevname (rdev0->bdev,b)); +"md: %s already running, cannot run %s\n" , +mdname (mddev),bdevname (rdev0->bdev,b));mddev_unlock (mddev); }else if (rdev0->preferred_minor >=0 && rdev0->preferred_minor <MAX_MD_DEVS ) { -printk (KERN_INFO "md: created md%d\n" ,mdidx (mddev)); +printk (KERN_INFO "md: created %s\n" ,mdname (mddev)); ITERATE_RDEV_GENERIC(candidates,rdev,tmp) {list_del_init (&rdev->same_set);if (bind_rdev_to_array (rdev, mddev))
@@ -2059,8 +2059,8 @@ static int add_new_disk(mddev_t * mddev,int err;if (!mddev->pers->hot_add_disk) {printk (KERN_WARNING -"md%d: personality does not support diskops!\n" , -mdidx (mddev)); +"%s: personality does not support diskops!\n" , +mdname (mddev));return -EINVAL ; } rdev = md_import_device(dev, mddev->major_version,
@@ -2085,8 +2085,8 @@ static int add_new_disk(mddev_t * mddev,* for major_version==0 superblocks */ if (mddev->major_version !=0 ) { -printk (KERN_WARNING "md%d: ADD_NEW_DISK not supported\n" , -mdidx (mddev)); +printk (KERN_WARNING "%s: ADD_NEW_DISK not supported\n" , +mdname (mddev));return -EINVAL ; }
@@ -2140,8 +2140,8 @@ static int hot_generate_error(mddev_t *if (!mddev->pers)return -ENODEV ; -printk (KERN_INFO "md: trying to generate %s error in md%d ... \n" , -__bdevname (dev, b),mdidx (mddev)); +printk (KERN_INFO "md: trying to generate %s error in %s ... \n" , +__bdevname (dev, b),mdname (mddev)); rdev =find_rdev (mddev, dev);if (!rdev) {
@@ -2175,8 +2175,8 @@ static int hot_remove_disk(mddev_t * mddif (!mddev->pers)return -ENODEV ; -printk (KERN_INFO "md: trying to remove %s from md%d ... \n" , -__bdevname (dev, b),mdidx (mddev)); +printk (KERN_INFO "md: trying to remove %s from %s ... \n" , +__bdevname (dev, b),mdname (mddev)); rdev =find_rdev (mddev, dev);if (!rdev)
@@ -2190,8 +2190,8 @@ static int hot_remove_disk(mddev_t * mddreturn 0 ; busy: -printk (KERN_WARNING "md: cannot remove active disk %s from md%d ... \n" , -bdevname (rdev->bdev,b),mdidx (mddev)); +printk (KERN_WARNING "md: cannot remove active disk %s from %s ... \n" , +bdevname (rdev->bdev,b),mdname (mddev));return -EBUSY ; }
@@ -2205,19 +2205,19 @@ static int hot_add_disk(mddev_t * mddev,if (!mddev->pers)return -ENODEV ; -printk (KERN_INFO "md: trying to hot-add %s to md%d ... \n" , -__bdevname (dev, b),mdidx (mddev)); +printk (KERN_INFO "md: trying to hot-add %s to %s ... \n" , +__bdevname (dev, b),mdname (mddev));if (mddev->major_version !=0 ) { -printk (KERN_WARNING "md%d: HOT_ADD may only be used with" +printk (KERN_WARNING "%s: HOT_ADD may only be used with" " version-0 superblocks.\n" , -mdidx (mddev)); +mdname (mddev));return -EINVAL ; }if (!mddev->pers->hot_add_disk) {printk (KERN_WARNING -"md%d: personality does not support diskops!\n" , -mdidx (mddev)); +"%s: personality does not support diskops!\n" , +mdname (mddev));return -EINVAL ; }
@@ -2235,8 +2235,8 @@ static int hot_add_disk(mddev_t * mddev,if (size < mddev->size) {printk (KERN_WARNING -"md%d: disk size %llu blocks < array size %llu\n" , -mdidx (mddev), (unsigned long long )size, +"%s: disk size %llu blocks < array size %llu\n" , +mdname (mddev), (unsigned long long )size, (unsigned long long )mddev->size); err = -ENOSPC ; goto abort_export;
@@ -2244,8 +2244,8 @@ static int hot_add_disk(mddev_t * mddev,if (rdev->faulty) {printk (KERN_WARNING -"md: can not hot-add faulty %s disk to md%d!\n" , -bdevname (rdev->bdev,b),mdidx (mddev)); +"md: can not hot-add faulty %s disk to %s!\n" , +bdevname (rdev->bdev,b),mdname (mddev)); err = -EINVAL ; goto abort_export; }
@@ -2259,8 +2259,8 @@ static int hot_add_disk(mddev_t * mddev,*/ if (rdev->desc_nr == mddev->max_disks) { -printk (KERN_WARNING "md%d: can not hot-add to full array!\n" , -mdidx (mddev)); +printk (KERN_WARNING "%s: can not hot-add to full array!\n" , +mdname (mddev)); err = -EBUSY ; goto abort_unbind_export; }
@@ -2442,15 +2442,15 @@ static int md_ioctl(struct inode *inode,if (!list_empty (&mddev->disks)) {printk (KERN_WARNING -"md: array md%d already has disks!\n" , -mdidx (mddev)); +"md: array %s already has disks!\n" , +mdname (mddev)); err = -EBUSY ; goto abort_unlock; }if (mddev->raid_disks) {printk (KERN_WARNING -"md: array md%d already initialised!\n" , -mdidx (mddev)); +"md: array %s already initialised!\n" , +mdname (mddev)); err = -EBUSY ; goto abort_unlock; }
@@ -2645,7 +2645,7 @@ int md_thread(void * arg)* Detach thread */ -daemonize (thread->name,mdidx (thread->mddev)); +daemonize (thread->name,mdname (thread->mddev)); current->exit_signal =SIGCHLD ;allow_signal (SIGKILL );
@@ -2759,8 +2759,8 @@ void md_error(mddev_t *mddev, mdk_rdev_tif (!rdev || rdev->faulty)return ; -dprintk ("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n" , -MD_MAJOR ,mdidx (mddev), +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 ));
@@ -2933,7 +2933,7 @@ static int md_seq_show(struct seq_file *if (mddev_lock (mddev)!=0 )return -EINTR ;if (mddev->pers || mddev->raid_disks || !list_empty (&mddev->disks)) { -seq_printf (seq,"md%d : %sactive" ,mdidx (mddev), +seq_printf (seq,"%s : %sactive" ,mdname (mddev), mddev->pers ?"" :"in" );if (mddev->pers) {if (mddev->ro)
@@ -3122,8 +3122,8 @@ static inline void md_enter_safemode(mddvoid md_handle_safemode (mddev_t *mddev) {if (signal_pending (current)) { -printk (KERN_INFO "md: md%d in immediate safe mode\n" , -mdidx (mddev)); +printk (KERN_INFO "md: %s in immediate safe mode\n" , +mdname (mddev)); mddev->safemode =2 ;flush_signals (current); }
@@ -3165,10 +3165,10 @@ static void md_do_sync(mddev_t *mddev)continue ;if (mddev2->curr_resync &&match_mddev_units (mddev,mddev2)) { -printk (KERN_INFO "md: delaying resync of md%d" -" until md%d has finished resync (they" +printk (KERN_INFO "md: delaying resync of %s" +" until %s has finished resync (they" " share one or more physical units)\n" , -mdidx (mddev),mdidx (mddev2)); +mdname (mddev),mdname (mddev2));if (mddev < mddev2) {/* arbitrarily yield */ mddev->curr_resync =1 ;wake_up (&resync_wait);
@@ -3189,7 +3189,7 @@ static void md_do_sync(mddev_t *mddev) max_sectors = mddev->size <<1 ; -printk (KERN_INFO "md: syncing RAID array md%d\n" ,mdidx (mddev)); +printk (KERN_INFO "md: syncing RAID array %s\n" ,mdname (mddev));printk (KERN_INFO "md: minimum _guaranteed_ reconstruction speed:" " %d KB/sec/disc.\n" , sysctl_speed_limit_min); printk(KERN_INFO "md: using maximum available idle IO bandwith "
@@ -3222,8 +3222,8 @@ static void md_do_sync(mddev_t *mddev)if (j)printk (KERN_INFO -"md: resuming recovery of md%d from checkpoint.\n" , -mdidx (mddev)); +"md: resuming recovery of %s from checkpoint.\n" , +mdname (mddev));while (j < max_sectors) {int sectors;
@@ -3293,7 +3293,7 @@ static void md_do_sync(mddev_t *mddev) } } } -printk (KERN_INFO "md: md%d: sync done.\n" ,mdidx (mddev)); +printk (KERN_INFO "md: %s: sync done.\n" ,mdname (mddev));/* * this also signals 'finished resyncing' to md_stop */
@@ -3308,8 +3308,8 @@ static void md_do_sync(mddev_t *mddev) mddev->curr_resync > mddev->recovery_cp) {if (test_bit (MD_RECOVERY_INTR , &mddev->recovery)) {printk (KERN_INFO -"md: checkpointing recovery of md%d.\n" , -mdidx (mddev)); +"md: checkpointing recovery of %s.\n" , +mdname (mddev)); mddev->recovery_cp = mddev->curr_resync; }else mddev->recovery_cp = MaxSector;
@@ -3429,11 +3429,11 @@ void md_check_recovery(mddev_t *mddev)set_bit (MD_RECOVERY_SYNC , &mddev->recovery); mddev->sync_thread =md_register_thread (md_do_sync, mddev, -"md%d_resync" ); +"%s_resync" );if (!mddev->sync_thread) { -printk (KERN_ERR "md%d: could not start resync" +printk (KERN_ERR "%s: could not start resync" " thread...\n" , -mdidx (mddev)); +mdname (mddev));/* leave the spares where they are, it shouldn't hurt */ mddev->recovery =0 ; }else {
drivers/md/multipath.c renamed from drivers/md/multipath.c~current~ +14 -16
@@ -389,8 +389,8 @@ static int multipath_run (mddev_t *mddevstruct list_head *tmp;if (mddev->level !=LEVEL_MULTIPATH ) { -printk ("multipath: md%d: raid level not set to multipath IO (%d)\n" , -mdidx (mddev), mddev->level); +printk ("multipath: %s: raid level not set to multipath IO (%d)\n" , +mdname (mddev), mddev->level); goto out; }/*
@@ -403,8 +403,8 @@ static int multipath_run (mddev_t *mddev mddev->private = conf;if (!conf) {printk (KERN_ERR -"multipath: couldn't allocate memory for md%d\n" , -mdidx (mddev)); +"multipath: couldn't allocate memory for %s\n" , +mdname (mddev)); goto out; }memset (conf,0 ,sizeof (*conf));
@@ -413,8 +413,8 @@ static int multipath_run (mddev_t *mddev GFP_KERNEL);if (!conf->multipaths) {printk (KERN_ERR -"multipath: couldn't allocate memory for md%d\n" , -mdidx (mddev)); +"multipath: couldn't allocate memory for %s\n" , +mdname (mddev)); goto out_free_conf; }memset (conf->multipaths,0 ,sizeof (struct multipath_info )*mddev->raid_disks);
@@ -448,8 +448,8 @@ static int multipath_run (mddev_t *mddev conf->device_lock =SPIN_LOCK_UNLOCKED ;if (!conf->working_disks) { -printk (KERN_ERR "multipath: no operational IO paths for md%d\n" , -mdidx (mddev)); +printk (KERN_ERR "multipath: no operational IO paths for %s\n" , +mdname (mddev)); goto out_free_conf; } mddev->degraded = conf->raid_disks = conf->working_disks;
@@ -459,25 +459,23 @@ static int multipath_run (mddev_t *mddev NULL);if (conf->pool ==NULL ) {printk (KERN_ERR -"multipath: couldn't allocate memory for md%d\n" , -mdidx (mddev)); +"multipath: couldn't allocate memory for %s\n" , +mdname (mddev)); goto out_free_conf; } { -const char * name ="md%d_multipath" ; - - mddev->thread =md_register_thread (multipathd, mddev, name); + mddev->thread =md_register_thread (multipathd, mddev,"%s_multipath" );if (!mddev->thread) {printk (KERN_ERR "multipath: couldn't allocate thread" -" for md%d\n" ,mdidx (mddev)); +" for %s\n" ,mdname (mddev)); goto out_free_conf; } }printk (KERN_INFO -"multipath: array md%d active with %d out of %d IO paths\n" , -mdidx (mddev), conf->working_disks, mddev->raid_disks); +"multipath: array %s active with %d out of %d IO paths\n" , +mdname (mddev), conf->working_disks, mddev->raid_disks);/* * Ok, everything is just fine now */
drivers/md/raid0.c renamed from drivers/md/raid0.c~current~ +2 -2
@@ -240,8 +240,8 @@ static int raid0_run (mddev_t *mddev)mdk_rdev_t *rdev;struct list_head *tmp; -printk ("md%d: setting max_sectors to %d, segment boundary to %d\n" , -mdidx (mddev), +printk ("%s: setting max_sectors to %d, segment boundary to %d\n" , +mdname (mddev), mddev->chunk_size >>9 , (mddev->chunk_size>>1 )-1 );blk_queue_max_sectors (mddev->queue, mddev->chunk_size >>9 );
drivers/md/raid1.c renamed from drivers/md/raid1.c~current~ +15 -15
@@ -1052,8 +1052,8 @@ static int run(mddev_t *mddev)struct list_head *tmp;if (mddev->level !=1 ) { -printk ("raid1: md%d: raid level not set to mirroring (%d)\n" , -mdidx (mddev), mddev->level); +printk ("raid1: %s: raid level not set to mirroring (%d)\n" , +mdname (mddev), mddev->level); goto out; }/*
@@ -1064,16 +1064,16 @@ static int run(mddev_t *mddev) conf =kmalloc (sizeof (conf_t),GFP_KERNEL ); mddev->private = conf;if (!conf) { -printk (KERN_ERR "raid1: couldn't allocate memory for md%d\n" , -mdidx (mddev)); +printk (KERN_ERR "raid1: couldn't allocate memory for %s\n" , +mdname (mddev)); goto out; }memset (conf,0 ,sizeof (*conf)); conf->mirrors =kmalloc (sizeof (struct mirror_info )*mddev->raid_disks,GFP_KERNEL );if (!conf->mirrors) { -printk (KERN_ERR "raid1: couldn't allocate memory for md%d\n" , -mdidx (mddev)); +printk (KERN_ERR "raid1: couldn't allocate memory for %s\n" , +mdname (mddev)); goto out_free_conf; }memset (conf->mirrors,0 ,sizeof (struct mirror_info )*mddev->raid_disks);
@@ -1081,8 +1081,8 @@ static int run(mddev_t *mddev) conf->r1bio_pool =mempool_create (NR_RAID1_BIOS , r1bio_pool_alloc, r1bio_pool_free, mddev);if (!conf->r1bio_pool) { -printk (KERN_ERR "raid1: couldn't allocate memory for md%d\n" , -mdidx (mddev)); +printk (KERN_ERR "raid1: couldn't allocate memory for %s\n" , +mdname (mddev)); goto out_free_conf; }
@@ -1121,8 +1121,8 @@ static int run(mddev_t *mddev)init_waitqueue_head (&conf->wait_resume);if (!conf->working_disks) { -printk (KERN_ERR "raid1: no operational mirrors for md%d\n" , -mdidx (mddev)); +printk (KERN_ERR "raid1: no operational mirrors for %s\n" , +mdname (mddev)); goto out_free_conf; }
@@ -1150,17 +1150,17 @@ static int run(mddev_t *mddev) { - mddev->thread =md_register_thread (raid1d, mddev,"md%d_raid1" ); + mddev->thread =md_register_thread (raid1d, mddev,"%s_raid1" );if (!mddev->thread) {printk (KERN_ERR -"raid1: couldn't allocate thread for md%d\n" , -mdidx (mddev)); +"raid1: couldn't allocate thread for %s\n" , +mdname (mddev)); goto out_free_conf; } }printk (KERN_INFO -"raid1: raid set md%d active with %d out of %d mirrors\n" , -mdidx (mddev), mddev->raid_disks - mddev->degraded, +"raid1: raid set %s active with %d out of %d mirrors\n" , +mdname (mddev), mddev->raid_disks - mddev->degraded, mddev->raid_disks);/* * Ok, everything is just fine now
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +20 -20
@@ -1485,7 +1485,7 @@ static int run (mddev_t *mddev)struct list_head *tmp;if (mddev->level !=5 && mddev->level !=4 ) { -printk ("raid5: md%d: raid level not set to 4/5 (%d)\n" ,mdidx (mddev), mddev->level); +printk ("raid5: %s: raid level not set to 4/5 (%d)\n" ,mdname (mddev), mddev->level);return -EIO ; }
@@ -1511,7 +1511,7 @@ static int run (mddev_t *mddev) mddev->queue->unplug_fn = raid5_unplug_device; -PRINTK ("raid5: run(md%d) called.\n" ,mdidx (mddev)); +PRINTK ("raid5: run(%s) called.\n" ,mdname (mddev)); ITERATE_RDEV(mddev,rdev,tmp) { raid_disk = rdev->raid_disk;
@@ -1543,37 +1543,37 @@ static int run (mddev_t *mddev) conf->max_nr_stripes =NR_STRIPES ;if (!conf->chunk_size || conf->chunk_size %4 ) { -printk (KERN_ERR "raid5: invalid chunk size %d for md%d\n" , - conf->chunk_size,mdidx (mddev)); +printk (KERN_ERR "raid5: invalid chunk size %d for %s\n" , + conf->chunk_size,mdname (mddev)); goto abort; }if (conf->algorithm >ALGORITHM_RIGHT_SYMMETRIC ) {printk (KERN_ERR -"raid5: unsupported parity algorithm %d for md%d\n" , - conf->algorithm,mdidx (mddev)); +"raid5: unsupported parity algorithm %d for %s\n" , + conf->algorithm,mdname (mddev)); goto abort; }if (mddev->degraded >1 ) { -printk (KERN_ERR "raid5: not enough operational devices for md%d" +printk (KERN_ERR "raid5: not enough operational devices for %s" " (%d/%d failed)\n" , -mdidx (mddev), conf->failed_disks, conf->raid_disks); +mdname (mddev), conf->failed_disks, conf->raid_disks); goto abort; }if (mddev->degraded ==1 && mddev->recovery_cp != MaxSector) {printk (KERN_ERR -"raid5: cannot start dirty degraded array for md%d\n" , -mdidx (mddev)); +"raid5: cannot start dirty degraded array for %s\n" , +mdname (mddev)); goto abort; } { - mddev->thread =md_register_thread (raid5d, mddev,"md%d_raid5" ); + mddev->thread =md_register_thread (raid5d, mddev,"%s_raid5" );if (!mddev->thread) {printk (KERN_ERR -"raid5: couldn't allocate thread for md%d\n" , -mdidx (mddev)); +"raid5: couldn't allocate thread for %s\n" , +mdname (mddev)); goto abort; } }
@@ -1586,18 +1586,18 @@ memory = conf->max_nr_stripes * (sizeof(md_unregister_thread (mddev->thread); goto abort; }else -printk (KERN_INFO "raid5: allocated %dkB for md%d\n" , - memory,mdidx (mddev)); +printk (KERN_INFO "raid5: allocated %dkB for %s\n" , + memory,mdname (mddev));if (mddev->degraded ==0 ) -printk ("raid5: raid level %d set md%d active with %d out of %d" -" devices, algorithm %d\n" , conf->level,mdidx (mddev), +printk ("raid5: raid level %d set %s active with %d out of %d" +" devices, algorithm %d\n" , conf->level,mdname (mddev), mddev->raid_disks-mddev->degraded, mddev->raid_disks, conf->algorithm);else -printk (KERN_ALERT "raid5: raid level %d set md%d active with %d" +printk (KERN_ALERT "raid5: raid level %d set %s active with %d" " out of %d devices, algorithm %d\n" , conf->level, -mdidx (mddev), mddev->raid_disks - mddev->degraded, +mdname (mddev), mddev->raid_disks - mddev->degraded, mddev->raid_disks, conf->algorithm);print_raid5_conf (conf);
@@ -1624,7 +1624,7 @@ abort:kfree (conf); } mddev->private =NULL ; -printk (KERN_ALERT "raid5: failed to run raid set md%d\n" ,mdidx (mddev)); +printk (KERN_ALERT "raid5: failed to run raid set %s\n" ,mdname (mddev));return -EIO ; }
drivers/md/raid6main.c renamed from drivers/md/raid6main.c~current~ +21 -21
102 lines not on this page · raw message
include/linux/raid/md_k.h renamed from include/linux/raid/md_k.h~current~ +4 -0
@@ -281,6 +281,10 @@ static inline int mdidx (mddev_t * mddev {return mddev->__minor; } +static inline char *mdname (mddev_t * mddev) +{ +return mddev->gendisk ? mddev->gendisk->disk_name :"mdX" ; +}extern mdk_rdev_t *find_rdev_nr (mddev_t *mddev,int nr);
PATCH 1/1 md - 6 of 7 - Allow partitioning of MD devices.
In reply to NeilBrownWith this patch, md used two major numbers for arrays.
One Major is number 9 with name 'md' have unpartitioned md arrays, one per minor number.
The other Major is allocated dynamically with name 'mdp' and had on array for every 64 minors, allowing for upto 63 partitions.
The arrays under one major are completely separate from the arrays under the other.
The preferred name for devices with the new major are of the form:
/dev/md/d1p3 # partion 3 of device 1 - minor 67
----------- Diffstat output ------------
./drivers/md/md.c | 64 ++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 50 insertions(+), 14 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +50 -14
@@ -52,6 +52,9 @@#define MAJOR_NR MD_MAJOR#define MD_DRIVER +/* 63 partitions with the alternate major number (mdp) */ +#define MdpMinorShift 6 +#define DEBUG 0 #define dprintk(x...) ((void)(DEBUG && printk(x)))
@@ -1442,14 +1445,24 @@ abort:return 1 ; } +static int mdp_major =0 ;static struct kobject *md_probe (dev_t dev,int *part,void *data) {static DECLARE_MUTEX (disks_sem); -int unit = *part; -mddev_t *mddev =mddev_find (unit); +int unit; +int minor; +mddev_t *mddev;struct gendisk *disk; +if (data) { + unit = *part >> MdpMinorShift; + minor = unit << MdpMinorShift; + unit =-1 -unit; + }else + minor = unit = *part; + + mddev =mddev_find (unit);if (!mddev)return NULL ;
@@ -1459,15 +1472,18 @@ static struct kobject *md_probe(dev_t demddev_put (mddev);return NULL ; } - disk =alloc_disk (1 ); + disk =alloc_disk (data ? (1 <<MdpMinorShift) :1 );if (!disk) {up (&disks_sem);mddev_put (mddev);return NULL ; } - disk->major =MD_MAJOR ; - disk->first_minor =mdidx (mddev); -sprintf (disk->disk_name,"md%d" ,mdidx (mddev)); + disk->major = data ? mdp_major :MD_MAJOR ; + disk->first_minor = minor; +if (data) +sprintf (disk->disk_name,"md_d%d" , minor >> MdpMinorShift); +else +sprintf (disk->disk_name,"md%d" , minor); disk->fops = &md_fops; disk->private_data = mddev; disk->queue = mddev->queue;
@@ -1495,6 +1511,7 @@ static int do_md_run(mddev_t * mddev)struct list_head *tmp;mdk_rdev_t *rdev;struct gendisk *disk; +struct block_device *bdev;char b[BDEVNAME_SIZE ];int unit;
@@ -1636,6 +1653,19 @@ static int do_md_run(mddev_t * mddev) mddev->queue->queuedata = mddev; mddev->queue->make_request_fn = mddev->pers->make_request; + bdev =bdget_disk (disk,0 ); +if (bdev) { +/* We need to reread the partition table, and that requires +* setting the size of the blockdev inode suitably. +* This code should really be export from block_dev.c, +* but for now it is copied from dm.c:__set_size +*/ +down (&bdev->bd_inode->i_sem); +i_size_write (bdev->bd_inode, (loff_t )mddev->array_size <<10 ); +up (&bdev->bd_inode->i_sem); +ioctl_by_bdev (bdev,BLKRRPART ,0 ); +bdput (bdev); + }return 0 ; }
@@ -2366,7 +2396,6 @@ static int md_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg) { char b[BDEVNAME_SIZE]; -unsigned int minor =iminor (inode);int err =0 ;struct hd_geometry *loc = (struct hd_geometry *) arg;mddev_t *mddev =NULL ;
@@ -2374,11 +2403,6 @@ static int md_ioctl(struct inode *inode,if (!capable (CAP_SYS_ADMIN ))return -EACCES ; -if (minor >=MAX_MD_DEVS ) { -MD_BUG (); -return -EINVAL ; - } -/* * Commands dealing with the RAID driver but not any * particular array:
@@ -3497,15 +3521,23 @@ int __init md_init(void)if (register_blkdev (MAJOR_NR ,"md" ))return -1 ; - +if ((mdp_major=register_blkdev (0 ,"mdp" ))<=0 ) { +unregister_blkdev (MAJOR_NR ,"md" ); +return -1 ; + }devfs_mk_dir ("md" );blk_register_region (MKDEV (MAJOR_NR ,0 ),MAX_MD_DEVS ,THIS_MODULE , md_probe,NULL ,NULL ); +blk_register_region (MKDEV (mdp_major,0 ),MAX_MD_DEVS <<MdpMinorShift,THIS_MODULE , + md_probe,NULL , (void *)1 );for (minor=0 ; minor <MAX_MD_DEVS ; ++minor) {devfs_mk_bdev (MKDEV (MAJOR_NR , minor),S_IFBLK |S_IRUSR |S_IWUSR ,"md/%d" , minor); +devfs_mk_bdev (MKDEV (mdp_major, minor<<MdpMinorShift), +S_IFBLK |S_IRUSR |S_IWUSR , +"md/d%d" , minor); }register_reboot_notifier (&md_notifier);
@@ -3568,11 +3600,15 @@ static __exit void md_exit(void)struct list_head *tmp;int i;blk_unregister_region (MKDEV (MAJOR_NR ,0 ),MAX_MD_DEVS ); -for (i=0 ; i <MAX_MD_DEVS ; i++) +blk_unregister_region (MKDEV (mdp_major,0 ),MAX_MD_DEVS << MdpMinorShift); +for (i=0 ; i <MAX_MD_DEVS ; i++) {devfs_remove ("md/%d" , i); +devfs_remove ("md/d%d" , i); + }devfs_remove ("md" );unregister_blkdev (MAJOR_NR ,"md" ); +unregister_blkdev (mdp_major,"mdp" );unregister_reboot_notifier (&md_notifier);unregister_sysctl_table (raid_table_header);remove_proc_entry ("mdstat" ,NULL );
PATCH 1/1 md - 7 of 7 - Make sure md devices appear in /proc/partitions
In reply to NeilBrownAs they are not partitionable, they don't (how wierd).
----------- Diffstat output ------------
./drivers/block/genhd.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-)
drivers/block/genhd.c renamed from drivers/block/genhd.c~current~ +8 -2
@@ -261,8 +261,14 @@ static int show_partition(struct seq_filseq_puts (part,"major minor #blocks name\n\n" );/* Don't show non-partitionable devices or empty devices */ -if (!get_capacity (sgp) || sgp->minors ==1 ) -return 0 ; +/* ... but do show 'md' devices. As it isn't clear *why* +* non-partitionable devices are excluded, and as I definately +* want md device to be included, the follow ugly code is +* needed - neilb Jan2004 +*/ +if (sgp->disk_name[0 ] !='m' || sgp->disk_name[1 ] !='d' ) +if (!get_capacity (sgp) || sgp->minors ==1 ) +return 0 ;/* show the full disk and all non-0 size partitions of it */ seq_printf(part, "%4d %4d %10llu %s\n",