diff options
Diffstat (limited to 'drivers/block/drbd/drbd_actlog.c')
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index ac04ef97eac2..ba95cba192be 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -78,11 +78,10 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
78 | init_completion(&md_io.event); | 78 | init_completion(&md_io.event); |
79 | md_io.error = 0; | 79 | md_io.error = 0; |
80 | 80 | ||
81 | if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags)) | 81 | if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) |
82 | rw |= REQ_HARDBARRIER; | 82 | rw |= REQ_FUA; |
83 | rw |= REQ_UNPLUG | REQ_SYNC; | 83 | rw |= REQ_UNPLUG | REQ_SYNC; |
84 | 84 | ||
85 | retry: | ||
86 | bio = bio_alloc(GFP_NOIO, 1); | 85 | bio = bio_alloc(GFP_NOIO, 1); |
87 | bio->bi_bdev = bdev->md_bdev; | 86 | bio->bi_bdev = bdev->md_bdev; |
88 | bio->bi_sector = sector; | 87 | bio->bi_sector = sector; |
@@ -100,17 +99,6 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
100 | wait_for_completion(&md_io.event); | 99 | wait_for_completion(&md_io.event); |
101 | ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; | 100 | ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; |
102 | 101 | ||
103 | /* check for unsupported barrier op. | ||
104 | * would rather check on EOPNOTSUPP, but that is not reliable. | ||
105 | * don't try again for ANY return value != 0 */ | ||
106 | if (unlikely((bio->bi_rw & REQ_HARDBARRIER) && !ok)) { | ||
107 | /* Try again with no barrier */ | ||
108 | dev_warn(DEV, "Barriers not supported on meta data device - disabling\n"); | ||
109 | set_bit(MD_NO_BARRIER, &mdev->flags); | ||
110 | rw &= ~REQ_HARDBARRIER; | ||
111 | bio_put(bio); | ||
112 | goto retry; | ||
113 | } | ||
114 | out: | 102 | out: |
115 | bio_put(bio); | 103 | bio_put(bio); |
116 | return ok; | 104 | return ok; |
@@ -284,18 +272,32 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) | |||
284 | u32 xor_sum = 0; | 272 | u32 xor_sum = 0; |
285 | 273 | ||
286 | if (!get_ldev(mdev)) { | 274 | if (!get_ldev(mdev)) { |
287 | dev_err(DEV, "get_ldev() failed in w_al_write_transaction\n"); | 275 | dev_err(DEV, |
276 | "disk is %s, cannot start al transaction (-%d +%d)\n", | ||
277 | drbd_disk_str(mdev->state.disk), evicted, new_enr); | ||
288 | complete(&((struct update_al_work *)w)->event); | 278 | complete(&((struct update_al_work *)w)->event); |
289 | return 1; | 279 | return 1; |
290 | } | 280 | } |
291 | /* do we have to do a bitmap write, first? | 281 | /* do we have to do a bitmap write, first? |
292 | * TODO reduce maximum latency: | 282 | * TODO reduce maximum latency: |
293 | * submit both bios, then wait for both, | 283 | * submit both bios, then wait for both, |
294 | * instead of doing two synchronous sector writes. */ | 284 | * instead of doing two synchronous sector writes. |
285 | * For now, we must not write the transaction, | ||
286 | * if we cannot write out the bitmap of the evicted extent. */ | ||
295 | if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) | 287 | if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) |
296 | drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); | 288 | drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); |
297 | 289 | ||
298 | mutex_lock(&mdev->md_io_mutex); /* protects md_io_page, al_tr_cycle, ... */ | 290 | /* The bitmap write may have failed, causing a state change. */ |
291 | if (mdev->state.disk < D_INCONSISTENT) { | ||
292 | dev_err(DEV, | ||
293 | "disk is %s, cannot write al transaction (-%d +%d)\n", | ||
294 | drbd_disk_str(mdev->state.disk), evicted, new_enr); | ||
295 | complete(&((struct update_al_work *)w)->event); | ||
296 | put_ldev(mdev); | ||
297 | return 1; | ||
298 | } | ||
299 | |||
300 | mutex_lock(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ | ||
299 | buffer = (struct al_transaction *)page_address(mdev->md_io_page); | 301 | buffer = (struct al_transaction *)page_address(mdev->md_io_page); |
300 | 302 | ||
301 | buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); | 303 | buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); |
@@ -739,7 +741,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) | |||
739 | unsigned int enr; | 741 | unsigned int enr; |
740 | unsigned long add = 0; | 742 | unsigned long add = 0; |
741 | char ppb[10]; | 743 | char ppb[10]; |
742 | int i; | 744 | int i, tmp; |
743 | 745 | ||
744 | wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); | 746 | wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); |
745 | 747 | ||
@@ -747,7 +749,9 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) | |||
747 | enr = lc_element_by_index(mdev->act_log, i)->lc_number; | 749 | enr = lc_element_by_index(mdev->act_log, i)->lc_number; |
748 | if (enr == LC_FREE) | 750 | if (enr == LC_FREE) |
749 | continue; | 751 | continue; |
750 | add += drbd_bm_ALe_set_all(mdev, enr); | 752 | tmp = drbd_bm_ALe_set_all(mdev, enr); |
753 | dynamic_dev_dbg(DEV, "AL: set %d bits in extent %u\n", tmp, enr); | ||
754 | add += tmp; | ||
751 | } | 755 | } |
752 | 756 | ||
753 | lc_unlock(mdev->act_log); | 757 | lc_unlock(mdev->act_log); |