diff options
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 102 |
1 files changed, 21 insertions, 81 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 7258c95e895e..fa650dd85b90 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2184,43 +2184,6 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size) return ok; } -static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) -{ - struct p_delay_probe dp; - int offset, ok = 0; - struct timeval now; - - mutex_lock(&ds->mutex); - if (likely(ds->socket)) { - do_gettimeofday(&now); - offset = now.tv_usec - mdev->dps_time.tv_usec + - (now.tv_sec - mdev->dps_time.tv_sec) * 1000000; - dp.seq_num = cpu_to_be32(mdev->delay_seq); - dp.offset = cpu_to_be32(offset); - - ok = _drbd_send_cmd(mdev, ds->socket, P_DELAY_PROBE, - (struct p_header *)&dp, sizeof(dp), 0); - } - mutex_unlock(&ds->mutex); - - return ok; -} - -static int drbd_send_delay_probes(struct drbd_conf *mdev) -{ - int ok; - - mdev->delay_seq++; - do_gettimeofday(&mdev->dps_time); - ok = drbd_send_delay_probe(mdev, &mdev->meta); - ok = ok && drbd_send_delay_probe(mdev, &mdev->data); - - mdev->dp_volume_last = mdev->send_cnt; - mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10); - - return ok; -} - /* called on sndtimeo * returns FALSE if we should retry, * TRUE if we think connection is dead @@ -2369,31 +2332,6 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) return 1; } -static void consider_delay_probes(struct drbd_conf *mdev) -{ - if (mdev->state.conn != C_SYNC_SOURCE || mdev->agreed_pro_version < 93) - return; - - if (mdev->dp_volume_last + mdev->sync_conf.dp_volume * 2 < mdev->send_cnt) - drbd_send_delay_probes(mdev); -} - -static int w_delay_probes(struct drbd_conf *mdev, struct drbd_work *w, int cancel) -{ - if (!cancel && mdev->state.conn == C_SYNC_SOURCE) - drbd_send_delay_probes(mdev); - - return 1; -} - -static void delay_probe_timer_fn(unsigned long data) -{ - struct drbd_conf *mdev = (struct drbd_conf *) data; - - if (list_empty(&mdev->delay_probe_work.list)) - drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work); -} - /* Used to send write requests * R_PRIMARY -> Peer (P_DATA) */ @@ -2425,15 +2363,15 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) /* NOTE: no need to check if barriers supported here as we would * not pass the test in make_request_common in that case */ - if (bio_rw_flagged(req->master_bio, BIO_RW_BARRIER)) { + if (req->master_bio->bi_rw & REQ_HARDBARRIER) { dev_err(DEV, "ASSERT FAILED would have set DP_HARDBARRIER\n"); /* dp_flags |= DP_HARDBARRIER; */ } - if (bio_rw_flagged(req->master_bio, BIO_RW_SYNCIO)) + if (req->master_bio->bi_rw & REQ_SYNC) dp_flags |= DP_RW_SYNC; /* for now handle SYNCIO and UNPLUG * as if they still were one and the same flag */ - if (bio_rw_flagged(req->master_bio, BIO_RW_UNPLUG)) + if (req->master_bio->bi_rw & REQ_UNPLUG) dp_flags |= DP_RW_SYNC; if (mdev->state.conn >= C_SYNC_SOURCE && mdev->state.conn <= C_PAUSED_SYNC_T) @@ -2457,9 +2395,6 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) drbd_put_data_sock(mdev); - if (ok) - consider_delay_probes(mdev); - return ok; } @@ -2506,9 +2441,6 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, drbd_put_data_sock(mdev); - if (ok) - consider_delay_probes(mdev); - return ok; } @@ -2604,6 +2536,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) unsigned long flags; int rv = 0; + lock_kernel(); spin_lock_irqsave(&mdev->req_lock, flags); /* to have a stable mdev->state.role * and no race with updating open_cnt */ @@ -2618,6 +2551,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) if (!rv) mdev->open_cnt++; spin_unlock_irqrestore(&mdev->req_lock, flags); + unlock_kernel(); return rv; } @@ -2625,7 +2559,9 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) static int drbd_release(struct gendisk *gd, fmode_t mode) { struct drbd_conf *mdev = gd->private_data; + lock_kernel(); mdev->open_cnt--; + unlock_kernel(); return 0; } @@ -2660,9 +2596,20 @@ static void drbd_unplug_fn(struct request_queue *q) static void drbd_set_defaults(struct drbd_conf *mdev) { - mdev->sync_conf.after = DRBD_AFTER_DEF; - mdev->sync_conf.rate = DRBD_RATE_DEF; - mdev->sync_conf.al_extents = DRBD_AL_EXTENTS_DEF; + /* This way we get a compile error when sync_conf grows, + and we forgot to initialize it here */ + mdev->sync_conf = (struct syncer_conf) { + /* .rate = */ DRBD_RATE_DEF, + /* .after = */ DRBD_AFTER_DEF, + /* .al_extents = */ DRBD_AL_EXTENTS_DEF, + /* .verify_alg = */ {}, 0, + /* .cpu_mask = */ {}, 0, + /* .csums_alg = */ {}, 0, + /* .use_rle = */ 0 + }; + + /* Have to use that way, because the layout differs between + big endian and little endian */ mdev->state = (union drbd_state) { { .role = R_SECONDARY, .peer = R_UNKNOWN, @@ -2721,24 +2668,17 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) INIT_LIST_HEAD(&mdev->unplug_work.list); INIT_LIST_HEAD(&mdev->md_sync_work.list); INIT_LIST_HEAD(&mdev->bm_io_work.w.list); - INIT_LIST_HEAD(&mdev->delay_probes); - INIT_LIST_HEAD(&mdev->delay_probe_work.list); mdev->resync_work.cb = w_resync_inactive; mdev->unplug_work.cb = w_send_write_hint; mdev->md_sync_work.cb = w_md_sync; mdev->bm_io_work.w.cb = w_bitmap_io; - mdev->delay_probe_work.cb = w_delay_probes; init_timer(&mdev->resync_timer); init_timer(&mdev->md_sync_timer); - init_timer(&mdev->delay_probe_timer); mdev->resync_timer.function = resync_timer_fn; mdev->resync_timer.data = (unsigned long) mdev; mdev->md_sync_timer.function = md_sync_timer_fn; mdev->md_sync_timer.data = (unsigned long) mdev; - mdev->delay_probe_timer.function = delay_probe_timer_fn; - mdev->delay_probe_timer.data = (unsigned long) mdev; - init_waitqueue_head(&mdev->misc_wait); init_waitqueue_head(&mdev->state_wait); |