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); |
