diff options
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 859afdfe5a08..eeda8b8e9d8e 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -221,6 +221,43 @@ void drbd_request_endio(struct bio *bio, int error) | |||
221 | error = -EIO; | 221 | error = -EIO; |
222 | } | 222 | } |
223 | 223 | ||
224 | |||
225 | /* If this request was aborted locally before, | ||
226 | * but now was completed "successfully", | ||
227 | * chances are that this caused arbitrary data corruption. | ||
228 | * | ||
229 | * "aborting" requests, or force-detaching the disk, is intended for | ||
230 | * completely blocked/hung local backing devices which do no longer | ||
231 | * complete requests at all, not even do error completions. In this | ||
232 | * situation, usually a hard-reset and failover is the only way out. | ||
233 | * | ||
234 | * By "aborting", basically faking a local error-completion, | ||
235 | * we allow for a more graceful swichover by cleanly migrating services. | ||
236 | * Still the affected node has to be rebooted "soon". | ||
237 | * | ||
238 | * By completing these requests, we allow the upper layers to re-use | ||
239 | * the associated data pages. | ||
240 | * | ||
241 | * If later the local backing device "recovers", and now DMAs some data | ||
242 | * from disk into the original request pages, in the best case it will | ||
243 | * just put random data into unused pages; but typically it will corrupt | ||
244 | * meanwhile completely unrelated data, causing all sorts of damage. | ||
245 | * | ||
246 | * Which means delayed successful completion, | ||
247 | * especially for READ requests, | ||
248 | * is a reason to panic(). | ||
249 | * | ||
250 | * We assume that a delayed *error* completion is OK, | ||
251 | * though we still will complain noisily about it. | ||
252 | */ | ||
253 | if (unlikely(req->rq_state & RQ_LOCAL_ABORTED)) { | ||
254 | if (__ratelimit(&drbd_ratelimit_state)) | ||
255 | dev_emerg(DEV, "delayed completion of aborted local request; disk-timeout may be too aggressive\n"); | ||
256 | |||
257 | if (!error) | ||
258 | panic("possible random memory corruption caused by delayed completion of aborted local request\n"); | ||
259 | } | ||
260 | |||
224 | /* to avoid recursion in __req_mod */ | 261 | /* to avoid recursion in __req_mod */ |
225 | if (unlikely(error)) { | 262 | if (unlikely(error)) { |
226 | what = (bio_data_dir(bio) == WRITE) | 263 | what = (bio_data_dir(bio) == WRITE) |