If a 'remove' fails there is no certainty that another event will
happen soon, so make sure we retry soon anyway.
Reported-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
* external:/md0/12
*/
int devcnt;
* external:/md0/12
*/
int devcnt;
static int read_and_act(struct active_array *a)
{
unsigned long long sync_completed;
static int read_and_act(struct active_array *a)
{
unsigned long long sync_completed;
if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
int remove_result;
if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
int remove_result;
- /* the kernel may not be able to immediately remove the
- * disk, we can simply wait until the next event to try
- * again.
+ /* The kernel may not be able to immediately remove the
+ * disk. In that case we wait a little while and
+ * try again.
*/
remove_result = write_attr("remove", mdi->state_fd);
if (remove_result > 0) {
*/
remove_result = write_attr("remove", mdi->state_fd);
if (remove_result > 0) {
close(mdi->state_fd);
close(mdi->recovery_fd);
mdi->state_fd = -1;
close(mdi->state_fd);
close(mdi->recovery_fd);
mdi->state_fd = -1;
+ } else
+ ret |= ARRAY_BUSY;
}
if (mdi->next_state & DS_INSYNC) {
write_attr("+in_sync", mdi->state_fd);
}
if (mdi->next_state & DS_INSYNC) {
write_attr("+in_sync", mdi->state_fd);
struct timespec ts;
ts.tv_sec = 24*3600;
ts.tv_nsec = 0;
struct timespec ts;
ts.tv_sec = 24*3600;
ts.tv_nsec = 0;
+ if (*aap == NULL || container->retry_soon) {
/* just waiting to get O_EXCL access */
ts.tv_sec = 0;
ts.tv_nsec = 20000000ULL;
/* just waiting to get O_EXCL access */
ts.tv_sec = 0;
ts.tv_nsec = 20000000ULL;
#ifdef DEBUG
dprint_wake_reasons(&rfds);
#endif
#ifdef DEBUG
dprint_wake_reasons(&rfds);
#endif
+ container->retry_soon = 0;
*/
if (sigterm && !(ret & ARRAY_DIRTY))
a->container = NULL; /* stop touching this array */
*/
if (sigterm && !(ret & ARRAY_DIRTY))
a->container = NULL; /* stop touching this array */
+ if (ret & ARRAY_BUSY)
+ container->retry_soon = 1;