diff options
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 68 |
1 files changed, 26 insertions, 42 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index be2d2da9cdba..6b077f93acc6 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1215,18 +1215,17 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1215 | ns.pdsk == D_OUTDATED)) { | 1215 | ns.pdsk == D_OUTDATED)) { |
1216 | if (get_ldev(mdev)) { | 1216 | if (get_ldev(mdev)) { |
1217 | if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && | 1217 | if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && |
1218 | mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE && | 1218 | mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { |
1219 | !atomic_read(&mdev->new_c_uuid)) | 1219 | drbd_uuid_new_current(mdev); |
1220 | atomic_set(&mdev->new_c_uuid, 2); | 1220 | drbd_send_uuids(mdev); |
1221 | } | ||
1221 | put_ldev(mdev); | 1222 | put_ldev(mdev); |
1222 | } | 1223 | } |
1223 | } | 1224 | } |
1224 | 1225 | ||
1225 | if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { | 1226 | if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { |
1226 | /* Diskless peer becomes primary or got connected do diskless, primary peer. */ | 1227 | if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) |
1227 | if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0 && | 1228 | drbd_uuid_new_current(mdev); |
1228 | !atomic_read(&mdev->new_c_uuid)) | ||
1229 | atomic_set(&mdev->new_c_uuid, 2); | ||
1230 | 1229 | ||
1231 | /* D_DISKLESS Peer becomes secondary */ | 1230 | /* D_DISKLESS Peer becomes secondary */ |
1232 | if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) | 1231 | if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) |
@@ -1350,24 +1349,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1350 | drbd_md_sync(mdev); | 1349 | drbd_md_sync(mdev); |
1351 | } | 1350 | } |
1352 | 1351 | ||
1353 | static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | ||
1354 | { | ||
1355 | if (get_ldev(mdev)) { | ||
1356 | if (mdev->ldev->md.uuid[UI_BITMAP] == 0) { | ||
1357 | drbd_uuid_new_current(mdev); | ||
1358 | if (get_net_conf(mdev)) { | ||
1359 | drbd_send_uuids(mdev); | ||
1360 | put_net_conf(mdev); | ||
1361 | } | ||
1362 | drbd_md_sync(mdev); | ||
1363 | } | ||
1364 | put_ldev(mdev); | ||
1365 | } | ||
1366 | atomic_dec(&mdev->new_c_uuid); | ||
1367 | wake_up(&mdev->misc_wait); | ||
1368 | |||
1369 | return 1; | ||
1370 | } | ||
1371 | 1352 | ||
1372 | static int drbd_thread_setup(void *arg) | 1353 | static int drbd_thread_setup(void *arg) |
1373 | { | 1354 | { |
@@ -2291,9 +2272,9 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket * | |||
2291 | * with page_count == 0 or PageSlab. | 2272 | * with page_count == 0 or PageSlab. |
2292 | */ | 2273 | */ |
2293 | static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, | 2274 | static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, |
2294 | int offset, size_t size) | 2275 | int offset, size_t size, unsigned msg_flags) |
2295 | { | 2276 | { |
2296 | int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0); | 2277 | int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, msg_flags); |
2297 | kunmap(page); | 2278 | kunmap(page); |
2298 | if (sent == size) | 2279 | if (sent == size) |
2299 | mdev->send_cnt += size>>9; | 2280 | mdev->send_cnt += size>>9; |
@@ -2301,7 +2282,7 @@ static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, | |||
2301 | } | 2282 | } |
2302 | 2283 | ||
2303 | static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, | 2284 | static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, |
2304 | int offset, size_t size) | 2285 | int offset, size_t size, unsigned msg_flags) |
2305 | { | 2286 | { |
2306 | mm_segment_t oldfs = get_fs(); | 2287 | mm_segment_t oldfs = get_fs(); |
2307 | int sent, ok; | 2288 | int sent, ok; |
@@ -2314,14 +2295,15 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, | |||
2314 | * __page_cache_release a page that would actually still be referenced | 2295 | * __page_cache_release a page that would actually still be referenced |
2315 | * by someone, leading to some obscure delayed Oops somewhere else. */ | 2296 | * by someone, leading to some obscure delayed Oops somewhere else. */ |
2316 | if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) | 2297 | if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) |
2317 | return _drbd_no_send_page(mdev, page, offset, size); | 2298 | return _drbd_no_send_page(mdev, page, offset, size, msg_flags); |
2318 | 2299 | ||
2300 | msg_flags |= MSG_NOSIGNAL; | ||
2319 | drbd_update_congested(mdev); | 2301 | drbd_update_congested(mdev); |
2320 | set_fs(KERNEL_DS); | 2302 | set_fs(KERNEL_DS); |
2321 | do { | 2303 | do { |
2322 | sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, | 2304 | sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, |
2323 | offset, len, | 2305 | offset, len, |
2324 | MSG_NOSIGNAL); | 2306 | msg_flags); |
2325 | if (sent == -EAGAIN) { | 2307 | if (sent == -EAGAIN) { |
2326 | if (we_should_drop_the_connection(mdev, | 2308 | if (we_should_drop_the_connection(mdev, |
2327 | mdev->data.socket)) | 2309 | mdev->data.socket)) |
@@ -2350,9 +2332,11 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio) | |||
2350 | { | 2332 | { |
2351 | struct bio_vec *bvec; | 2333 | struct bio_vec *bvec; |
2352 | int i; | 2334 | int i; |
2335 | /* hint all but last page with MSG_MORE */ | ||
2353 | __bio_for_each_segment(bvec, bio, i, 0) { | 2336 | __bio_for_each_segment(bvec, bio, i, 0) { |
2354 | if (!_drbd_no_send_page(mdev, bvec->bv_page, | 2337 | if (!_drbd_no_send_page(mdev, bvec->bv_page, |
2355 | bvec->bv_offset, bvec->bv_len)) | 2338 | bvec->bv_offset, bvec->bv_len, |
2339 | i == bio->bi_vcnt -1 ? 0 : MSG_MORE)) | ||
2356 | return 0; | 2340 | return 0; |
2357 | } | 2341 | } |
2358 | return 1; | 2342 | return 1; |
@@ -2362,12 +2346,13 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) | |||
2362 | { | 2346 | { |
2363 | struct bio_vec *bvec; | 2347 | struct bio_vec *bvec; |
2364 | int i; | 2348 | int i; |
2349 | /* hint all but last page with MSG_MORE */ | ||
2365 | __bio_for_each_segment(bvec, bio, i, 0) { | 2350 | __bio_for_each_segment(bvec, bio, i, 0) { |
2366 | if (!_drbd_send_page(mdev, bvec->bv_page, | 2351 | if (!_drbd_send_page(mdev, bvec->bv_page, |
2367 | bvec->bv_offset, bvec->bv_len)) | 2352 | bvec->bv_offset, bvec->bv_len, |
2353 | i == bio->bi_vcnt -1 ? 0 : MSG_MORE)) | ||
2368 | return 0; | 2354 | return 0; |
2369 | } | 2355 | } |
2370 | |||
2371 | return 1; | 2356 | return 1; |
2372 | } | 2357 | } |
2373 | 2358 | ||
@@ -2375,9 +2360,11 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) | |||
2375 | { | 2360 | { |
2376 | struct page *page = e->pages; | 2361 | struct page *page = e->pages; |
2377 | unsigned len = e->size; | 2362 | unsigned len = e->size; |
2363 | /* hint all but last page with MSG_MORE */ | ||
2378 | page_chain_for_each(page) { | 2364 | page_chain_for_each(page) { |
2379 | unsigned l = min_t(unsigned, len, PAGE_SIZE); | 2365 | unsigned l = min_t(unsigned, len, PAGE_SIZE); |
2380 | if (!_drbd_send_page(mdev, page, 0, l)) | 2366 | if (!_drbd_send_page(mdev, page, 0, l, |
2367 | page_chain_next(page) ? MSG_MORE : 0)) | ||
2381 | return 0; | 2368 | return 0; |
2382 | len -= l; | 2369 | len -= l; |
2383 | } | 2370 | } |
@@ -2457,11 +2444,11 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) | |||
2457 | p.dp_flags = cpu_to_be32(dp_flags); | 2444 | p.dp_flags = cpu_to_be32(dp_flags); |
2458 | set_bit(UNPLUG_REMOTE, &mdev->flags); | 2445 | set_bit(UNPLUG_REMOTE, &mdev->flags); |
2459 | ok = (sizeof(p) == | 2446 | ok = (sizeof(p) == |
2460 | drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); | 2447 | drbd_send(mdev, mdev->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0)); |
2461 | if (ok && dgs) { | 2448 | if (ok && dgs) { |
2462 | dgb = mdev->int_dig_out; | 2449 | dgb = mdev->int_dig_out; |
2463 | drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); | 2450 | drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); |
2464 | ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); | 2451 | ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); |
2465 | } | 2452 | } |
2466 | if (ok) { | 2453 | if (ok) { |
2467 | if (mdev->net_conf->wire_protocol == DRBD_PROT_A) | 2454 | if (mdev->net_conf->wire_protocol == DRBD_PROT_A) |
@@ -2510,11 +2497,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, | |||
2510 | return 0; | 2497 | return 0; |
2511 | 2498 | ||
2512 | ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, | 2499 | ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, |
2513 | sizeof(p), MSG_MORE); | 2500 | sizeof(p), dgs ? MSG_MORE : 0); |
2514 | if (ok && dgs) { | 2501 | if (ok && dgs) { |
2515 | dgb = mdev->int_dig_out; | 2502 | dgb = mdev->int_dig_out; |
2516 | drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); | 2503 | drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); |
2517 | ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); | 2504 | ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); |
2518 | } | 2505 | } |
2519 | if (ok) | 2506 | if (ok) |
2520 | ok = _drbd_send_zc_ee(mdev, e); | 2507 | ok = _drbd_send_zc_ee(mdev, e); |
@@ -2708,7 +2695,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2708 | atomic_set(&mdev->net_cnt, 0); | 2695 | atomic_set(&mdev->net_cnt, 0); |
2709 | atomic_set(&mdev->packet_seq, 0); | 2696 | atomic_set(&mdev->packet_seq, 0); |
2710 | atomic_set(&mdev->pp_in_use, 0); | 2697 | atomic_set(&mdev->pp_in_use, 0); |
2711 | atomic_set(&mdev->new_c_uuid, 0); | ||
2712 | 2698 | ||
2713 | mutex_init(&mdev->md_io_mutex); | 2699 | mutex_init(&mdev->md_io_mutex); |
2714 | mutex_init(&mdev->data.mutex); | 2700 | mutex_init(&mdev->data.mutex); |
@@ -2739,14 +2725,12 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2739 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); | 2725 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); |
2740 | INIT_LIST_HEAD(&mdev->delay_probes); | 2726 | INIT_LIST_HEAD(&mdev->delay_probes); |
2741 | INIT_LIST_HEAD(&mdev->delay_probe_work.list); | 2727 | INIT_LIST_HEAD(&mdev->delay_probe_work.list); |
2742 | INIT_LIST_HEAD(&mdev->uuid_work.list); | ||
2743 | 2728 | ||
2744 | mdev->resync_work.cb = w_resync_inactive; | 2729 | mdev->resync_work.cb = w_resync_inactive; |
2745 | mdev->unplug_work.cb = w_send_write_hint; | 2730 | mdev->unplug_work.cb = w_send_write_hint; |
2746 | mdev->md_sync_work.cb = w_md_sync; | 2731 | mdev->md_sync_work.cb = w_md_sync; |
2747 | mdev->bm_io_work.w.cb = w_bitmap_io; | 2732 | mdev->bm_io_work.w.cb = w_bitmap_io; |
2748 | mdev->delay_probe_work.cb = w_delay_probes; | 2733 | mdev->delay_probe_work.cb = w_delay_probes; |
2749 | mdev->uuid_work.cb = w_new_current_uuid; | ||
2750 | init_timer(&mdev->resync_timer); | 2734 | init_timer(&mdev->resync_timer); |
2751 | init_timer(&mdev->md_sync_timer); | 2735 | init_timer(&mdev->md_sync_timer); |
2752 | init_timer(&mdev->delay_probe_timer); | 2736 | init_timer(&mdev->delay_probe_timer); |
@@ -3799,7 +3783,7 @@ _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) | |||
3799 | if (ret) { | 3783 | if (ret) { |
3800 | fault_count++; | 3784 | fault_count++; |
3801 | 3785 | ||
3802 | if (printk_ratelimit()) | 3786 | if (__ratelimit(&drbd_ratelimit_state)) |
3803 | dev_warn(DEV, "***Simulating %s failure\n", | 3787 | dev_warn(DEV, "***Simulating %s failure\n", |
3804 | _drbd_fault_str(type)); | 3788 | _drbd_fault_str(type)); |
3805 | } | 3789 | } |