1 --- linux-2.6.35.4/drivers/md/raid1.c 2010-08-26 18:47:12.000000000 -0500 2 +++ linux-2.6.35.4-2rrrr/drivers/md/raid1.c 2010-09-06 14:50:15.309000014 -0500 3 @@ -51,6 +51,52 @@ 4 */ 5 #define NR_RAID1_BIOS 256 6 7 +static ssize_t raid1_show_mode_roundrobbin(mddev_t *mddev, char *page) 8 +{ 9 + conf_t *conf = mddev->private; 10 + 11 + if (!conf) { 12 + return(-ENODEV); 13 + } 14 + 15 + return sprintf(page, "%d\n", conf->round_robbin); 16 +} 17 + 18 +static ssize_t raid1_store_mode_roundrobbin(mddev_t *mddev, const char *page, size_t len) 19 +{ 20 + conf_t *conf = mddev->private; 21 + unsigned long new; 22 + 23 + if (!conf) { 24 + return(-ENODEV); 25 + } 26 + 27 + if (strict_strtoul(page, 10, &new)) { 28 + return -EINVAL; 29 + } 30 + 31 + if (new) { 32 + conf->round_robbin = 1; 33 + } else { 34 + conf->round_robbin = 0; 35 + } 36 + 37 + return len; 38 +} 39 + 40 +static struct md_sysfs_entry raid1_mode_roundrobbin = __ATTR(round_robbin, 41 + S_IRUGO | S_IWUSR, raid1_show_mode_roundrobbin, 42 + raid1_store_mode_roundrobbin); 43 + 44 +static struct attribute *raid1_attrs[] = { 45 + &raid1_mode_roundrobbin.attr, 46 + NULL 47 +}; 48 + 49 +static struct attribute_group raid1_attrs_group = { 50 + .name = NULL, 51 + .attrs = raid1_attrs, 52 +}; 53 54 static void unplug_slaves(mddev_t *mddev); 55 56 @@ -456,6 +502,10 @@ 57 goto rb_out; 58 } 59 60 + /* If round-robbin mode enabled for this array, select next disk */ 61 + if (conf->round_robbin) { 62 + new_disk = (new_disk + 1) % conf->raid_disks; 63 + } 64 65 /* make sure the disk is operational */ 66 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); 67 @@ -480,6 +530,11 @@ 68 if (new_disk < 0) 69 goto rb_out; 70 71 + /* Don't bother searching for the best disk if we are in round-robbin mode */ 72 + if (conf->round_robbin) { 73 + goto rb_out; 74 + } 75 + 76 disk = new_disk; 77 /* now disk == new_disk == starting point for search */ 78 79 @@ -2061,6 +2116,8 @@ 80 goto abort; 81 } 82 83 + conf->round_robbin = 0; 84 + 85 return conf; 86 87 abort: 88 @@ -2147,6 +2204,15 @@ 89 90 md_set_array_sectors(mddev, raid1_size(mddev, 0, 0)); 91 92 + if (mddev->to_remove == &raid1_attrs_group) { 93 + mddev->to_remove = NULL; 94 + } else { 95 + if (sysfs_create_group(&mddev->kobj, &raid1_attrs_group)) 96 + printk(KERN_WARNING 97 + "md/raid:%s: failed to create sysfs attributes.\n", 98 + mdname(mddev)); 99 + } 100 + 101 mddev->queue->unplug_fn = raid1_unplug; 102 mddev->queue->backing_dev_info.congested_fn = raid1_congested; 103 mddev->queue->backing_dev_info.congested_data = mddev; 104 @@ -2173,6 +2239,7 @@ 105 106 md_unregister_thread(mddev->thread); 107 mddev->thread = NULL; 108 + mddev->to_remove = &raid1_attrs_group; 109 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 110 if (conf->r1bio_pool) 111 mempool_destroy(conf->r1bio_pool); 112 --- linux-2.6.35.4/drivers/md/raid1.h 2010-08-26 18:47:12.000000000 -0500 113 +++ linux-2.6.35.4-2rrrr/drivers/md/raid1.h 2010-09-06 14:26:10.297999975 -0500 114 @@ -64,6 +64,8 @@ 115 * the new thread here until we fully activate the array. 116 */ 117 struct mdk_thread_s *thread; 118 + 119 + int round_robbin; 120 }; 121 122 typedef struct r1_private_data_s conf_t; |