*/
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <linux/blkdev.h>
#include <linux/sysctl.h>
#include <linux/seq_file.h>
int err = -ENOMEM;
if (md_allow_write(mddev))
- file = kmalloc(sizeof(*file), GFP_NOIO);
+ file = kzalloc(sizeof(*file), GFP_NOIO);
else
- file = kmalloc(sizeof(*file), GFP_KERNEL);
+ file = kzalloc(sizeof(*file), GFP_KERNEL);
if (!file)
goto out;
mddev->ctime != info->ctime ||
mddev->level != info->level ||
/* mddev->layout != info->layout || */
- !mddev->persistent != info->not_persistent||
+ mddev->persistent != !info->not_persistent ||
mddev->chunk_sectors != info->chunk_size >> 9 ||
/* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */
((state^info->state) & 0xfffffe00)
/* just incase thread restarts... */
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
return;
- if (mddev->ro) /* never try to sync a read-only array */
+ if (mddev->ro) {/* never try to sync a read-only array */
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
return;
+ }
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
*
*/
+ set_freezable();
+
do {
mddev->curr_resync = 2;
try_again:
- if (kthread_should_stop())
+
+ if (kthread_freezable_should_stop(NULL))
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
* time 'round when curr_resync == 2
*/
continue;
+
+ try_to_freeze();
+
/* We need to wait 'interruptible' so as not to
* contribute to the load average, and not to
* be caught by 'softlockup'
" share one or more physical units)\n",
desc, mdname(mddev), mdname(mddev2));
mddev_put(mddev2);
+ try_to_freeze();
if (signal_pending(current))
flush_signals(current);
schedule();
rdev->recovery_offset < j)
j = rdev->recovery_offset;
rcu_read_unlock();
+
+ /* If there is a bitmap, we need to make sure all
+ * writes that started before we added a spare
+ * complete before we start doing a recovery.
+ * Otherwise the write might complete and (via
+ * bitmap_endwrite) set a bit in the bitmap after the
+ * recovery has checked that bit and skipped that
+ * region.
+ */
+ if (mddev->bitmap) {
+ mddev->pers->quiesce(mddev, 1);
+ mddev->pers->quiesce(mddev, 0);
+ }
}
printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
|| kthread_should_stop());
}
- if (kthread_should_stop())
+ if (kthread_freezable_should_stop(NULL))
goto interrupted;
sectors = mddev->pers->sync_request(mddev, j, &skipped,
last_mark = next;
}
-
- if (kthread_should_stop())
+ if (kthread_freezable_should_stop(NULL))
goto interrupted;
*/
void md_check_recovery(struct mddev *mddev)
{
- if (mddev->suspended)
+#ifdef CONFIG_FREEZER
+ if (mddev->suspended || unlikely(atomic_read(&system_freezing_cnt)))
return;
+#endif
if (mddev->bitmap)
bitmap_daemon_work(mddev);
/* There is no thread, but we need to call
* ->spare_active and clear saved_raid_disk
*/
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
md_reap_sync_thread(mddev);
clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
goto unlock;
if (mddev_trylock(mddev)) {
if (mddev->pers)
__md_stop_writes(mddev);
- mddev->safemode = 2;
+ if (mddev->persistent)
+ mddev->safemode = 2;
mddev_unlock(mddev);
}
need_delay = 1;