瀏覽代碼

md: use interruptible wait when duration is controlled by userspace.

User space can set various limits on an md array so that resync waits
when it gets to a certain point, or so that I/O is blocked for a short
while.
When md is waiting against one of these limit, it should use an
interruptible wait so as not to add to the load average, and so are
not to trigger a warning if the wait goes on for too long.

Signed-off-by: NeilBrown <neilb@suse.de>
NeilBrown 16 年之前
父節點
當前提交
e62e58a5ff
共有 2 個文件被更改,包括 21 次插入8 次删除
  1. 10 4
      drivers/md/md.c
  2. 11 4
      drivers/md/raid5.c

+ 10 - 4
drivers/md/md.c

@@ -6336,10 +6336,16 @@ void md_do_sync(mddev_t *mddev)
 			sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 			sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 		}
 		}
 
 
-		if (j >= mddev->resync_max)
-			wait_event(mddev->recovery_wait,
-				   mddev->resync_max > j
-				   || kthread_should_stop());
+		while (j >= mddev->resync_max && !kthread_should_stop()) {
+			/* As this condition is controlled by user-space,
+			 * we can block indefinitely, so use '_interruptible'
+			 * to avoid triggering warnings.
+			 */
+			flush_signals(current); /* just in case */
+			wait_event_interruptible(mddev->recovery_wait,
+						 mddev->resync_max > j
+						 || kthread_should_stop());
+		}
 
 
 		if (kthread_should_stop())
 		if (kthread_should_stop())
 			goto interrupted;
 			goto interrupted;

+ 11 - 4
drivers/md/raid5.c

@@ -3699,14 +3699,21 @@ static int make_request(struct request_queue *q, struct bio * bi)
 					goto retry;
 					goto retry;
 				}
 				}
 			}
 			}
-			/* FIXME what if we get a false positive because these
-			 * are being updated.
-			 */
+
 			if (bio_data_dir(bi) == WRITE &&
 			if (bio_data_dir(bi) == WRITE &&
 			    logical_sector >= mddev->suspend_lo &&
 			    logical_sector >= mddev->suspend_lo &&
 			    logical_sector < mddev->suspend_hi) {
 			    logical_sector < mddev->suspend_hi) {
 				release_stripe(sh);
 				release_stripe(sh);
-				schedule();
+				/* As the suspend_* range is controlled by
+				 * userspace, we want an interruptible
+				 * wait.
+				 */
+				flush_signals(current);
+				prepare_to_wait(&conf->wait_for_overlap,
+						&w, TASK_INTERRUPTIBLE);
+				if (logical_sector >= mddev->suspend_lo &&
+				    logical_sector < mddev->suspend_hi)
+					schedule();
 				goto retry;
 				goto retry;
 			}
 			}