diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index d1cb45f6d6a9..e8807ea5377d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1633,7 +1633,8 @@ repeat: | |||
1633 | * and 'events' is odd, we can roll back to the previous clean state */ | 1633 | * and 'events' is odd, we can roll back to the previous clean state */ |
1634 | if (nospares | 1634 | if (nospares |
1635 | && (mddev->in_sync && mddev->recovery_cp == MaxSector) | 1635 | && (mddev->in_sync && mddev->recovery_cp == MaxSector) |
1636 | && (mddev->events & 1)) | 1636 | && (mddev->events & 1) |
1637 | && mddev->events != 1) | ||
1637 | mddev->events--; | 1638 | mddev->events--; |
1638 | else { | 1639 | else { |
1639 | /* otherwise we have to go forward and ... */ | 1640 | /* otherwise we have to go forward and ... */ |
@@ -3563,6 +3564,8 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) | |||
3563 | char *ptr, *buf = NULL; | 3564 | char *ptr, *buf = NULL; |
3564 | int err = -ENOMEM; | 3565 | int err = -ENOMEM; |
3565 | 3566 | ||
3567 | md_allow_write(mddev); | ||
3568 | |||
3566 | file = kmalloc(sizeof(*file), GFP_KERNEL); | 3569 | file = kmalloc(sizeof(*file), GFP_KERNEL); |
3567 | if (!file) | 3570 | if (!file) |
3568 | goto out; | 3571 | goto out; |
@@ -5031,6 +5034,33 @@ void md_write_end(mddev_t *mddev) | |||
5031 | } | 5034 | } |
5032 | } | 5035 | } |
5033 | 5036 | ||
5037 | /* md_allow_write(mddev) | ||
5038 | * Calling this ensures that the array is marked 'active' so that writes | ||
5039 | * may proceed without blocking. It is important to call this before | ||
5040 | * attempting a GFP_KERNEL allocation while holding the mddev lock. | ||
5041 | * Must be called with mddev_lock held. | ||
5042 | */ | ||
5043 | void md_allow_write(mddev_t *mddev) | ||
5044 | { | ||
5045 | if (!mddev->pers) | ||
5046 | return; | ||
5047 | if (mddev->ro) | ||
5048 | return; | ||
5049 | |||
5050 | spin_lock_irq(&mddev->write_lock); | ||
5051 | if (mddev->in_sync) { | ||
5052 | mddev->in_sync = 0; | ||
5053 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
5054 | if (mddev->safemode_delay && | ||
5055 | mddev->safemode == 0) | ||
5056 | mddev->safemode = 1; | ||
5057 | spin_unlock_irq(&mddev->write_lock); | ||
5058 | md_update_sb(mddev, 0); | ||
5059 | } else | ||
5060 | spin_unlock_irq(&mddev->write_lock); | ||
5061 | } | ||
5062 | EXPORT_SYMBOL_GPL(md_allow_write); | ||
5063 | |||
5034 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | 5064 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); |
5035 | 5065 | ||
5036 | #define SYNC_MARKS 10 | 5066 | #define SYNC_MARKS 10 |