aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8238c1c0ec09..d002b8301fc2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -131,6 +131,8 @@ static ctl_table raid_root_table[] = {
131 131
132static struct block_device_operations md_fops; 132static struct block_device_operations md_fops;
133 133
134static int start_readonly;
135
134/* 136/*
135 * Enables to iterate over all existing md arrays 137 * Enables to iterate over all existing md arrays
136 * all_mddevs_lock protects this list. 138 * all_mddevs_lock protects this list.
@@ -2029,6 +2031,9 @@ static int do_md_run(mddev_t * mddev)
2029 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ 2031 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
2030 mddev->barriers_work = 1; 2032 mddev->barriers_work = 1;
2031 2033
2034 if (start_readonly)
2035 mddev->ro = 2; /* read-only, but switch on first write */
2036
2032 /* before we start the array running, initialise the bitmap */ 2037 /* before we start the array running, initialise the bitmap */
2033 err = bitmap_create(mddev); 2038 err = bitmap_create(mddev);
2034 if (err) 2039 if (err)
@@ -2141,7 +2146,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
2141 2146
2142 if (ro) { 2147 if (ro) {
2143 err = -ENXIO; 2148 err = -ENXIO;
2144 if (mddev->ro) 2149 if (mddev->ro==1)
2145 goto out; 2150 goto out;
2146 mddev->ro = 1; 2151 mddev->ro = 1;
2147 } else { 2152 } else {
@@ -3258,12 +3263,22 @@ static int md_ioctl(struct inode *inode, struct file *file,
3258 3263
3259 /* 3264 /*
3260 * The remaining ioctls are changing the state of the 3265 * The remaining ioctls are changing the state of the
3261 * superblock, so we do not allow read-only arrays 3266 * superblock, so we do not allow them on read-only arrays.
3262 * here: 3267 * However non-MD ioctls (e.g. get-size) will still come through
3268 * here and hit the 'default' below, so only disallow
3269 * 'md' ioctls, and switch to rw mode if started auto-readonly.
3263 */ 3270 */
3264 if (mddev->ro) { 3271 if (_IOC_TYPE(cmd) == MD_MAJOR &&
3265 err = -EROFS; 3272 mddev->ro && mddev->pers) {
3266 goto abort_unlock; 3273 if (mddev->ro == 2) {
3274 mddev->ro = 0;
3275 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3276 md_wakeup_thread(mddev->thread);
3277
3278 } else {
3279 err = -EROFS;
3280 goto abort_unlock;
3281 }
3267 } 3282 }
3268 3283
3269 switch (cmd) 3284 switch (cmd)
@@ -3651,8 +3666,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
3651 seq_printf(seq, "%s : %sactive", mdname(mddev), 3666 seq_printf(seq, "%s : %sactive", mdname(mddev),
3652 mddev->pers ? "" : "in"); 3667 mddev->pers ? "" : "in");
3653 if (mddev->pers) { 3668 if (mddev->pers) {
3654 if (mddev->ro) 3669 if (mddev->ro==1)
3655 seq_printf(seq, " (read-only)"); 3670 seq_printf(seq, " (read-only)");
3671 if (mddev->ro==2)
3672 seq_printf(seq, "(auto-read-only)");
3656 seq_printf(seq, " %s", mddev->pers->name); 3673 seq_printf(seq, " %s", mddev->pers->name);
3657 } 3674 }
3658 3675
@@ -3696,7 +3713,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
3696 status_resync (seq, mddev); 3713 status_resync (seq, mddev);
3697 seq_printf(seq, "\n "); 3714 seq_printf(seq, "\n ");
3698 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) 3715 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
3699 seq_printf(seq, " resync=DELAYED\n "); 3716 seq_printf(seq, "\tresync=DELAYED\n ");
3717 else if (mddev->recovery_cp < MaxSector)
3718 seq_printf(seq, "\tresync=PENDING\n ");
3700 } else 3719 } else
3701 seq_printf(seq, "\n "); 3720 seq_printf(seq, "\n ");
3702 3721
@@ -3833,6 +3852,13 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
3833 if (bio_data_dir(bi) != WRITE) 3852 if (bio_data_dir(bi) != WRITE)
3834 return; 3853 return;
3835 3854
3855 BUG_ON(mddev->ro == 1);
3856 if (mddev->ro == 2) {
3857 /* need to switch to read/write */
3858 mddev->ro = 0;
3859 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3860 md_wakeup_thread(mddev->thread);
3861 }
3836 atomic_inc(&mddev->writes_pending); 3862 atomic_inc(&mddev->writes_pending);
3837 if (mddev->in_sync) { 3863 if (mddev->in_sync) {
3838 spin_lock_irq(&mddev->write_lock); 3864 spin_lock_irq(&mddev->write_lock);
@@ -4431,6 +4457,23 @@ static __exit void md_exit(void)
4431module_init(md_init) 4457module_init(md_init)
4432module_exit(md_exit) 4458module_exit(md_exit)
4433 4459
4460static int get_ro(char *buffer, struct kernel_param *kp)
4461{
4462 return sprintf(buffer, "%d", start_readonly);
4463}
4464static int set_ro(const char *val, struct kernel_param *kp)
4465{
4466 char *e;
4467 int num = simple_strtoul(val, &e, 10);
4468 if (*val && (*e == '\0' || *e == '\n')) {
4469 start_readonly = num;
4470 return 0;;
4471 }
4472 return -EINVAL;
4473}
4474
4475module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
4476
4434EXPORT_SYMBOL(register_md_personality); 4477EXPORT_SYMBOL(register_md_personality);
4435EXPORT_SYMBOL(unregister_md_personality); 4478EXPORT_SYMBOL(unregister_md_personality);
4436EXPORT_SYMBOL(md_error); 4479EXPORT_SYMBOL(md_error);