aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_actlog.c2
-rw-r--r--drivers/block/drbd/drbd_bitmap.c4
-rw-r--r--drivers/block/drbd/drbd_int.h17
-rw-r--r--drivers/block/drbd/drbd_main.c20
-rw-r--r--drivers/block/drbd/drbd_nl.c4
-rw-r--r--drivers/block/drbd/drbd_req.c6
-rw-r--r--drivers/block/drbd/drbd_worker.c4
7 files changed, 42 insertions, 15 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index e54e31b02b88..6ace11e9e5a1 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -411,7 +411,7 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
411 + mdev->ldev->md.al_offset + mdev->al_tr_pos; 411 + mdev->ldev->md.al_offset + mdev->al_tr_pos;
412 412
413 if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) 413 if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE))
414 drbd_chk_io_error(mdev, 1, true); 414 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
415 415
416 if (++mdev->al_tr_pos > 416 if (++mdev->al_tr_pos >
417 div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT)) 417 div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT))
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index fcb956bb4b4c..ba91b408abad 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -1096,7 +1096,7 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w
1096 1096
1097 if (ctx->error) { 1097 if (ctx->error) {
1098 dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n"); 1098 dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n");
1099 drbd_chk_io_error(mdev, 1, true); 1099 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
1100 err = -EIO; /* ctx->error ? */ 1100 err = -EIO; /* ctx->error ? */
1101 } 1101 }
1102 1102
@@ -1212,7 +1212,7 @@ int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(loc
1212 wait_until_done_or_disk_failure(mdev, mdev->ldev, &ctx->done); 1212 wait_until_done_or_disk_failure(mdev, mdev->ldev, &ctx->done);
1213 1213
1214 if (ctx->error) 1214 if (ctx->error)
1215 drbd_chk_io_error(mdev, 1, true); 1215 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
1216 /* that should force detach, so the in memory bitmap will be 1216 /* that should force detach, so the in memory bitmap will be
1217 * gone in a moment as well. */ 1217 * gone in a moment as well. */
1218 1218
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 356a6e5b4415..79c69ebb0653 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -832,6 +832,7 @@ enum {
832 BITMAP_IO_QUEUED, /* Started bitmap IO */ 832 BITMAP_IO_QUEUED, /* Started bitmap IO */
833 GO_DISKLESS, /* Disk is being detached, on io-error or admin request. */ 833 GO_DISKLESS, /* Disk is being detached, on io-error or admin request. */
834 WAS_IO_ERROR, /* Local disk failed returned IO error */ 834 WAS_IO_ERROR, /* Local disk failed returned IO error */
835 FORCE_DETACH, /* Force-detach from local disk, aborting any pending local IO */
835 RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ 836 RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */
836 NET_CONGESTED, /* The data socket is congested */ 837 NET_CONGESTED, /* The data socket is congested */
837 838
@@ -1838,12 +1839,20 @@ static inline int drbd_request_state(struct drbd_conf *mdev,
1838 return _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_ORDERED); 1839 return _drbd_request_state(mdev, mask, val, CS_VERBOSE + CS_ORDERED);
1839} 1840}
1840 1841
1842enum drbd_force_detach_flags {
1843 DRBD_IO_ERROR,
1844 DRBD_META_IO_ERROR,
1845 DRBD_FORCE_DETACH,
1846};
1847
1841#define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__) 1848#define __drbd_chk_io_error(m,f) __drbd_chk_io_error_(m,f, __func__)
1842static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, const char *where) 1849static inline void __drbd_chk_io_error_(struct drbd_conf *mdev,
1850 enum drbd_force_detach_flags forcedetach,
1851 const char *where)
1843{ 1852{
1844 switch (mdev->ldev->dc.on_io_error) { 1853 switch (mdev->ldev->dc.on_io_error) {
1845 case EP_PASS_ON: 1854 case EP_PASS_ON:
1846 if (!forcedetach) { 1855 if (forcedetach == DRBD_IO_ERROR) {
1847 if (__ratelimit(&drbd_ratelimit_state)) 1856 if (__ratelimit(&drbd_ratelimit_state))
1848 dev_err(DEV, "Local IO failed in %s.\n", where); 1857 dev_err(DEV, "Local IO failed in %s.\n", where);
1849 if (mdev->state.disk > D_INCONSISTENT) 1858 if (mdev->state.disk > D_INCONSISTENT)
@@ -1854,6 +1863,8 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach,
1854 case EP_DETACH: 1863 case EP_DETACH:
1855 case EP_CALL_HELPER: 1864 case EP_CALL_HELPER:
1856 set_bit(WAS_IO_ERROR, &mdev->flags); 1865 set_bit(WAS_IO_ERROR, &mdev->flags);
1866 if (forcedetach == DRBD_FORCE_DETACH)
1867 set_bit(FORCE_DETACH, &mdev->flags);
1857 if (mdev->state.disk > D_FAILED) { 1868 if (mdev->state.disk > D_FAILED) {
1858 _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL); 1869 _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL);
1859 dev_err(DEV, 1870 dev_err(DEV,
@@ -1873,7 +1884,7 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach,
1873 */ 1884 */
1874#define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__) 1885#define drbd_chk_io_error(m,e,f) drbd_chk_io_error_(m,e,f, __func__)
1875static inline void drbd_chk_io_error_(struct drbd_conf *mdev, 1886static inline void drbd_chk_io_error_(struct drbd_conf *mdev,
1876 int error, int forcedetach, const char *where) 1887 int error, enum drbd_force_detach_flags forcedetach, const char *where)
1877{ 1888{
1878 if (error) { 1889 if (error) {
1879 unsigned long flags; 1890 unsigned long flags;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 920ede2829d6..5bebe8d8ace3 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1630,9 +1630,21 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1630 eh = mdev->ldev->dc.on_io_error; 1630 eh = mdev->ldev->dc.on_io_error;
1631 was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags); 1631 was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags);
1632 1632
1633 /* Immediately allow completion of all application IO, that waits 1633 /* Immediately allow completion of all application IO,
1634 for completion from the local disk. */ 1634 * that waits for completion from the local disk,
1635 tl_abort_disk_io(mdev); 1635 * if this was a force-detach due to disk_timeout
1636 * or administrator request (drbdsetup detach --force).
1637 * Do NOT abort otherwise.
1638 * Aborting local requests may cause serious problems,
1639 * if requests are completed to upper layers already,
1640 * and then later the already submitted local bio completes.
1641 * This can cause DMA into former bio pages that meanwhile
1642 * have been re-used for other things.
1643 * So aborting local requests may cause crashes,
1644 * or even worse, silent data corruption.
1645 */
1646 if (test_and_clear_bit(FORCE_DETACH, &mdev->flags))
1647 tl_abort_disk_io(mdev);
1636 1648
1637 /* current state still has to be D_FAILED, 1649 /* current state still has to be D_FAILED,
1638 * there is only one way out: to D_DISKLESS, 1650 * there is only one way out: to D_DISKLESS,
@@ -3870,7 +3882,7 @@ void drbd_md_sync(struct drbd_conf *mdev)
3870 if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) { 3882 if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
3871 /* this was a try anyways ... */ 3883 /* this was a try anyways ... */
3872 dev_err(DEV, "meta data update failed!\n"); 3884 dev_err(DEV, "meta data update failed!\n");
3873 drbd_chk_io_error(mdev, 1, true); 3885 drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
3874 } 3886 }
3875 3887
3876 /* Update mdev->ldev->md.la_size_sect, 3888 /* Update mdev->ldev->md.la_size_sect,
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 6d4de6a72e80..40a1c4f07190 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -950,6 +950,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
950 * to realize a "hot spare" feature (not that I'd recommend that) */ 950 * to realize a "hot spare" feature (not that I'd recommend that) */
951 wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); 951 wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
952 952
953 /* make sure there is no leftover from previous force-detach attempts */
954 clear_bit(FORCE_DETACH, &mdev->flags);
955
953 /* allocation not in the IO path, cqueue thread context */ 956 /* allocation not in the IO path, cqueue thread context */
954 nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); 957 nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL);
955 if (!nbc) { 958 if (!nbc) {
@@ -1345,6 +1348,7 @@ static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
1345 } 1348 }
1346 1349
1347 if (dt.detach_force) { 1350 if (dt.detach_force) {
1351 set_bit(FORCE_DETACH, &mdev->flags);
1348 drbd_force_state(mdev, NS(disk, D_FAILED)); 1352 drbd_force_state(mdev, NS(disk, D_FAILED));
1349 reply->ret_code = SS_SUCCESS; 1353 reply->ret_code = SS_SUCCESS;
1350 goto out; 1354 goto out;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 8e93a6ac9bb6..1f4b2dbb7d4a 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -455,7 +455,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
455 req->rq_state |= RQ_LOCAL_COMPLETED; 455 req->rq_state |= RQ_LOCAL_COMPLETED;
456 req->rq_state &= ~RQ_LOCAL_PENDING; 456 req->rq_state &= ~RQ_LOCAL_PENDING;
457 457
458 __drbd_chk_io_error(mdev, false); 458 __drbd_chk_io_error(mdev, DRBD_IO_ERROR);
459 _req_may_be_done_not_susp(req, m); 459 _req_may_be_done_not_susp(req, m);
460 break; 460 break;
461 461
@@ -477,7 +477,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
477 break; 477 break;
478 } 478 }
479 479
480 __drbd_chk_io_error(mdev, false); 480 __drbd_chk_io_error(mdev, DRBD_IO_ERROR);
481 481
482 goto_queue_for_net_read: 482 goto_queue_for_net_read:
483 483
@@ -1275,7 +1275,7 @@ void request_timer_fn(unsigned long data)
1275 time_after(now, req->start_time + dt) && 1275 time_after(now, req->start_time + dt) &&
1276 !time_in_range(now, mdev->last_reattach_jif, mdev->last_reattach_jif + dt)) { 1276 !time_in_range(now, mdev->last_reattach_jif, mdev->last_reattach_jif + dt)) {
1277 dev_warn(DEV, "Local backing device failed to meet the disk-timeout\n"); 1277 dev_warn(DEV, "Local backing device failed to meet the disk-timeout\n");
1278 __drbd_chk_io_error(mdev, 1); 1278 __drbd_chk_io_error(mdev, DRBD_FORCE_DETACH);
1279 } 1279 }
1280 nt = (time_after(now, req->start_time + et) ? now : req->start_time) + et; 1280 nt = (time_after(now, req->start_time + et) ? now : req->start_time) + et;
1281 spin_unlock_irq(&mdev->req_lock); 1281 spin_unlock_irq(&mdev->req_lock);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 620c70ff2231..a35393f2fd1b 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -111,7 +111,7 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
111 if (list_empty(&mdev->read_ee)) 111 if (list_empty(&mdev->read_ee))
112 wake_up(&mdev->ee_wait); 112 wake_up(&mdev->ee_wait);
113 if (test_bit(__EE_WAS_ERROR, &e->flags)) 113 if (test_bit(__EE_WAS_ERROR, &e->flags))
114 __drbd_chk_io_error(mdev, false); 114 __drbd_chk_io_error(mdev, DRBD_IO_ERROR);
115 spin_unlock_irqrestore(&mdev->req_lock, flags); 115 spin_unlock_irqrestore(&mdev->req_lock, flags);
116 116
117 drbd_queue_work(&mdev->data.work, &e->w); 117 drbd_queue_work(&mdev->data.work, &e->w);
@@ -154,7 +154,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
154 : list_empty(&mdev->active_ee); 154 : list_empty(&mdev->active_ee);
155 155
156 if (test_bit(__EE_WAS_ERROR, &e->flags)) 156 if (test_bit(__EE_WAS_ERROR, &e->flags))
157 __drbd_chk_io_error(mdev, false); 157 __drbd_chk_io_error(mdev, DRBD_IO_ERROR);
158 spin_unlock_irqrestore(&mdev->req_lock, flags); 158 spin_unlock_irqrestore(&mdev->req_lock, flags);
159 159
160 if (is_syncer_req) 160 if (is_syncer_req)