Introduction
PATCH 1/1 Introduction
8 patches for md/raid in 2.6 follow.
The first replaces
md-identify-raid-rcu-protected-pointer.patch
which has some minor issues.
2 and 3 fix problems in previous patches identified by some kindly code reviewers.
Thanks,
NeilBrown
[PATCH md 001 of 8] Provide proper rcu_dereference / rcu_assign_pointer annotations in md [PATCH md 002 of 8] Fix ref-counting problems with kobjects in md
[PATCH md 003 of 8] Minor MD fixes
[PATCH md 004 of 8] Change raid5 sysfs attribute to not create a new directory. [PATCH md 005 of 8] Improvements to raid5 handling of read errors
[PATCH md 006 of 8] Convert 'faulty' and 'in_sync' fields to bits in 'flags' field. [PATCH md 007 of 8] Make md on-disk bitmaps not host-endian
[PATCH md 008 of 8] Support BIO_RW_BARRIER for md/raid1.
PATCH 1/1 Provide proper rcu_dereference / rcu_assign_pointer annotations in md
### Diffstat output
./drivers/md/multipath.c | 8 ++++---- ./drivers/md/raid1.c | 20 ++++++++++---------- ./drivers/md/raid10.c | 30 ++++++++++++++++-------------- ./drivers/md/raid5.c | 8 ++++---- ./drivers/md/raid6main.c | 8 ++++---- 5 files changed, 38 insertions(+), 36 deletions(-)
drivers/md/multipath.c renamed from drivers/md/multipath.c~current~ +4 -4
@@ -63,7 +63,7 @@ static int multipath_map (multipath_confrcu_read_lock ();for (i =0 ; i < disks; i++) { -mdk_rdev_t *rdev = conf->multipaths[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->multipaths[i].rdev);if (rdev && rdev->in_sync) {atomic_inc (&rdev->nr_pending);rcu_read_unlock ();
@@ -139,7 +139,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) { -mdk_rdev_t *rdev = conf->multipaths[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->multipaths[i].rdev);if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);
@@ -228,7 +228,7 @@ static int multipath_issue_flush(requestrcu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) { -mdk_rdev_t *rdev = conf->multipaths[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->multipaths[i].rdev);if (rdev && !rdev->faulty) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -335,7 +335,7 @@ static int multipath_add_disk(mddev_t *m conf->working_disks++; rdev->raid_disk = path; rdev->in_sync =1 ; - p->rdev = rdev; +rcu_assign_pointer (p->rdev, rdev); found =1 ; }
drivers/md/raid1.c renamed from drivers/md/raid1.c~current~ +10 -10
@@ -416,10 +416,10 @@ static int read_balance(conf_t *conf, r1/* Choose the first operation device, for consistancy */ new_disk =0 ; -for (rdev = conf->mirrors[new_disk].rdev; +for (rdev =rcu_dereference (conf->mirrors[new_disk].rdev); !rdev || !rdev->in_sync ||test_bit (WriteMostly, &rdev->flags); - rdev = conf->mirrors[++new_disk].rdev) { + rdev =rcu_dereference (conf->mirrors[++new_disk].rdev)) {if (rdev && rdev->in_sync) wonly_disk = new_disk;
@@ -434,10 +434,10 @@ static int read_balance(conf_t *conf, r1/* make sure the disk is operational */ -for (rdev = conf->mirrors[new_disk].rdev; +for (rdev =rcu_dereference (conf->mirrors[new_disk].rdev); !rdev || !rdev->in_sync ||test_bit (WriteMostly, &rdev->flags); - rdev = conf->mirrors[new_disk].rdev) { + rdev =rcu_dereference (conf->mirrors[new_disk].rdev)) {if (rdev && rdev->in_sync) wonly_disk = new_disk;
@@ -474,7 +474,7 @@ static int read_balance(conf_t *conf, r1 disk = conf->raid_disks; disk--; - rdev = conf->mirrors[disk].rdev; + rdev =rcu_dereference (conf->mirrors[disk].rdev); if (!rdev || !rdev->in_sync ||
@@ -496,7 +496,7 @@ static int read_balance(conf_t *conf, r1if (new_disk >=0 ) { - rdev = conf->mirrors[new_disk].rdev; + rdev =rcu_dereference (conf->mirrors[new_disk].rdev);if (!rdev) goto retry;atomic_inc (&rdev->nr_pending);
@@ -522,7 +522,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) { -mdk_rdev_t *rdev = conf->mirrors[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->mirrors[i].rdev);if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);
@@ -556,7 +556,7 @@ static int raid1_issue_flush(request_quercu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) { -mdk_rdev_t *rdev = conf->mirrors[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->mirrors[i].rdev);if (rdev && !rdev->faulty) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -732,7 +732,7 @@ static int make_request(request_queue_t#endif rcu_read_lock ();for (i =0 ; i < disks; i++) { -if ((rdev=conf->mirrors[i].rdev) !=NULL && +if ((rdev=rcu_dereference (conf->mirrors[i].rdev)) !=NULL && !rdev->faulty) {atomic_inc (&rdev->nr_pending);if (rdev->faulty) {
@@ -958,7 +958,7 @@ static int raid1_add_disk(mddev_t *mddev found =1 ;if (rdev->saved_raid_disk != mirror) conf->fullsync =1 ; - p->rdev = rdev; +rcu_assign_pointer (p->rdev, rdev);break ; }
drivers/md/raid10.c renamed from drivers/md/raid10.c~current~ +16 -14
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r1int disk, slot, nslot;const int sectors = r10_bio->sectors;sector_t new_distance, current_distance; +mdk_rdev_t *rdev;raid10_find_phys (conf, r10_bio);rcu_read_lock ();
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r1 slot =0 ; disk = r10_bio->devs[slot].devnum; -while (!conf->mirrors[disk].rdev || - !conf->mirrors[disk].rdev->in_sync) { +while ((rdev =rcu_dereference (conf->mirrors[disk].rdev)) ==NULL || + !rdev->in_sync) { slot++;if (slot == conf->copies) { slot =0 ;
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r1/* make sure the disk is operational */ slot =0 ; disk = r10_bio->devs[slot].devnum; -while (!conf->mirrors[disk].rdev || - !conf->mirrors[disk].rdev->in_sync) { +while ((rdev=rcu_dereference (conf->mirrors[disk].rdev)) ==NULL || + !rdev->in_sync) { slot ++;if (slot == conf->copies) { disk =-1 ;
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r1int ndisk = r10_bio->devs[nslot].devnum; -if (!conf->mirrors[ndisk].rdev || - !conf->mirrors[ndisk].rdev->in_sync) +if ((rdev=rcu_dereference (conf->mirrors[ndisk].rdev)) ==NULL || + !rdev->in_sync)continue ; -if (!atomic_read (&conf->mirrors[ndisk].rdev->nr_pending)) { +if (!atomic_read (&rdev->nr_pending)) { disk = ndisk; slot = nslot;break ;
@@ -569,7 +570,7 @@ rb_out: r10_bio->read_slot = slot;/* conf->next_seq_sect = this_sector + sectors;*/ -if (disk >=0 && conf->mirrors[disk].rdev) +if (disk >=0 && (rdev=rcu_dereference (conf->mirrors[disk].rdev))!=NULL )atomic_inc (&conf->mirrors[disk].rdev->nr_pending);rcu_read_unlock ();
@@ -583,7 +584,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) { -mdk_rdev_t *rdev = conf->mirrors[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->mirrors[i].rdev);if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);
@@ -614,7 +615,7 @@ static int raid10_issue_flush(request_qurcu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) { -mdk_rdev_t *rdev = conf->mirrors[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->mirrors[i].rdev);if (rdev && !rdev->faulty) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -772,9 +773,10 @@ static int make_request(request_queue_trcu_read_lock ();for (i =0 ; i < conf->copies; i++) {int d = r10_bio->devs[i].devnum; -if (conf->mirrors[d].rdev && - !conf->mirrors[d].rdev->faulty) { -atomic_inc (&conf->mirrors[d].rdev->nr_pending); +mdk_rdev_t *rdev =rcu_dereference (conf->mirrors[d].rdev); +if (rdev && + !rdev->faulty) { +atomic_inc (&rdev->nr_pending); r10_bio->devs[i].bio = bio; }else r10_bio->devs[i].bio =NULL ;
@@ -984,7 +986,7 @@ static int raid10_add_disk(mddev_t *mdde p->head_position =0 ; rdev->raid_disk = mirror; found =1 ; - p->rdev = rdev; +rcu_assign_pointer (p->rdev, rdev);break ; }
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +4 -4
@@ -1374,7 +1374,7 @@ static void handle_stripe(struct stripe_ bi->bi_end_io = raid5_end_read_request;rcu_read_lock (); - rdev = conf->disks[i].rdev; + rdev =rcu_dereference (conf->disks[i].rdev);if (rdev && rdev->faulty) rdev =NULL ;if (rdev)
@@ -1448,7 +1448,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) { -mdk_rdev_t *rdev = conf->disks[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev);if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);
@@ -1493,7 +1493,7 @@ static int raid5_issue_flush(request_quercu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) { -mdk_rdev_t *rdev = conf->disks[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev);if (rdev && !rdev->faulty) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -2169,7 +2169,7 @@ static int raid5_add_disk(mddev_t *mddev found =1 ;if (rdev->saved_raid_disk != disk) conf->fullsync =1 ; - p->rdev = rdev; +rcu_assign_pointer (p->rdev, rdev);break ; }print_raid5_conf (conf);
drivers/md/raid6main.c renamed from drivers/md/raid6main.c~current~ +4 -4
@@ -1464,7 +1464,7 @@ static void handle_stripe(struct stripe_ bi->bi_end_io = raid6_end_read_request;rcu_read_lock (); - rdev = conf->disks[i].rdev; + rdev =rcu_dereference (conf->disks[i].rdev);if (rdev && rdev->faulty) rdev =NULL ;if (rdev)
@@ -1538,7 +1538,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) { -mdk_rdev_t *rdev = conf->disks[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev);if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);
@@ -1583,7 +1583,7 @@ static int raid6_issue_flush(request_quercu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) { -mdk_rdev_t *rdev = conf->disks[i].rdev; +mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev);if (rdev && !rdev->faulty) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -2158,7 +2158,7 @@ static int raid6_add_disk(mddev_t *mddev found =1 ;if (rdev->saved_raid_disk != disk) conf->fullsync =1 ; - p->rdev = rdev; +rcu_assign_pointer (p->rdev, rdev);break ; }print_raid6_conf (conf);
PATCH 1/1 Fix ref-counting problems with kobjects in md
In reply to NeilBrownThanks Greg.
### Diffstat output
./drivers/md/md.c | 8 ++++++-- ./drivers/md/raid5.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +6 -2
@@ -805,7 +805,11 @@ static void super_90_sync(mddev_t *mddevif (fixdesc & (1 <<rdev2->desc_nr)) {snprintf (rdev2->kobj.name,KOBJ_NAME_LEN ,"dev%d" , rdev2->desc_nr); +/* kobject_add gets a ref on the parent, so +* we have to drop the one we already have +*/ kobject_add (&rdev2->kobj); +kobject_put (rdev->kobj.parent);sysfs_create_link (&rdev2->kobj, &rdev2->bdev->bd_disk->kobj,"block" );
@@ -1178,7 +1182,7 @@ static int bind_rdev_to_array(mdk_rdev_t rdev->kobj.k_name =NULL ;snprintf (rdev->kobj.name,KOBJ_NAME_LEN ,"dev%d" , rdev->desc_nr); - rdev->kobj.parent =kobject_get (&mddev->kobj); + rdev->kobj.parent = &mddev->kobj;kobject_add (&rdev->kobj);sysfs_create_link (&rdev->kobj, &rdev->bdev->bd_disk->kobj,"block" );
@@ -1864,7 +1868,7 @@ static struct kobject *md_probe(dev_t deadd_disk (disk); mddev->gendisk = disk;up (&disks_sem); - mddev->kobj.parent =kobject_get (&disk->kobj); + mddev->kobj.parent = &disk->kobj; mddev->kobj.k_name =NULL ;snprintf (mddev->kobj.name,KOBJ_NAME_LEN ,"%s" ,"md" ); mddev->kobj.ktype = &md_ktype;
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +1 -1
@@ -1979,7 +1979,7 @@ memory = conf->max_nr_stripes * (sizeof( }/* Ok, everything is just fine now */ - conf->kobj.parent =kobject_get (&mddev->kobj); + conf->kobj.parent = &mddev->kobj;strcpy (conf->kobj.name,"raid5" ); conf->kobj.ktype = &raid5_ktype;kobject_register (&conf->kobj);
PATCH 1/1 Minor MD fixes
In reply to NeilBrown1/ Use reduce stack usage, because 'gcc' apparently doesn't overlay
different variables that are in separate scopes...
2/ Use test_bit instead of ( .. & 1<< ..) which in this case is buggy.
Thanks to Andrew Morton
### Diffstat output
./drivers/md/md.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +7 -7
@@ -698,6 +698,7 @@ static void super_90_sync(mddev_t *mddevstruct list_head *tmp;mdk_rdev_t *rdev2;int next_spare = mddev->raid_disks; +char nm[20 ];/* make rdev->sb match mddev data.. *
@@ -768,7 +769,6 @@ static void super_90_sync(mddev_t *mddev fixdesc |= (1 << desc_nr); rdev2->desc_nr = desc_nr;if (rdev2->raid_disk >=0 ) { -char nm[20 ];sprintf (nm,"rd%d" , rdev2->raid_disk);sysfs_remove_link (&mddev->kobj, nm); }
@@ -814,7 +814,6 @@ static void super_90_sync(mddev_t *mddev &rdev2->bdev->bd_disk->kobj, "block");if (rdev2->raid_disk >=0 ) { -char nm[20 ];sprintf (nm,"rd%d" , rdev2->raid_disk);sysfs_create_link (&mddev->kobj, &rdev2->kobj, nm);
@@ -1722,9 +1721,9 @@ static ssize_t md_show_scan(mddev_t *mddev, char *page) {char *type ="none" ; -if (mddev->recovery & - ((1 <<MD_RECOVERY_RUNNING ) || (1 <<MD_RECOVERY_NEEDED ))) { -if (mddev->recovery & (1 <<MD_RECOVERY_SYNC )) { +if (test_bit (MD_RECOVERY_RUNNING , &mddev->recovery) || +test_bit (MD_RECOVERY_NEEDED , &mddev->recovery)) { +if (test_bit (MD_RECOVERY_SYNC , &mddev->recovery)) {if (!test_bit (MD_RECOVERY_REQUESTED , &mddev->recovery)) type ="resync" ;else if (test_bit (MD_RECOVERY_CHECK , &mddev->recovery))
@@ -1741,8 +1740,9 @@ static ssize_t md_store_scan(mddev_t *mddev, const char *page, size_t len) {int canscan=0 ; -if (mddev->recovery & - ((1 <<MD_RECOVERY_RUNNING ) || (1 <<MD_RECOVERY_NEEDED ))) + +if (test_bit (MD_RECOVERY_RUNNING , &mddev->recovery) || +test_bit (MD_RECOVERY_NEEDED , &mddev->recovery))return -EBUSY ;down (&mddev->reconfig_sem);if (mddev->pers && mddev->pers->sync_request)
PATCH 1/1 Change raid5 sysfs attribute to not create a new directory.
In reply to NeilBrownThere isn't really a need for raid5 attributes to be an a subdirectory, so this patch moves them from
/sys/block/mdX/md/raid5/attribute
to
/sys/block/mdX/md/attribute
This suggests that all md personalities should co-operate about namespace usage, but that shouldn't be a problem.
### Diffstat output
./drivers/md/md.c | 6 --- ./drivers/md/raid5.c | 72 ++++++++----------------------------------- ./include/linux/raid/md_k.h | 7 ++++ ./include/linux/raid/raid5.h | 1 4 files changed, 22 insertions(+), 64 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +0 -6
@@ -1683,12 +1683,6 @@ static void analyze_sbs(mddev_t * mddev) } -struct md_sysfs_entry { -struct attribute attr; -ssize_t (*show)(mddev_t *,char *); -ssize_t (*store)(mddev_t *,const char *,size_t ); -}; -static ssize_t md_show_level (mddev_t *mddev,char *page) {
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +15 -57
121 lines not on this page · raw message
include/linux/raid/md_k.h renamed from include/linux/raid/md_k.h~current~ +7 -0
@@ -282,6 +282,13 @@ struct mdk_personality_s }; +struct md_sysfs_entry { +struct attribute attr; +ssize_t (*show)(mddev_t *,char *); +ssize_t (*store)(mddev_t *,const char *,size_t ); +}; + +static inline char *mdname (mddev_t * mddev) {return mddev->gendisk ? mddev->gendisk->disk_name :"mdX" ;
include/linux/raid/raid5.h renamed from include/linux/raid/raid5.h~current~ +0 -1
@@ -228,7 +228,6 @@ struct raid5_private_data {* Cleared when a sync completes. */ -struct kobject kobj;/* * Free stripes pool */
PATCH 1/1 Improvements to raid5 handling of read errors
In reply to NeilBrownTwo refinements to the 'attempt-overwrite-on-read-error' mechanism. 1/ If the array is read-only, don't attempt an over-write. 2/ If there are more than max_nr_stripes read errors on a device with
no success, fail the drive. This will make sure a dead drive will be eventually kicked even when we aren't trying to rewrite (which would normally kick a dead drive more quickly.
### Diffstat output
./drivers/md/md.c | 1 + ./drivers/md/raid5.c | 25 +++++++++++++++++-------- ./include/linux/raid/md_k.h | 3 +++ 3 files changed, 21 insertions(+), 8 deletions(-)
drivers/md/md.c renamed from drivers/md/md.c~current~ +1 -0
@@ -1582,6 +1582,7 @@ static mdk_rdev_t *md_import_device(dev_ rdev->in_sync =0 ; rdev->data_offset =0 ;atomic_set (&rdev->nr_pending,0 ); +atomic_set (&rdev->read_errors,0 ); size = rdev->bdev->bd_inode->i_size >>BLOCK_SIZE_BITS ;if (!size) {
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +17 -8
@@ -420,21 +420,29 @@ static int raid5_end_read_request(structclear_bit (R5_ReadError, &sh->dev[i].flags);clear_bit (R5_ReWrite, &sh->dev[i].flags); } +if (atomic_read (&conf->disks[i].rdev->read_errors)) +atomic_set (&conf->disks[i].rdev->read_errors,0 ); }else { +int retry =0 ;clear_bit (R5_UPTODATE , &sh->dev[i].flags); -if (conf->mddev->degraded) { +atomic_inc (&conf->disks[i].rdev->read_errors); +if (conf->mddev->degraded)printk ("R5: read error not correctable.\n" ); -clear_bit (R5_ReadError, &sh->dev[i].flags); -clear_bit (R5_ReWrite, &sh->dev[i].flags); -md_error (conf->mddev, conf->disks[i].rdev); - }else if (test_bit (R5_ReWrite, &sh->dev[i].flags)) { +else if (test_bit (R5_ReWrite, &sh->dev[i].flags))/* Oh, no!!! */ printk ("R5: read error NOT corrected!!\n" ); +else if (atomic_read (&conf->disks[i].rdev->read_errors) + > conf->max_nr_stripes) +printk ("raid5: Too many read errors, failing device.\n" ); +else + retry =1 ; +if (retry) +set_bit (R5_ReadError, &sh->dev[i].flags); +else {clear_bit (R5_ReadError, &sh->dev[i].flags);clear_bit (R5_ReWrite, &sh->dev[i].flags);md_error (conf->mddev, conf->disks[i].rdev); - }else -set_bit (R5_ReadError, &sh->dev[i].flags); + } }rdev_dec_pending (conf->disks[i].rdev, conf->mddev);#if 0
@@ -1328,7 +1336,8 @@ static void handle_stripe(struct stripe_/* If the failed drive is just a ReadError, then we might need to progress * the repair/check process */ -if (failed ==1 &&test_bit (R5_ReadError, &sh->dev[failed_num].flags) +if (failed ==1 && ! conf->mddev->ro && +test_bit (R5_ReadError, &sh->dev[failed_num].flags) && !test_bit (R5_LOCKED , &sh->dev[failed_num].flags) &&test_bit (R5_UPTODATE , &sh->dev[failed_num].flags) ) {
include/linux/raid/md_k.h renamed from include/linux/raid/md_k.h~current~ +3 -0
@@ -134,6 +134,9 @@ struct mdk_rdev_s* only maintained for arrays that * support hot removal */ +atomic_t read_errors;/* number of consecutive read errors that +* we have tried to ignore. +*/ };typedef struct mdk_personality_s mdk_personality_t ;
PATCH 1/1 Convert 'faulty' and 'in_sync' fields to bits in 'flags' field.
In reply to NeilBrownThis has the advantage of removing the confusion caused by 'rdev_t' and 'mddev_t' both having 'in_sync' fields.
### Diffstat output
./drivers/md/bitmap.c | 6 +- ./drivers/md/md.c | 92 +++++++++++++++++++++----------------------- ./drivers/md/multipath.c | 23 +++++------ ./drivers/md/raid1.c | 52 ++++++++++++------------ ./drivers/md/raid10.c | 41 ++++++++++--------- ./drivers/md/raid5.c | 36 ++++++++--------- ./drivers/md/raid6main.c | 32 +++++++-------- ./include/linux/raid/md_k.h | 8 +-- 8 files changed, 146 insertions(+), 144 deletions(-)
drivers/md/bitmap.c renamed from drivers/md/bitmap.c~current~ +4 -2
@@ -272,7 +272,8 @@ static struct page *read_sb_page(mddev_treturn ERR_PTR (-ENOMEM ); ITERATE_RDEV(mddev, rdev, tmp) { -if (! rdev->in_sync || rdev->faulty) +if (!test_bit (In_sync, &rdev->flags) + ||test_bit (Faulty, &rdev->flags))continue ; target = (rdev->sb_offset <<1 ) + offset + index * (PAGE_SIZE /512 );
@@ -292,7 +293,8 @@ static int write_sb_page(mddev_t *mddev,struct list_head *tmp; ITERATE_RDEV(mddev, rdev, tmp) -if (rdev->in_sync && !rdev->faulty) +if (test_bit (In_sync, &rdev->flags) + && !test_bit (Faulty, &rdev->flags)) md_super_write(mddev, rdev, (rdev->sb_offset<<1) + offset + page->index * (PAGE_SIZE/512),
drivers/md/md.c renamed from drivers/md/md.c~current~ +45 -47
288 lines not on this page · raw message
drivers/md/multipath.c renamed from drivers/md/multipath.c~current~ +12 -11
@@ -64,7 +64,7 @@ static int multipath_map (multipath_confrcu_read_lock ();for (i =0 ; i < disks; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->multipaths[i].rdev); -if (rdev && rdev->in_sync) { +if (rdev &&test_bit (In_sync, &rdev->flags)) {atomic_inc (&rdev->nr_pending);rcu_read_unlock ();return i;
@@ -140,7 +140,8 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->multipaths[i].rdev); -if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) { +if (rdev && !test_bit (Faulty, &rdev->flags) + &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);atomic_inc (&rdev->nr_pending);
@@ -215,7 +216,7 @@ static void multipath_status (struct seqfor (i =0 ; i < conf->raid_disks; i++)seq_printf (seq,"%s" , conf->multipaths[i].rdev && - conf->multipaths[i].rdev->in_sync ?"U" :"_" ); +test_bit (In_sync, &conf->multipaths[i].rdev->flags) ?"U" :"_" );seq_printf (seq,"]" ); }
@@ -229,7 +230,7 @@ static int multipath_issue_flush(requestrcu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->multipaths[i].rdev); -if (rdev && !rdev->faulty) { +if (rdev && !test_bit (Faulty, &rdev->flags)) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -269,10 +270,10 @@ static void multipath_error (mddev_t *md/* * Mark disk as unusable */ -if (!rdev->faulty) { +if (!test_bit (Faulty, &rdev->flags)) {char b[BDEVNAME_SIZE ]; - rdev->in_sync =0 ; - rdev->faulty =1 ; +clear_bit (In_sync, &rdev->flags); +set_bit (Faulty, &rdev->flags); mddev->sb_dirty =1 ; conf->working_disks--; printk(KERN_ALERT "multipath: IO failure on %s,"
@@ -302,7 +303,7 @@ static void print_multipath_conf (multip tmp = conf->multipaths + i;if (tmp->rdev)printk (" disk%d, o:%d, dev:%s\n" , - i,!tmp->rdev->faulty, + i,!test_bit (Faulty, &tmp->rdev->flags),bdevname (tmp->rdev->bdev,b)); } }
@@ -334,7 +335,7 @@ static int multipath_add_disk(mddev_t *m conf->working_disks++; rdev->raid_disk = path; - rdev->in_sync =1 ; +set_bit (In_sync, &rdev->flags);rcu_assign_pointer (p->rdev, rdev); found =1 ; }
@@ -354,7 +355,7 @@ static int multipath_remove_disk(mddev_t rdev = p->rdev;if (rdev) { -if (rdev->in_sync || +if (test_bit (In_sync, &rdev->flags) ||atomic_read (&rdev->nr_pending)) {printk (KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n" , number); err = -EBUSY ;
@@ -486,7 +487,7 @@ static int multipath_run (mddev_t *mddev mddev->queue->max_sectors > (PAGE_SIZE>>9))blk_queue_max_sectors (mddev->queue,PAGE_SIZE >>9 ); -if (!rdev->faulty) +if (!test_bit (Faulty, &rdev->flags)) conf->working_disks++; }
drivers/md/raid1.c renamed from drivers/md/raid1.c~current~ +26 -26
174 lines not on this page · raw message
drivers/md/raid10.c renamed from drivers/md/raid10.c~current~ +21 -20
145 lines not on this page · raw message
drivers/md/raid5.c renamed from drivers/md/raid5.c~current~ +18 -18
@@ -525,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdraid5_conf_t *conf = (raid5_conf_t *) mddev->private;PRINTK ("raid5: error called\n" ); -if (!rdev->faulty) { +if (!test_bit (Faulty, &rdev->flags)) { mddev->sb_dirty =1 ; -if (rdev->in_sync) { +if (test_bit (In_sync, &rdev->flags)) { conf->working_disks--; mddev->degraded++; conf->failed_disks++; - rdev->in_sync =0 ; +clear_bit (In_sync, &rdev->flags);/* * if recovery was running, make sure it aborts. */ set_bit (MD_RECOVERY_ERR , &mddev->recovery); } - rdev->faulty =1 ; +set_bit (Faulty, &rdev->flags); printk (KERN_ALERT "raid5: Disk failure on %s, disabling device." " Operation continuing on %d devices\n",
@@ -1003,12 +1003,12 @@ static void handle_stripe(struct stripe_ }if (dev->written) written++; rdev = conf->disks[i].rdev;/* FIXME, should I be looking rdev */ -if (!rdev || !rdev->in_sync) { +if (!rdev || !test_bit (In_sync, &rdev->flags)) {/* The ReadError flag wil just be confusing now */ clear_bit (R5_ReadError, &dev->flags);clear_bit (R5_ReWrite, &dev->flags); } -if (!rdev || !rdev->in_sync +if (!rdev || !test_bit (In_sync, &rdev->flags) ||test_bit (R5_ReadError, &dev->flags)) { failed++; failed_num = i;
@@ -1027,7 +1027,7 @@ static void handle_stripe(struct stripe_if (test_bit (R5_ReadError, &sh->dev[i].flags)) {mdk_rdev_t *rdev = conf->disks[i].rdev; -if (rdev && rdev->in_sync) +if (rdev &&test_bit (In_sync, &rdev->flags))/* multiple read failures in one stripe */ md_error (conf->mddev, rdev); }
@@ -1384,7 +1384,7 @@ static void handle_stripe(struct stripe_rcu_read_lock (); rdev =rcu_dereference (conf->disks[i].rdev); -if (rdev && rdev->faulty) +if (rdev &&test_bit (Faulty, &rdev->flags)) rdev =NULL ;if (rdev)atomic_inc (&rdev->nr_pending);
@@ -1458,7 +1458,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev); -if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) { +if (rdev && !test_bit (Faulty, &rdev->flags) &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);atomic_inc (&rdev->nr_pending);
@@ -1503,7 +1503,7 @@ static int raid5_issue_flush(request_quercu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev); -if (rdev && !rdev->faulty) { +if (rdev && !test_bit (Faulty, &rdev->flags)) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -1854,7 +1854,7 @@ static int run(mddev_t *mddev) disk->rdev = rdev; -if (rdev->in_sync) { +if (test_bit (In_sync, &rdev->flags)) {char b[BDEVNAME_SIZE ]; printk(KERN_INFO "raid5: device %s operational as raid" " disk %d\n", bdevname(rdev->bdev,b),
@@ -2033,7 +2033,7 @@ static void status (struct seq_file *seqfor (i =0 ; i < conf->raid_disks; i++)seq_printf (seq,"%s" , conf->disks[i].rdev && - conf->disks[i].rdev->in_sync ?"U" :"_" ); +test_bit (In_sync, &conf->disks[i].rdev->flags) ?"U" :"_" );seq_printf (seq,"]" );#if RAID5_DEBUG #define D (x) \
@@ -2060,7 +2060,7 @@ static void print_raid5_conf (raid5_conf tmp = conf->disks + i;if (tmp->rdev)printk (" disk %d, o:%d, dev:%s\n" , - i, !tmp->rdev->faulty, + i, !test_bit (Faulty, &tmp->rdev->flags),bdevname (tmp->rdev->bdev,b)); } }
@@ -2074,12 +2074,12 @@ static int raid5_spare_active(mddev_t *mfor (i =0 ; i < conf->raid_disks; i++) { tmp = conf->disks + i;if (tmp->rdev - && !tmp->rdev->faulty - && !tmp->rdev->in_sync) { + && !test_bit (Faulty, &tmp->rdev->flags) + && !test_bit (In_sync, &tmp->rdev->flags)) { mddev->degraded--; conf->failed_disks--; conf->working_disks++; - tmp->rdev->in_sync =1 ; +set_bit (In_sync, &tmp->rdev->flags); } }print_raid5_conf (conf);
@@ -2096,7 +2096,7 @@ static int raid5_remove_disk(mddev_t *mdprint_raid5_conf (conf); rdev = p->rdev;if (rdev) { -if (rdev->in_sync || +if (test_bit (In_sync, &rdev->flags) ||atomic_read (&rdev->nr_pending)) { err = -EBUSY ; goto abort;
@@ -2131,7 +2131,7 @@ static int raid5_add_disk(mddev_t *mddev*/ for (disk=0 ; disk < mddev->raid_disks; disk++)if ((p=conf->disks + disk)->rdev ==NULL ) { - rdev->in_sync =0 ; +clear_bit (In_sync, &rdev->flags); rdev->raid_disk = disk; found =1 ;if (rdev->saved_raid_disk != disk)
drivers/md/raid6main.c renamed from drivers/md/raid6main.c~current~ +16 -16
@@ -507,19 +507,19 @@ static void error(mddev_t *mddev, mdk_rdraid6_conf_t *conf = (raid6_conf_t *) mddev->private;PRINTK ("raid6: error called\n" ); -if (!rdev->faulty) { +if (!test_bit (Faulty, &rdev->flags)) { mddev->sb_dirty =1 ; -if (rdev->in_sync) { +if (test_bit (In_sync, &rdev->flags)) { conf->working_disks--; mddev->degraded++; conf->failed_disks++; - rdev->in_sync =0 ; +clear_bit (In_sync, &rdev->flags);/* * if recovery was running, make sure it aborts. */ set_bit (MD_RECOVERY_ERR , &mddev->recovery); } - rdev->faulty =1 ; +set_bit (Faulty, &rdev->flags); printk (KERN_ALERT "raid6: Disk failure on %s, disabling device." " Operation continuing on %d devices\n",
@@ -1071,7 +1071,7 @@ static void handle_stripe(struct stripe_ }if (dev->written) written++; rdev = conf->disks[i].rdev;/* FIXME, should I be looking rdev */ -if (!rdev || !rdev->in_sync) { +if (!rdev || !test_bit (In_sync, &rdev->flags)) {if ( failed <2 ) failed_num[failed] = i; failed++;
@@ -1465,7 +1465,7 @@ static void handle_stripe(struct stripe_rcu_read_lock (); rdev =rcu_dereference (conf->disks[i].rdev); -if (rdev && rdev->faulty) +if (rdev &&test_bit (Faulty, &rdev->flags)) rdev =NULL ;if (rdev)atomic_inc (&rdev->nr_pending);
@@ -1539,7 +1539,7 @@ static void unplug_slaves(mddev_t *mddevrcu_read_lock ();for (i=0 ; i<mddev->raid_disks; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev); -if (rdev && !rdev->faulty &&atomic_read (&rdev->nr_pending)) { +if (rdev && !test_bit (Faulty, &rdev->flags) &&atomic_read (&rdev->nr_pending)) {request_queue_t *r_queue =bdev_get_queue (rdev->bdev);atomic_inc (&rdev->nr_pending);
@@ -1584,7 +1584,7 @@ static int raid6_issue_flush(request_quercu_read_lock ();for (i=0 ; i<mddev->raid_disks && ret ==0 ; i++) {mdk_rdev_t *rdev =rcu_dereference (conf->disks[i].rdev); -if (rdev && !rdev->faulty) { +if (rdev && !test_bit (Faulty, &rdev->flags)) {struct block_device *bdev = rdev->bdev;request_queue_t *r_queue =bdev_get_queue (bdev);
@@ -1872,7 +1872,7 @@ static int run(mddev_t *mddev) disk->rdev = rdev; -if (rdev->in_sync) { +if (test_bit (In_sync, &rdev->flags)) {char b[BDEVNAME_SIZE ]; printk(KERN_INFO "raid6: device %s operational as raid" " disk %d\n", bdevname(rdev->bdev,b),
@@ -2056,7 +2056,7 @@ static void status (struct seq_file *seqfor (i =0 ; i < conf->raid_disks; i++)seq_printf (seq,"%s" , conf->disks[i].rdev && - conf->disks[i].rdev->in_sync ?"U" :"_" ); +test_bit (In_sync, &conf->disks[i].rdev->flags) ?"U" :"_" );seq_printf (seq,"]" );#if RAID6_DUMPSTATE seq_printf (seq,"\n" );
@@ -2082,7 +2082,7 @@ static void print_raid6_conf (raid6_conf tmp = conf->disks + i;if (tmp->rdev)printk (" disk %d, o:%d, dev:%s\n" , - i, !tmp->rdev->faulty, + i, !test_bit (Faulty, &tmp->rdev->flags),bdevname (tmp->rdev->bdev,b)); } }
@@ -2096,12 +2096,12 @@ static int raid6_spare_active(mddev_t *mfor (i =0 ; i < conf->raid_disks; i++) { tmp = conf->disks + i;if (tmp->rdev - && !tmp->rdev->faulty - && !tmp->rdev->in_sync) { + && !test_bit (Faulty, &tmp->rdev->flags) + && !test_bit (In_sync, &tmp->rdev->flags)) { mddev->degraded--; conf->failed_disks--; conf->working_disks++; - tmp->rdev->in_sync =1 ; +set_bit (In_sync, &tmp->rdev->flags); } }print_raid6_conf (conf);
@@ -2118,7 +2118,7 @@ static int raid6_remove_disk(mddev_t *mdprint_raid6_conf (conf); rdev = p->rdev;if (rdev) { -if (rdev->in_sync || +if (test_bit (In_sync, &rdev->flags) ||atomic_read (&rdev->nr_pending)) { err = -EBUSY ; goto abort;
@@ -2153,7 +2153,7 @@ static int raid6_add_disk(mddev_t *mddev*/ for (disk=0 ; disk < mddev->raid_disks; disk++)if ((p=conf->disks + disk)->rdev ==NULL ) { - rdev->in_sync =0 ; +clear_bit (In_sync, &rdev->flags); rdev->raid_disk = disk; found =1 ;if (rdev->saved_raid_disk != disk)
include/linux/raid/md_k.h renamed from include/linux/raid/md_k.h~current~ +4 -4
@@ -117,10 +117,10 @@ struct mdk_rdev_s* It can never have faulty==1, in_sync==1 * This reduces the burden of testing multiple flags in many cases */ -int faulty;/* if faulty do not issue IO requests */ -int in_sync;/* device is a full member of the array */ -unsigned long flags;/* Should include faulty and in_sync here. */ +unsigned long flags; +#define Faulty 1/* device is known to have a fault */ +#define In_sync 2/* device is in_sync with rest of array */ #define WriteMostly 4/* Avoid reading if at all possible */ int desc_nr;/* descriptor index in the superblock */
@@ -247,7 +247,7 @@ struct mddev_sstatic inline void rdev_dec_pending (mdk_rdev_t *rdev,mddev_t *mddev) { -int faulty = rdev->faulty; +int faulty =test_bit (Faulty, &rdev->flags);if (atomic_dec_and_test (&rdev->nr_pending) && faulty)set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); }
PATCH 1/1 Make md on-disk bitmaps not host-endian
In reply to NeilBrownCurrent bitmaps use set_bit et.al and so are host-endian, which means not-portable. Oops.
Define a new version number (4) for which bitmaps are little-endian.
### Diffstat output
./drivers/md/bitmap.c | 22 ++++++++++++++++++---- ./drivers/md/md.c | 2 +- ./include/linux/raid/bitmap.h | 11 +++++++++-- ./include/linux/raid/md.h | 4 +++- 4 files changed, 31 insertions(+), 8 deletions(-)
drivers/md/bitmap.c renamed from drivers/md/bitmap.c~current~ +18 -4
@@ -483,7 +483,8 @@ static int bitmap_read_sb(struct bitmap/* verify that the bitmap-specific fields are valid */ if (sb->magic !=cpu_to_le32 (BITMAP_MAGIC )) reason ="bad magic" ; -else if (sb->version !=cpu_to_le32 (BITMAP_MAJOR )) +else if (le32_to_cpu (sb->version) <BITMAP_MAJOR_LO || +le32_to_cpu (sb->version) >BITMAP_MAJOR_HI ) reason ="unrecognized superblock version" ;else if (chunksize <512 || chunksize > (1024 *1024 *4 )) reason ="bitmap chunksize out of range (512B - 4MB)" ;
@@ -528,6 +529,8 @@ success: bitmap->daemon_lastrun = jiffies; bitmap->max_write_behind = write_behind; bitmap->flags |= sb->state; +if (le32_to_cpu (sb->version) ==BITMAP_MAJOR_HOSTENDIAN ) + bitmap->flags |=BITMAP_HOSTENDIAN ; bitmap->events_cleared =le64_to_cpu (sb->events_cleared);if (sb->state &BITMAP_STALE ) bitmap->events_cleared = bitmap->mddev->events;
@@ -765,7 +768,10 @@ static void bitmap_file_set_bit(struct b/* set the bit */ kaddr =kmap_atomic (page,KM_USER0 ); -set_bit (bit, kaddr); +if (bitmap->flags &BITMAP_HOSTENDIAN ) +set_bit (bit, kaddr); +else +ext2_set_bit (bit, kaddr);kunmap_atomic (kaddr,KM_USER0 );PRINTK ("set file bit %lu page %lu\n" , bit, page->index);
@@ -892,6 +898,7 @@ static int bitmap_init_from_disk(struct oldindex = ~0L ;for (i =0 ; i < chunks; i++) { +int b; index =file_page_index (i); bit =file_page_offset (i);if (index != oldindex) {/* this is a new page, read it in */
@@ -940,7 +947,11 @@ static int bitmap_init_from_disk(struct bitmap->filemap[bitmap->file_pages++] = page; } -if (test_bit (bit,page_address (page))) { +if (bitmap->flags &BITMAP_HOSTENDIAN ) + b =test_bit (bit,page_address (page)); +else + b =ext2_test_bit (bit,page_address (page)); +if (b) {/* if the disk bit is set, set the memory bit */ bitmap_set_memory_bits (bitmap, i <<CHUNK_BLOCK_SHIFT (bitmap), ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
@@ -1098,7 +1109,10 @@ int bitmap_daemon_work(struct bitmap *bi -1);/* clear the bit */ -clear_bit (file_page_offset (j),page_address (page)); +if (bitmap->flags &BITMAP_HOSTENDIAN ) +clear_bit (file_page_offset (j),page_address (page)); +else +ext2_clear_bit (file_page_offset (j),page_address (page)); } }spin_unlock_irqrestore (&bitmap->lock, flags);
drivers/md/md.c renamed from drivers/md/md.c~current~ +1 -1
@@ -4277,7 +4277,7 @@ static int __init md_init(void)" MD_SB_DISKS=%d\n" ,MD_MAJOR_VERSION ,MD_MINOR_VERSION , MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); -printk (KERN_INFO "md: bitmap version %d.%d\n" ,BITMAP_MAJOR , +printk (KERN_INFO "md: bitmap version %d.%d\n" ,BITMAP_MAJOR_HI ,BITMAP_MINOR );if (register_blkdev (MAJOR_NR ,"md" ))
include/linux/raid/bitmap.h renamed from include/linux/raid/bitmap.h~current~ +9 -2
@@ -6,7 +6,13 @@#ifndef BITMAP_H #define BITMAP_H 1 -#define BITMAP_MAJOR 3 +#define BITMAP_MAJOR_LO 3 +/* version 4 insists the bitmap is in little-endian order +* with version 3, it is host-endian which is non-portable +*/ +#define BITMAP_MAJOR_HI 4 +#define BITMAP_MAJOR_HOSTENDIAN 3 +#define BITMAP_MINOR 39/*
@@ -133,7 +139,8 @@ typedef __u16 bitmap_counter_t;/* use these for bitmap->flags and bitmap->sb->state bit-fields */ enum bitmap_state {BITMAP_ACTIVE =0x001 ,/* the bitmap is in use */ -BITMAP_STALE =0x002 /* the bitmap file is out of date or had -EIO */ +BITMAP_STALE =0x002 ,/* the bitmap file is out of date or had -EIO */ +BITMAP_HOSTENDIAN =0x8000 , };/* the superblock at the front of the bitmap file -- little endian */
include/linux/raid/md.h renamed from include/linux/raid/md.h~current~ +3 -1
@@ -66,8 +66,10 @@* and major_version/minor_version accordingly * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT * in the super status byte +* >=3 means that bitmap superblock version 4 is supported, which uses +* little-ending representation rather than host-endian */ -#define MD_PATCHLEVEL_VERSION 2 +#define MD_PATCHLEVEL_VERSION 3extern int register_md_personality (int p_num,mdk_personality_t *p);extern int unregister_md_personality (int p_num);
PATCH 1/1 Support BIO_RW_BARRIER for md/raid1.
In reply to NeilBrownWe can only accept BARRIER requests if all slaves handle barriers, and that can, of course, change with time....
So we keep track of whether the whole array seems safe for barriers, and also whether each individual rdev handles barriers.
We initially assumes barriers are OK.
When writing the superblock we try a barrier, and if that fails, we flag things for no-barriers. This will usually clear the flags fairly quickly.
If writing the superblock finds that BIO_RW_BARRIER is -ENOTSUPP, we need to resubmit, so introduce function "md_super_wait" which waits for requests to finish, and retries ENOTSUPP requests without the barrier flag.
When writing the real raid1, write requests which were BIO_RW_BARRIER but which aresn't supported need to be retried. So raid1d is enhanced to do this, and when any bio write completes (i.e. no retry needed) we remove it from the r1bio, so that devices needing retry are easy to find.
We should hardly ever get -ENOTSUPP errors when writing data to the raid. It should only happen if:
1/ the device used to support BARRIER, but now doesn't. Few devices
change like this, though raid1 can!
or
2/ the array has no persistent superblock, so there was no opportunity to
pre-test for barriers when writing the superblock.
### Diffstat output
./drivers/md/bitmap.c | 5 - ./drivers/md/md.c | 99 +++++++++++++++++++++++++++----- ./drivers/md/raid1.c | 130 +++++++++++++++++++++++++++++-------------- ./include/linux/raid/md.h | 1 ./include/linux/raid/md_k.h | 8 ++ ./include/linux/raid/raid1.h | 4 - 6 files changed, 187 insertions(+), 60 deletions(-)
drivers/md/bitmap.c renamed from drivers/md/bitmap.c~current~ +2 -3
@@ -302,7 +302,7 @@ static int write_sb_page(mddev_t *mddev, page);if (wait) -wait_event (mddev->sb_wait,atomic_read (&mddev->pending_writes)==0 ); +md_super_wait (mddev);return 0 ; }
@@ -829,8 +829,7 @@ int bitmap_unplug(struct bitmap *bitmap) wake_up_process(bitmap->writeback_daemon->tsk));spin_unlock_irq (&bitmap->write_lock); }else -wait_event (bitmap->mddev->sb_wait, -atomic_read (&bitmap->mddev->pending_writes)==0 ); +md_super_wait (bitmap->mddev); }return 0 ; }
drivers/md/md.c renamed from drivers/md/md.c~current~ +83 -16
192 lines not on this page · raw message
drivers/md/raid1.c renamed from drivers/md/raid1.c~current~ +90 -40
179 lines not on this page · raw message
include/linux/raid/md.h renamed from include/linux/raid/md.h~current~ +1 -0
@@ -89,6 +89,7 @@ extern void md_print_devices (void);extern void md_super_write (mddev_t *mddev,mdk_rdev_t *rdev,sector_t sector,int size,struct page *page); +extern void md_super_wait (mddev_t *mddev);extern int sync_page_io (struct block_device *bdev,sector_t sector,int size,struct page *page,int rw);
include/linux/raid/md_k.h renamed from include/linux/raid/md_k.h~current~ +8 -0
@@ -122,6 +122,7 @@ struct mdk_rdev_s#define Faulty 1/* device is known to have a fault */ #define In_sync 2/* device is in_sync with rest of array */ #define WriteMostly 4/* Avoid reading if at all possible */ +#define BarriersNotsupp 5/* BIO_RW_BARRIER is not supported */ int desc_nr;/* descriptor index in the superblock */ int raid_disk;/* role of device in array */
@@ -210,6 +211,13 @@ struct mddev_sint degraded;/* whether md should consider * adding a spare */ +int barriers_work;/* initialised to true, cleared as soon +* as a barrier request to slave +* fails. Only supported +*/ +struct bio *biolist;/* bios that need to be retried +* because BIO_RW_BARRIER is not supported +*/ atomic_t recovery_active;/* blocks scheduled, but not written */ wait_queue_head_t recovery_wait;
include/linux/raid/raid1.h renamed from include/linux/raid/raid1.h~current~ +3 -1
@@ -110,7 +110,9 @@ struct r1bio_s {#define R1BIO_Uptodate 0#define R1BIO_IsSync 1#define R1BIO_Degraded 2 -#define R1BIO_BehindIO 3 +#define R1BIO_BehindIO 3 +#define R1BIO_Barrier 4 +#define R1BIO_BarrierRetry 5/* For write-behind requests, we call bi_end_io when * the last non-write-behind device completes, providing * any write was successful. Otherwise we call when
Hello Neil , Is it possible to inert in the 'Introduction's for your patches a Min & Max kernel level they will successfully patch against ? ie: 2.6.12 to 2.6.14-rc4 or some such .
That would sure take the angst out of guessing . Tia , JimL
Quoted 24 lines · NeilBrown
8 patches for md/raid in 2.6 follow.
The first replaces
md-identify-raid-rcu-protected-pointer.patch
which has some minor issues.
2 and 3 fix problems in previous patches identified by some kindly code reviewers.Thanks,
NeilBrown[PATCH md 001 of 8] Provide proper
rcu_dereference/rcu_assign_pointerannotations in md [PATCH md 002 of 8] Fix ref-counting problems with kobjects in md
[PATCH md 003 of 8] Minor MD fixes
[PATCH md 004 of 8] Change raid5 sysfs attribute to not create a new directory. [PATCH md 005 of 8] Improvements to raid5 handling of read errors
[PATCH md 006 of 8] Convert 'faulty' and 'in_sync' fields to bits in 'flags' field. [PATCH md 007 of 8] Make md on-disk bitmaps not host-endian
[PATCH md 008 of 8] SupportBIO_RW_BARRIERfor md/raid1.
-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 5 lines
+------------------------------------------------------------------+ | James W. Laferriere | System Techniques | Give me VMS | | Network Engineer | 3542 Broken Yoke Dr. | Give me Linux | | [email protected] | Billings , MT. 59105 | only on AXP | +------------------------------------------------------------------+
Review
Quoted 5 lines · On Sunday October 16, [email protected] wrote:
(quoted diff) +0
-0Hello Neil , Is it possible to inert in the 'Introduction's for your patches a Min & Max kernel level they will successfully patch against ? ie: 2.6.12 to 2.6.14-rc4 or some such . That would sure take the angst out of guessing . Tia , JimL
I could certainly be more precise about which kernel they are created against (it is usually the latest 2.6-mm) but it would be a lot of work to figure out how far back you can safely go and still have the patch usefully apply, and I'm not sure that it is really worth it, is it?
If you want to help test raid patch (and I do appreciate the help), it is really best if you use the most recent kernel, otherwise there could be unexpected interactions which invalidate the test.
Hope that's ok,
Thanks,
NeilBrown
Hello Neil ,
Quoted 8 lines · Neil Brown
Review
Quoted 4 lines · On Sunday October 16, [email protected] wrote:
(quoted diff) +0
-0Hello Neil , Is it possible to inert in the 'Introduction's for your patches a Min & Max kernel level they will successfully patch against ? ie: 2.6.12 to 2.6.14-rc4 or some such . That would sure take the angst out of guessing . Tia , JimLI could certainly be more precise about which kernel they are created against (it is usually the latest 2.6-mm) .
Perfect . Would you please insert the full kernel source version number the patches were created from in with the 'Introductions' , Please ?
Quoted 4 lines
but it would be a lot of
work to figure out how far back you can safely go and still have the patch usefully apply, and I'm not sure that it is really worth it, is it?
Not really what I was looking for . Was thinking more on the lines of the last kernel version that had accepted a previous patch set of yours as a approximation of patch'ability . That sound do able ?
Quoted 3 lines
If you want to help test raid patch (and I do appreciate the help), it is really best if you use the most recent kernel, otherwise there could be unexpected interactions which invalidate the test.
I am definately willing to test patch sets . Whether I'll be able to do so for very long is another matter . Tnx , JimL
Signature · 5 lines
+------------------------------------------------------------------+ | James W. Laferriere | System Techniques | Give me VMS | | Network Engineer | 3542 Broken Yoke Dr. | Give me Linux | | [email protected] | Billings , MT. 59105 | only on AXP | +------------------------------------------------------------------+