aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c86
1 files changed, 48 insertions, 38 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index e4e161372a3e..b6d16022a53e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -110,7 +110,7 @@ static ctl_table raid_table[] = {
110 .procname = "speed_limit_min", 110 .procname = "speed_limit_min",
111 .data = &sysctl_speed_limit_min, 111 .data = &sysctl_speed_limit_min,
112 .maxlen = sizeof(int), 112 .maxlen = sizeof(int),
113 .mode = 0644, 113 .mode = S_IRUGO|S_IWUSR,
114 .proc_handler = &proc_dointvec, 114 .proc_handler = &proc_dointvec,
115 }, 115 },
116 { 116 {
@@ -118,7 +118,7 @@ static ctl_table raid_table[] = {
118 .procname = "speed_limit_max", 118 .procname = "speed_limit_max",
119 .data = &sysctl_speed_limit_max, 119 .data = &sysctl_speed_limit_max,
120 .maxlen = sizeof(int), 120 .maxlen = sizeof(int),
121 .mode = 0644, 121 .mode = S_IRUGO|S_IWUSR,
122 .proc_handler = &proc_dointvec, 122 .proc_handler = &proc_dointvec,
123 }, 123 },
124 { .ctl_name = 0 } 124 { .ctl_name = 0 }
@@ -129,7 +129,7 @@ static ctl_table raid_dir_table[] = {
129 .ctl_name = DEV_RAID, 129 .ctl_name = DEV_RAID,
130 .procname = "raid", 130 .procname = "raid",
131 .maxlen = 0, 131 .maxlen = 0,
132 .mode = 0555, 132 .mode = S_IRUGO|S_IXUGO,
133 .child = raid_table, 133 .child = raid_table,
134 }, 134 },
135 { .ctl_name = 0 } 135 { .ctl_name = 0 }
@@ -1062,6 +1062,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
1062 if (rdev->sb_size & bmask) 1062 if (rdev->sb_size & bmask)
1063 rdev-> sb_size = (rdev->sb_size | bmask)+1; 1063 rdev-> sb_size = (rdev->sb_size | bmask)+1;
1064 1064
1065 if (sb->level == cpu_to_le32(LEVEL_MULTIPATH))
1066 rdev->desc_nr = -1;
1067 else
1068 rdev->desc_nr = le32_to_cpu(sb->dev_number);
1069
1065 if (refdev == 0) 1070 if (refdev == 0)
1066 ret = 1; 1071 ret = 1;
1067 else { 1072 else {
@@ -1171,7 +1176,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
1171 } 1176 }
1172 if (mddev->level != LEVEL_MULTIPATH) { 1177 if (mddev->level != LEVEL_MULTIPATH) {
1173 int role; 1178 int role;
1174 rdev->desc_nr = le32_to_cpu(sb->dev_number);
1175 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); 1179 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
1176 switch(role) { 1180 switch(role) {
1177 case 0xffff: /* spare */ 1181 case 0xffff: /* spare */
@@ -1779,8 +1783,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1779 } 1783 }
1780 return err ? err : len; 1784 return err ? err : len;
1781} 1785}
1782static struct rdev_sysfs_entry 1786static struct rdev_sysfs_entry rdev_state =
1783rdev_state = __ATTR(state, 0644, state_show, state_store); 1787__ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store);
1784 1788
1785static ssize_t 1789static ssize_t
1786super_show(mdk_rdev_t *rdev, char *page) 1790super_show(mdk_rdev_t *rdev, char *page)
@@ -1811,7 +1815,7 @@ errors_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1811 return -EINVAL; 1815 return -EINVAL;
1812} 1816}
1813static struct rdev_sysfs_entry rdev_errors = 1817static struct rdev_sysfs_entry rdev_errors =
1814__ATTR(errors, 0644, errors_show, errors_store); 1818__ATTR(errors, S_IRUGO|S_IWUSR, errors_show, errors_store);
1815 1819
1816static ssize_t 1820static ssize_t
1817slot_show(mdk_rdev_t *rdev, char *page) 1821slot_show(mdk_rdev_t *rdev, char *page)
@@ -1845,7 +1849,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1845 1849
1846 1850
1847static struct rdev_sysfs_entry rdev_slot = 1851static struct rdev_sysfs_entry rdev_slot =
1848__ATTR(slot, 0644, slot_show, slot_store); 1852__ATTR(slot, S_IRUGO|S_IWUSR, slot_show, slot_store);
1849 1853
1850static ssize_t 1854static ssize_t
1851offset_show(mdk_rdev_t *rdev, char *page) 1855offset_show(mdk_rdev_t *rdev, char *page)
@@ -1867,7 +1871,7 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1867} 1871}
1868 1872
1869static struct rdev_sysfs_entry rdev_offset = 1873static struct rdev_sysfs_entry rdev_offset =
1870__ATTR(offset, 0644, offset_show, offset_store); 1874__ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store);
1871 1875
1872static ssize_t 1876static ssize_t
1873rdev_size_show(mdk_rdev_t *rdev, char *page) 1877rdev_size_show(mdk_rdev_t *rdev, char *page)
@@ -1891,7 +1895,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
1891} 1895}
1892 1896
1893static struct rdev_sysfs_entry rdev_size = 1897static struct rdev_sysfs_entry rdev_size =
1894__ATTR(size, 0644, rdev_size_show, rdev_size_store); 1898__ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
1895 1899
1896static struct attribute *rdev_default_attrs[] = { 1900static struct attribute *rdev_default_attrs[] = {
1897 &rdev_state.attr, 1901 &rdev_state.attr,
@@ -1922,6 +1926,8 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
1922 1926
1923 if (!entry->store) 1927 if (!entry->store)
1924 return -EIO; 1928 return -EIO;
1929 if (!capable(CAP_SYS_ADMIN))
1930 return -EACCES;
1925 return entry->store(rdev, page, length); 1931 return entry->store(rdev, page, length);
1926} 1932}
1927 1933
@@ -2128,7 +2134,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
2128 return len; 2134 return len;
2129} 2135}
2130static struct md_sysfs_entry md_safe_delay = 2136static struct md_sysfs_entry md_safe_delay =
2131__ATTR(safe_mode_delay, 0644,safe_delay_show, safe_delay_store); 2137__ATTR(safe_mode_delay, S_IRUGO|S_IWUSR,safe_delay_show, safe_delay_store);
2132 2138
2133static ssize_t 2139static ssize_t
2134level_show(mddev_t *mddev, char *page) 2140level_show(mddev_t *mddev, char *page)
@@ -2163,7 +2169,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
2163} 2169}
2164 2170
2165static struct md_sysfs_entry md_level = 2171static struct md_sysfs_entry md_level =
2166__ATTR(level, 0644, level_show, level_store); 2172__ATTR(level, S_IRUGO|S_IWUSR, level_show, level_store);
2167 2173
2168 2174
2169static ssize_t 2175static ssize_t
@@ -2188,7 +2194,7 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
2188 return len; 2194 return len;
2189} 2195}
2190static struct md_sysfs_entry md_layout = 2196static struct md_sysfs_entry md_layout =
2191__ATTR(layout, 0655, layout_show, layout_store); 2197__ATTR(layout, S_IRUGO|S_IWUSR, layout_show, layout_store);
2192 2198
2193 2199
2194static ssize_t 2200static ssize_t
@@ -2219,7 +2225,7 @@ raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
2219 return rv ? rv : len; 2225 return rv ? rv : len;
2220} 2226}
2221static struct md_sysfs_entry md_raid_disks = 2227static struct md_sysfs_entry md_raid_disks =
2222__ATTR(raid_disks, 0644, raid_disks_show, raid_disks_store); 2228__ATTR(raid_disks, S_IRUGO|S_IWUSR, raid_disks_show, raid_disks_store);
2223 2229
2224static ssize_t 2230static ssize_t
2225chunk_size_show(mddev_t *mddev, char *page) 2231chunk_size_show(mddev_t *mddev, char *page)
@@ -2243,7 +2249,7 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
2243 return len; 2249 return len;
2244} 2250}
2245static struct md_sysfs_entry md_chunk_size = 2251static struct md_sysfs_entry md_chunk_size =
2246__ATTR(chunk_size, 0644, chunk_size_show, chunk_size_store); 2252__ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store);
2247 2253
2248static ssize_t 2254static ssize_t
2249resync_start_show(mddev_t *mddev, char *page) 2255resync_start_show(mddev_t *mddev, char *page)
@@ -2267,7 +2273,7 @@ resync_start_store(mddev_t *mddev, const char *buf, size_t len)
2267 return len; 2273 return len;
2268} 2274}
2269static struct md_sysfs_entry md_resync_start = 2275static struct md_sysfs_entry md_resync_start =
2270__ATTR(resync_start, 0644, resync_start_show, resync_start_store); 2276__ATTR(resync_start, S_IRUGO|S_IWUSR, resync_start_show, resync_start_store);
2271 2277
2272/* 2278/*
2273 * The array state can be: 2279 * The array state can be:
@@ -2437,7 +2443,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
2437 else 2443 else
2438 return len; 2444 return len;
2439} 2445}
2440static struct md_sysfs_entry md_array_state = __ATTR(array_state, 0644, array_state_show, array_state_store); 2446static struct md_sysfs_entry md_array_state =
2447__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
2441 2448
2442static ssize_t 2449static ssize_t
2443null_show(mddev_t *mddev, char *page) 2450null_show(mddev_t *mddev, char *page)
@@ -2497,7 +2504,7 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len)
2497} 2504}
2498 2505
2499static struct md_sysfs_entry md_new_device = 2506static struct md_sysfs_entry md_new_device =
2500__ATTR(new_dev, 0200, null_show, new_dev_store); 2507__ATTR(new_dev, S_IWUSR, null_show, new_dev_store);
2501 2508
2502static ssize_t 2509static ssize_t
2503size_show(mddev_t *mddev, char *page) 2510size_show(mddev_t *mddev, char *page)
@@ -2535,7 +2542,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
2535} 2542}
2536 2543
2537static struct md_sysfs_entry md_size = 2544static struct md_sysfs_entry md_size =
2538__ATTR(component_size, 0644, size_show, size_store); 2545__ATTR(component_size, S_IRUGO|S_IWUSR, size_show, size_store);
2539 2546
2540 2547
2541/* Metdata version. 2548/* Metdata version.
@@ -2583,7 +2590,7 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
2583} 2590}
2584 2591
2585static struct md_sysfs_entry md_metadata = 2592static struct md_sysfs_entry md_metadata =
2586__ATTR(metadata_version, 0644, metadata_show, metadata_store); 2593__ATTR(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
2587 2594
2588static ssize_t 2595static ssize_t
2589action_show(mddev_t *mddev, char *page) 2596action_show(mddev_t *mddev, char *page)
@@ -2651,12 +2658,11 @@ mismatch_cnt_show(mddev_t *mddev, char *page)
2651 (unsigned long long) mddev->resync_mismatches); 2658 (unsigned long long) mddev->resync_mismatches);
2652} 2659}
2653 2660
2654static struct md_sysfs_entry 2661static struct md_sysfs_entry md_scan_mode =
2655md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store); 2662__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
2656 2663
2657 2664
2658static struct md_sysfs_entry 2665static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt);
2659md_mismatches = __ATTR_RO(mismatch_cnt);
2660 2666
2661static ssize_t 2667static ssize_t
2662sync_min_show(mddev_t *mddev, char *page) 2668sync_min_show(mddev_t *mddev, char *page)
@@ -2715,15 +2721,14 @@ static ssize_t
2715sync_speed_show(mddev_t *mddev, char *page) 2721sync_speed_show(mddev_t *mddev, char *page)
2716{ 2722{
2717 unsigned long resync, dt, db; 2723 unsigned long resync, dt, db;
2718 resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); 2724 resync = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active));
2719 dt = ((jiffies - mddev->resync_mark) / HZ); 2725 dt = ((jiffies - mddev->resync_mark) / HZ);
2720 if (!dt) dt++; 2726 if (!dt) dt++;
2721 db = resync - (mddev->resync_mark_cnt); 2727 db = resync - (mddev->resync_mark_cnt);
2722 return sprintf(page, "%ld\n", db/dt/2); /* K/sec */ 2728 return sprintf(page, "%ld\n", db/dt/2); /* K/sec */
2723} 2729}
2724 2730
2725static struct md_sysfs_entry 2731static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed);
2726md_sync_speed = __ATTR_RO(sync_speed);
2727 2732
2728static ssize_t 2733static ssize_t
2729sync_completed_show(mddev_t *mddev, char *page) 2734sync_completed_show(mddev_t *mddev, char *page)
@@ -2739,8 +2744,7 @@ sync_completed_show(mddev_t *mddev, char *page)
2739 return sprintf(page, "%lu / %lu\n", resync, max_blocks); 2744 return sprintf(page, "%lu / %lu\n", resync, max_blocks);
2740} 2745}
2741 2746
2742static struct md_sysfs_entry 2747static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
2743md_sync_completed = __ATTR_RO(sync_completed);
2744 2748
2745static ssize_t 2749static ssize_t
2746suspend_lo_show(mddev_t *mddev, char *page) 2750suspend_lo_show(mddev_t *mddev, char *page)
@@ -2857,6 +2861,8 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
2857 2861
2858 if (!entry->store) 2862 if (!entry->store)
2859 return -EIO; 2863 return -EIO;
2864 if (!capable(CAP_SYS_ADMIN))
2865 return -EACCES;
2860 rv = mddev_lock(mddev); 2866 rv = mddev_lock(mddev);
2861 if (!rv) { 2867 if (!rv) {
2862 rv = entry->store(mddev, page, length); 2868 rv = entry->store(mddev, page, length);
@@ -3091,7 +3097,6 @@ static int do_md_run(mddev_t * mddev)
3091 } 3097 }
3092 3098
3093 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 3099 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3094 md_wakeup_thread(mddev->thread);
3095 3100
3096 if (mddev->sb_dirty) 3101 if (mddev->sb_dirty)
3097 md_update_sb(mddev); 3102 md_update_sb(mddev);
@@ -3112,7 +3117,7 @@ static int do_md_run(mddev_t * mddev)
3112 * start recovery here. If we leave it to md_check_recovery, 3117 * start recovery here. If we leave it to md_check_recovery,
3113 * it will remove the drives and not do the right thing 3118 * it will remove the drives and not do the right thing
3114 */ 3119 */
3115 if (mddev->degraded) { 3120 if (mddev->degraded && !mddev->sync_thread) {
3116 struct list_head *rtmp; 3121 struct list_head *rtmp;
3117 int spares = 0; 3122 int spares = 0;
3118 ITERATE_RDEV(mddev,rdev,rtmp) 3123 ITERATE_RDEV(mddev,rdev,rtmp)
@@ -3133,10 +3138,11 @@ static int do_md_run(mddev_t * mddev)
3133 mdname(mddev)); 3138 mdname(mddev));
3134 /* leave the spares where they are, it shouldn't hurt */ 3139 /* leave the spares where they are, it shouldn't hurt */
3135 mddev->recovery = 0; 3140 mddev->recovery = 0;
3136 } else 3141 }
3137 md_wakeup_thread(mddev->sync_thread);
3138 } 3142 }
3139 } 3143 }
3144 md_wakeup_thread(mddev->thread);
3145 md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
3140 3146
3141 mddev->changed = 1; 3147 mddev->changed = 1;
3142 md_new_event(mddev); 3148 md_new_event(mddev);
@@ -4586,6 +4592,8 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
4586 __builtin_return_address(0),__builtin_return_address(1), 4592 __builtin_return_address(0),__builtin_return_address(1),
4587 __builtin_return_address(2),__builtin_return_address(3)); 4593 __builtin_return_address(2),__builtin_return_address(3));
4588*/ 4594*/
4595 if (!mddev->pers)
4596 return;
4589 if (!mddev->pers->error_handler) 4597 if (!mddev->pers->error_handler)
4590 return; 4598 return;
4591 mddev->pers->error_handler(mddev,rdev); 4599 mddev->pers->error_handler(mddev,rdev);
@@ -4683,12 +4691,13 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
4683 */ 4691 */
4684 dt = ((jiffies - mddev->resync_mark) / HZ); 4692 dt = ((jiffies - mddev->resync_mark) / HZ);
4685 if (!dt) dt++; 4693 if (!dt) dt++;
4686 db = resync - (mddev->resync_mark_cnt/2); 4694 db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
4687 rt = (dt * ((unsigned long)(max_blocks-resync) / (db/100+1)))/100; 4695 - mddev->resync_mark_cnt;
4696 rt = (dt * ((unsigned long)(max_blocks-resync) / (db/2/100+1)))/100;
4688 4697
4689 seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6); 4698 seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
4690 4699
4691 seq_printf(seq, " speed=%ldK/sec", db/dt); 4700 seq_printf(seq, " speed=%ldK/sec", db/2/dt);
4692} 4701}
4693 4702
4694static void *md_seq_start(struct seq_file *seq, loff_t *pos) 4703static void *md_seq_start(struct seq_file *seq, loff_t *pos)
@@ -5199,6 +5208,7 @@ void md_do_sync(mddev_t *mddev)
5199 5208
5200 j += sectors; 5209 j += sectors;
5201 if (j>1) mddev->curr_resync = j; 5210 if (j>1) mddev->curr_resync = j;
5211 mddev->curr_mark_cnt = io_sectors;
5202 if (last_check == 0) 5212 if (last_check == 0)
5203 /* this is the earliers that rebuilt will be 5213 /* this is the earliers that rebuilt will be
5204 * visible in /proc/mdstat 5214 * visible in /proc/mdstat
@@ -5645,8 +5655,8 @@ static int set_ro(const char *val, struct kernel_param *kp)
5645 return -EINVAL; 5655 return -EINVAL;
5646} 5656}
5647 5657
5648module_param_call(start_ro, set_ro, get_ro, NULL, 0600); 5658module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR);
5649module_param(start_dirty_degraded, int, 0644); 5659module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR);
5650 5660
5651 5661
5652EXPORT_SYMBOL(register_md_personality); 5662EXPORT_SYMBOL(register_md_personality);