@@ -753,7 +753,6 @@ int mddev_init(struct mddev *mddev)
753
753
754
754
mutex_init (& mddev -> open_mutex );
755
755
mutex_init (& mddev -> reconfig_mutex );
756
- mutex_init (& mddev -> sync_mutex );
757
756
mutex_init (& mddev -> suspend_mutex );
758
757
mutex_init (& mddev -> bitmap_info .mutex );
759
758
INIT_LIST_HEAD (& mddev -> disks );
@@ -5021,59 +5020,20 @@ void md_unfrozen_sync_thread(struct mddev *mddev)
5021
5020
}
5022
5021
EXPORT_SYMBOL_GPL (md_unfrozen_sync_thread );
5023
5022
5024
- static void idle_sync_thread (struct mddev * mddev )
5025
- {
5026
- mutex_lock (& mddev -> sync_mutex );
5027
- clear_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5028
-
5029
- if (mddev_lock (mddev )) {
5030
- mutex_unlock (& mddev -> sync_mutex );
5031
- return ;
5032
- }
5033
-
5034
- stop_sync_thread (mddev , false);
5035
- mutex_unlock (& mddev -> sync_mutex );
5036
- }
5037
-
5038
- static void frozen_sync_thread (struct mddev * mddev )
5039
- {
5040
- mutex_lock (& mddev -> sync_mutex );
5041
- set_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5042
-
5043
- if (mddev_lock (mddev )) {
5044
- mutex_unlock (& mddev -> sync_mutex );
5045
- return ;
5046
- }
5047
-
5048
- stop_sync_thread (mddev , false);
5049
- mutex_unlock (& mddev -> sync_mutex );
5050
- }
5051
-
5052
5023
static int mddev_start_reshape (struct mddev * mddev )
5053
5024
{
5054
5025
int ret ;
5055
5026
5056
5027
if (mddev -> pers -> start_reshape == NULL )
5057
5028
return - EINVAL ;
5058
5029
5059
- ret = mddev_lock (mddev );
5060
- if (ret )
5061
- return ret ;
5062
-
5063
- if (test_bit (MD_RECOVERY_RUNNING , & mddev -> recovery )) {
5064
- mddev_unlock (mddev );
5065
- return - EBUSY ;
5066
- }
5067
-
5068
5030
if (mddev -> reshape_position == MaxSector ||
5069
5031
mddev -> pers -> check_reshape == NULL ||
5070
5032
mddev -> pers -> check_reshape (mddev )) {
5071
5033
clear_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5072
5034
ret = mddev -> pers -> start_reshape (mddev );
5073
- if (ret ) {
5074
- mddev_unlock (mddev );
5035
+ if (ret )
5075
5036
return ret ;
5076
- }
5077
5037
} else {
5078
5038
/*
5079
5039
* If reshape is still in progress, and md_check_recovery() can
@@ -5083,7 +5043,6 @@ static int mddev_start_reshape(struct mddev *mddev)
5083
5043
clear_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5084
5044
}
5085
5045
5086
- mddev_unlock (mddev );
5087
5046
sysfs_notify_dirent_safe (mddev -> sysfs_degraded );
5088
5047
return 0 ;
5089
5048
}
@@ -5097,36 +5056,53 @@ action_store(struct mddev *mddev, const char *page, size_t len)
5097
5056
if (!mddev -> pers || !mddev -> pers -> sync_request )
5098
5057
return - EINVAL ;
5099
5058
5059
+ retry :
5060
+ if (work_busy (& mddev -> sync_work ))
5061
+ flush_work (& mddev -> sync_work );
5062
+
5063
+ ret = mddev_lock (mddev );
5064
+ if (ret )
5065
+ return ret ;
5066
+
5067
+ if (work_busy (& mddev -> sync_work )) {
5068
+ mddev_unlock (mddev );
5069
+ goto retry ;
5070
+ }
5071
+
5100
5072
action = md_sync_action_by_name (page );
5101
5073
5102
5074
/* TODO: mdadm rely on "idle" to start sync_thread. */
5103
5075
if (test_bit (MD_RECOVERY_RUNNING , & mddev -> recovery )) {
5104
5076
switch (action ) {
5105
5077
case ACTION_FROZEN :
5106
- frozen_sync_thread (mddev );
5107
- return len ;
5078
+ md_frozen_sync_thread (mddev );
5079
+ ret = len ;
5080
+ goto out ;
5108
5081
case ACTION_IDLE :
5109
- idle_sync_thread (mddev );
5082
+ md_idle_sync_thread (mddev );
5110
5083
break ;
5111
5084
case ACTION_RESHAPE :
5112
5085
case ACTION_RECOVER :
5113
5086
case ACTION_CHECK :
5114
5087
case ACTION_REPAIR :
5115
5088
case ACTION_RESYNC :
5116
- return - EBUSY ;
5089
+ ret = - EBUSY ;
5090
+ goto out ;
5117
5091
default :
5118
- return - EINVAL ;
5092
+ ret = - EINVAL ;
5093
+ goto out ;
5119
5094
}
5120
5095
} else {
5121
5096
switch (action ) {
5122
5097
case ACTION_FROZEN :
5123
5098
set_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5124
- return len ;
5099
+ ret = len ;
5100
+ goto out ;
5125
5101
case ACTION_RESHAPE :
5126
5102
clear_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5127
5103
ret = mddev_start_reshape (mddev );
5128
5104
if (ret )
5129
- return ret ;
5105
+ goto out ;
5130
5106
break ;
5131
5107
case ACTION_RECOVER :
5132
5108
clear_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
@@ -5144,22 +5120,27 @@ action_store(struct mddev *mddev, const char *page, size_t len)
5144
5120
clear_bit (MD_RECOVERY_FROZEN , & mddev -> recovery );
5145
5121
break ;
5146
5122
default :
5147
- return - EINVAL ;
5123
+ ret = - EINVAL ;
5124
+ goto out ;
5148
5125
}
5149
5126
}
5150
5127
5151
5128
if (mddev -> ro == MD_AUTO_READ ) {
5152
5129
/* A write to sync_action is enough to justify
5153
5130
* canceling read-auto mode
5154
5131
*/
5155
- flush_work (& mddev -> sync_work );
5156
5132
mddev -> ro = MD_RDWR ;
5157
5133
md_wakeup_thread (mddev -> sync_thread );
5158
5134
}
5135
+
5159
5136
set_bit (MD_RECOVERY_NEEDED , & mddev -> recovery );
5160
5137
md_wakeup_thread (mddev -> thread );
5161
5138
sysfs_notify_dirent_safe (mddev -> sysfs_action );
5162
- return len ;
5139
+ ret = len ;
5140
+
5141
+ out :
5142
+ mddev_unlock (mddev );
5143
+ return ret ;
5163
5144
}
5164
5145
5165
5146
static struct md_sysfs_entry md_scan_mode =
0 commit comments