diff options
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 216 |
1 files changed, 152 insertions, 64 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 352441b0f92f..c07c370c4c82 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -337,13 +337,25 @@ static inline void bm_xfer_ctx_bit_to_word_offset(struct bm_xfer_ctx *c) | |||
337 | * NOTE that the payload starts at a long aligned offset, | 337 | * NOTE that the payload starts at a long aligned offset, |
338 | * regardless of 32 or 64 bit arch! | 338 | * regardless of 32 or 64 bit arch! |
339 | */ | 339 | */ |
340 | struct p_header { | 340 | struct p_header80 { |
341 | u32 magic; | 341 | u32 magic; |
342 | u16 command; | 342 | u16 command; |
343 | u16 length; /* bytes of data after this header */ | 343 | u16 length; /* bytes of data after this header */ |
344 | u8 payload[0]; | 344 | u8 payload[0]; |
345 | } __packed; | 345 | } __packed; |
346 | /* 8 bytes. packet FIXED for the next century! */ | 346 | |
347 | /* Header for big packets, Used for data packets exceeding 64kB */ | ||
348 | struct p_header95 { | ||
349 | u16 magic; /* use DRBD_MAGIC_BIG here */ | ||
350 | u16 command; | ||
351 | u32 length; /* Use only 24 bits of that. Ignore the highest 8 bit. */ | ||
352 | u8 payload[0]; | ||
353 | } __packed; | ||
354 | |||
355 | union p_header { | ||
356 | struct p_header80 h80; | ||
357 | struct p_header95 h95; | ||
358 | }; | ||
347 | 359 | ||
348 | /* | 360 | /* |
349 | * short commands, packets without payload, plain p_header: | 361 | * short commands, packets without payload, plain p_header: |
@@ -362,12 +374,16 @@ struct p_header { | |||
362 | */ | 374 | */ |
363 | 375 | ||
364 | /* these defines must not be changed without changing the protocol version */ | 376 | /* these defines must not be changed without changing the protocol version */ |
365 | #define DP_HARDBARRIER 1 | 377 | #define DP_HARDBARRIER 1 /* depricated */ |
366 | #define DP_RW_SYNC 2 | 378 | #define DP_RW_SYNC 2 /* equals REQ_SYNC */ |
367 | #define DP_MAY_SET_IN_SYNC 4 | 379 | #define DP_MAY_SET_IN_SYNC 4 |
380 | #define DP_UNPLUG 8 /* equals REQ_UNPLUG */ | ||
381 | #define DP_FUA 16 /* equals REQ_FUA */ | ||
382 | #define DP_FLUSH 32 /* equals REQ_FLUSH */ | ||
383 | #define DP_DISCARD 64 /* equals REQ_DISCARD */ | ||
368 | 384 | ||
369 | struct p_data { | 385 | struct p_data { |
370 | struct p_header head; | 386 | union p_header head; |
371 | u64 sector; /* 64 bits sector number */ | 387 | u64 sector; /* 64 bits sector number */ |
372 | u64 block_id; /* to identify the request in protocol B&C */ | 388 | u64 block_id; /* to identify the request in protocol B&C */ |
373 | u32 seq_num; | 389 | u32 seq_num; |
@@ -383,7 +399,7 @@ struct p_data { | |||
383 | * P_DATA_REQUEST, P_RS_DATA_REQUEST | 399 | * P_DATA_REQUEST, P_RS_DATA_REQUEST |
384 | */ | 400 | */ |
385 | struct p_block_ack { | 401 | struct p_block_ack { |
386 | struct p_header head; | 402 | struct p_header80 head; |
387 | u64 sector; | 403 | u64 sector; |
388 | u64 block_id; | 404 | u64 block_id; |
389 | u32 blksize; | 405 | u32 blksize; |
@@ -392,7 +408,7 @@ struct p_block_ack { | |||
392 | 408 | ||
393 | 409 | ||
394 | struct p_block_req { | 410 | struct p_block_req { |
395 | struct p_header head; | 411 | struct p_header80 head; |
396 | u64 sector; | 412 | u64 sector; |
397 | u64 block_id; | 413 | u64 block_id; |
398 | u32 blksize; | 414 | u32 blksize; |
@@ -409,7 +425,7 @@ struct p_block_req { | |||
409 | */ | 425 | */ |
410 | 426 | ||
411 | struct p_handshake { | 427 | struct p_handshake { |
412 | struct p_header head; /* 8 bytes */ | 428 | struct p_header80 head; /* 8 bytes */ |
413 | u32 protocol_min; | 429 | u32 protocol_min; |
414 | u32 feature_flags; | 430 | u32 feature_flags; |
415 | u32 protocol_max; | 431 | u32 protocol_max; |
@@ -424,19 +440,19 @@ struct p_handshake { | |||
424 | /* 80 bytes, FIXED for the next century */ | 440 | /* 80 bytes, FIXED for the next century */ |
425 | 441 | ||
426 | struct p_barrier { | 442 | struct p_barrier { |
427 | struct p_header head; | 443 | struct p_header80 head; |
428 | u32 barrier; /* barrier number _handle_ only */ | 444 | u32 barrier; /* barrier number _handle_ only */ |
429 | u32 pad; /* to multiple of 8 Byte */ | 445 | u32 pad; /* to multiple of 8 Byte */ |
430 | } __packed; | 446 | } __packed; |
431 | 447 | ||
432 | struct p_barrier_ack { | 448 | struct p_barrier_ack { |
433 | struct p_header head; | 449 | struct p_header80 head; |
434 | u32 barrier; | 450 | u32 barrier; |
435 | u32 set_size; | 451 | u32 set_size; |
436 | } __packed; | 452 | } __packed; |
437 | 453 | ||
438 | struct p_rs_param { | 454 | struct p_rs_param { |
439 | struct p_header head; | 455 | struct p_header80 head; |
440 | u32 rate; | 456 | u32 rate; |
441 | 457 | ||
442 | /* Since protocol version 88 and higher. */ | 458 | /* Since protocol version 88 and higher. */ |
@@ -444,20 +460,31 @@ struct p_rs_param { | |||
444 | } __packed; | 460 | } __packed; |
445 | 461 | ||
446 | struct p_rs_param_89 { | 462 | struct p_rs_param_89 { |
447 | struct p_header head; | 463 | struct p_header80 head; |
448 | u32 rate; | 464 | u32 rate; |
449 | /* protocol version 89: */ | 465 | /* protocol version 89: */ |
450 | char verify_alg[SHARED_SECRET_MAX]; | 466 | char verify_alg[SHARED_SECRET_MAX]; |
451 | char csums_alg[SHARED_SECRET_MAX]; | 467 | char csums_alg[SHARED_SECRET_MAX]; |
452 | } __packed; | 468 | } __packed; |
453 | 469 | ||
470 | struct p_rs_param_95 { | ||
471 | struct p_header80 head; | ||
472 | u32 rate; | ||
473 | char verify_alg[SHARED_SECRET_MAX]; | ||
474 | char csums_alg[SHARED_SECRET_MAX]; | ||
475 | u32 c_plan_ahead; | ||
476 | u32 c_delay_target; | ||
477 | u32 c_fill_target; | ||
478 | u32 c_max_rate; | ||
479 | } __packed; | ||
480 | |||
454 | enum drbd_conn_flags { | 481 | enum drbd_conn_flags { |
455 | CF_WANT_LOSE = 1, | 482 | CF_WANT_LOSE = 1, |
456 | CF_DRY_RUN = 2, | 483 | CF_DRY_RUN = 2, |
457 | }; | 484 | }; |
458 | 485 | ||
459 | struct p_protocol { | 486 | struct p_protocol { |
460 | struct p_header head; | 487 | struct p_header80 head; |
461 | u32 protocol; | 488 | u32 protocol; |
462 | u32 after_sb_0p; | 489 | u32 after_sb_0p; |
463 | u32 after_sb_1p; | 490 | u32 after_sb_1p; |
@@ -471,17 +498,17 @@ struct p_protocol { | |||
471 | } __packed; | 498 | } __packed; |
472 | 499 | ||
473 | struct p_uuids { | 500 | struct p_uuids { |
474 | struct p_header head; | 501 | struct p_header80 head; |
475 | u64 uuid[UI_EXTENDED_SIZE]; | 502 | u64 uuid[UI_EXTENDED_SIZE]; |
476 | } __packed; | 503 | } __packed; |
477 | 504 | ||
478 | struct p_rs_uuid { | 505 | struct p_rs_uuid { |
479 | struct p_header head; | 506 | struct p_header80 head; |
480 | u64 uuid; | 507 | u64 uuid; |
481 | } __packed; | 508 | } __packed; |
482 | 509 | ||
483 | struct p_sizes { | 510 | struct p_sizes { |
484 | struct p_header head; | 511 | struct p_header80 head; |
485 | u64 d_size; /* size of disk */ | 512 | u64 d_size; /* size of disk */ |
486 | u64 u_size; /* user requested size */ | 513 | u64 u_size; /* user requested size */ |
487 | u64 c_size; /* current exported size */ | 514 | u64 c_size; /* current exported size */ |
@@ -491,18 +518,18 @@ struct p_sizes { | |||
491 | } __packed; | 518 | } __packed; |
492 | 519 | ||
493 | struct p_state { | 520 | struct p_state { |
494 | struct p_header head; | 521 | struct p_header80 head; |
495 | u32 state; | 522 | u32 state; |
496 | } __packed; | 523 | } __packed; |
497 | 524 | ||
498 | struct p_req_state { | 525 | struct p_req_state { |
499 | struct p_header head; | 526 | struct p_header80 head; |
500 | u32 mask; | 527 | u32 mask; |
501 | u32 val; | 528 | u32 val; |
502 | } __packed; | 529 | } __packed; |
503 | 530 | ||
504 | struct p_req_state_reply { | 531 | struct p_req_state_reply { |
505 | struct p_header head; | 532 | struct p_header80 head; |
506 | u32 retcode; | 533 | u32 retcode; |
507 | } __packed; | 534 | } __packed; |
508 | 535 | ||
@@ -517,7 +544,7 @@ struct p_drbd06_param { | |||
517 | } __packed; | 544 | } __packed; |
518 | 545 | ||
519 | struct p_discard { | 546 | struct p_discard { |
520 | struct p_header head; | 547 | struct p_header80 head; |
521 | u64 block_id; | 548 | u64 block_id; |
522 | u32 seq_num; | 549 | u32 seq_num; |
523 | u32 pad; | 550 | u32 pad; |
@@ -533,7 +560,7 @@ enum drbd_bitmap_code { | |||
533 | }; | 560 | }; |
534 | 561 | ||
535 | struct p_compressed_bm { | 562 | struct p_compressed_bm { |
536 | struct p_header head; | 563 | struct p_header80 head; |
537 | /* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code | 564 | /* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code |
538 | * (encoding & 0x80): polarity (set/unset) of first runlength | 565 | * (encoding & 0x80): polarity (set/unset) of first runlength |
539 | * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits | 566 | * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits |
@@ -544,10 +571,10 @@ struct p_compressed_bm { | |||
544 | u8 code[0]; | 571 | u8 code[0]; |
545 | } __packed; | 572 | } __packed; |
546 | 573 | ||
547 | struct p_delay_probe { | 574 | struct p_delay_probe93 { |
548 | struct p_header head; | 575 | struct p_header80 head; |
549 | u32 seq_num; /* sequence number to match the two probe packets */ | 576 | u32 seq_num; /* sequence number to match the two probe packets */ |
550 | u32 offset; /* usecs the probe got sent after the reference time point */ | 577 | u32 offset; /* usecs the probe got sent after the reference time point */ |
551 | } __packed; | 578 | } __packed; |
552 | 579 | ||
553 | /* DCBP: Drbd Compressed Bitmap Packet ... */ | 580 | /* DCBP: Drbd Compressed Bitmap Packet ... */ |
@@ -594,7 +621,7 @@ DCBP_set_pad_bits(struct p_compressed_bm *p, int n) | |||
594 | * so we need to use the fixed size 4KiB page size | 621 | * so we need to use the fixed size 4KiB page size |
595 | * most architechtures have used for a long time. | 622 | * most architechtures have used for a long time. |
596 | */ | 623 | */ |
597 | #define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header)) | 624 | #define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header80)) |
598 | #define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long)) | 625 | #define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long)) |
599 | #define BM_PACKET_VLI_BYTES_MAX (4096 - sizeof(struct p_compressed_bm)) | 626 | #define BM_PACKET_VLI_BYTES_MAX (4096 - sizeof(struct p_compressed_bm)) |
600 | #if (PAGE_SIZE < 4096) | 627 | #if (PAGE_SIZE < 4096) |
@@ -603,13 +630,14 @@ DCBP_set_pad_bits(struct p_compressed_bm *p, int n) | |||
603 | #endif | 630 | #endif |
604 | 631 | ||
605 | union p_polymorph { | 632 | union p_polymorph { |
606 | struct p_header header; | 633 | union p_header header; |
607 | struct p_handshake handshake; | 634 | struct p_handshake handshake; |
608 | struct p_data data; | 635 | struct p_data data; |
609 | struct p_block_ack block_ack; | 636 | struct p_block_ack block_ack; |
610 | struct p_barrier barrier; | 637 | struct p_barrier barrier; |
611 | struct p_barrier_ack barrier_ack; | 638 | struct p_barrier_ack barrier_ack; |
612 | struct p_rs_param_89 rs_param_89; | 639 | struct p_rs_param_89 rs_param_89; |
640 | struct p_rs_param_95 rs_param_95; | ||
613 | struct p_protocol protocol; | 641 | struct p_protocol protocol; |
614 | struct p_sizes sizes; | 642 | struct p_sizes sizes; |
615 | struct p_uuids uuids; | 643 | struct p_uuids uuids; |
@@ -617,6 +645,8 @@ union p_polymorph { | |||
617 | struct p_req_state req_state; | 645 | struct p_req_state req_state; |
618 | struct p_req_state_reply req_state_reply; | 646 | struct p_req_state_reply req_state_reply; |
619 | struct p_block_req block_req; | 647 | struct p_block_req block_req; |
648 | struct p_delay_probe93 delay_probe93; | ||
649 | struct p_rs_uuid rs_uuid; | ||
620 | } __packed; | 650 | } __packed; |
621 | 651 | ||
622 | /**********************************************************************/ | 652 | /**********************************************************************/ |
@@ -697,7 +727,7 @@ struct drbd_tl_epoch { | |||
697 | struct list_head requests; /* requests before */ | 727 | struct list_head requests; /* requests before */ |
698 | struct drbd_tl_epoch *next; /* pointer to the next barrier */ | 728 | struct drbd_tl_epoch *next; /* pointer to the next barrier */ |
699 | unsigned int br_number; /* the barriers identifier. */ | 729 | unsigned int br_number; /* the barriers identifier. */ |
700 | int n_req; /* number of requests attached before this barrier */ | 730 | int n_writes; /* number of requests attached before this barrier */ |
701 | }; | 731 | }; |
702 | 732 | ||
703 | struct drbd_request; | 733 | struct drbd_request; |
@@ -747,7 +777,7 @@ struct digest_info { | |||
747 | struct drbd_epoch_entry { | 777 | struct drbd_epoch_entry { |
748 | struct drbd_work w; | 778 | struct drbd_work w; |
749 | struct hlist_node colision; | 779 | struct hlist_node colision; |
750 | struct drbd_epoch *epoch; | 780 | struct drbd_epoch *epoch; /* for writes */ |
751 | struct drbd_conf *mdev; | 781 | struct drbd_conf *mdev; |
752 | struct page *pages; | 782 | struct page *pages; |
753 | atomic_t pending_bios; | 783 | atomic_t pending_bios; |
@@ -755,7 +785,10 @@ struct drbd_epoch_entry { | |||
755 | /* see comments on ee flag bits below */ | 785 | /* see comments on ee flag bits below */ |
756 | unsigned long flags; | 786 | unsigned long flags; |
757 | sector_t sector; | 787 | sector_t sector; |
758 | u64 block_id; | 788 | union { |
789 | u64 block_id; | ||
790 | struct digest_info *digest; | ||
791 | }; | ||
759 | }; | 792 | }; |
760 | 793 | ||
761 | /* ee flag bits. | 794 | /* ee flag bits. |
@@ -781,12 +814,16 @@ enum { | |||
781 | * if any of those fail, we set this flag atomically | 814 | * if any of those fail, we set this flag atomically |
782 | * from the endio callback */ | 815 | * from the endio callback */ |
783 | __EE_WAS_ERROR, | 816 | __EE_WAS_ERROR, |
817 | |||
818 | /* This ee has a pointer to a digest instead of a block id */ | ||
819 | __EE_HAS_DIGEST, | ||
784 | }; | 820 | }; |
785 | #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) | 821 | #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) |
786 | #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) | 822 | #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) |
787 | #define EE_IS_BARRIER (1<<__EE_IS_BARRIER) | 823 | #define EE_IS_BARRIER (1<<__EE_IS_BARRIER) |
788 | #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) | 824 | #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) |
789 | #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) | 825 | #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) |
826 | #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) | ||
790 | 827 | ||
791 | /* global flag bits */ | 828 | /* global flag bits */ |
792 | enum { | 829 | enum { |
@@ -794,7 +831,6 @@ enum { | |||
794 | SIGNAL_ASENDER, /* whether asender wants to be interrupted */ | 831 | SIGNAL_ASENDER, /* whether asender wants to be interrupted */ |
795 | SEND_PING, /* whether asender should send a ping asap */ | 832 | SEND_PING, /* whether asender should send a ping asap */ |
796 | 833 | ||
797 | STOP_SYNC_TIMER, /* tell timer to cancel itself */ | ||
798 | UNPLUG_QUEUED, /* only relevant with kernel 2.4 */ | 834 | UNPLUG_QUEUED, /* only relevant with kernel 2.4 */ |
799 | UNPLUG_REMOTE, /* sending a "UnplugRemote" could help */ | 835 | UNPLUG_REMOTE, /* sending a "UnplugRemote" could help */ |
800 | MD_DIRTY, /* current uuids and flags not yet on disk */ | 836 | MD_DIRTY, /* current uuids and flags not yet on disk */ |
@@ -816,6 +852,7 @@ enum { | |||
816 | BITMAP_IO, /* suspend application io; | 852 | BITMAP_IO, /* suspend application io; |
817 | once no more io in flight, start bitmap io */ | 853 | once no more io in flight, start bitmap io */ |
818 | BITMAP_IO_QUEUED, /* Started bitmap IO */ | 854 | BITMAP_IO_QUEUED, /* Started bitmap IO */ |
855 | GO_DISKLESS, /* Disk failed, local_cnt reached zero, we are going diskless */ | ||
819 | RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ | 856 | RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ |
820 | NET_CONGESTED, /* The data socket is congested */ | 857 | NET_CONGESTED, /* The data socket is congested */ |
821 | 858 | ||
@@ -829,6 +866,8 @@ enum { | |||
829 | * the peer, if it changed there as well. */ | 866 | * the peer, if it changed there as well. */ |
830 | CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ | 867 | CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ |
831 | GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ | 868 | GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ |
869 | NEW_CUR_UUID, /* Create new current UUID when thawing IO */ | ||
870 | AL_SUSPENDED, /* Activity logging is currently suspended. */ | ||
832 | }; | 871 | }; |
833 | 872 | ||
834 | struct drbd_bitmap; /* opaque for drbd_conf */ | 873 | struct drbd_bitmap; /* opaque for drbd_conf */ |
@@ -838,10 +877,6 @@ struct drbd_bitmap; /* opaque for drbd_conf */ | |||
838 | 877 | ||
839 | /* THINK maybe we actually want to use the default "event/%s" worker threads | 878 | /* THINK maybe we actually want to use the default "event/%s" worker threads |
840 | * or similar in linux 2.6, which uses per cpu data and threads. | 879 | * or similar in linux 2.6, which uses per cpu data and threads. |
841 | * | ||
842 | * To be general, this might need a spin_lock member. | ||
843 | * For now, please use the mdev->req_lock to protect list_head, | ||
844 | * see drbd_queue_work below. | ||
845 | */ | 880 | */ |
846 | struct drbd_work_queue { | 881 | struct drbd_work_queue { |
847 | struct list_head q; | 882 | struct list_head q; |
@@ -915,6 +950,12 @@ enum write_ordering_e { | |||
915 | WO_bio_barrier | 950 | WO_bio_barrier |
916 | }; | 951 | }; |
917 | 952 | ||
953 | struct fifo_buffer { | ||
954 | int *values; | ||
955 | unsigned int head_index; | ||
956 | unsigned int size; | ||
957 | }; | ||
958 | |||
918 | struct drbd_conf { | 959 | struct drbd_conf { |
919 | /* things that are stored as / read from meta data on disk */ | 960 | /* things that are stored as / read from meta data on disk */ |
920 | unsigned long flags; | 961 | unsigned long flags; |
@@ -936,9 +977,16 @@ struct drbd_conf { | |||
936 | unsigned int ko_count; | 977 | unsigned int ko_count; |
937 | struct drbd_work resync_work, | 978 | struct drbd_work resync_work, |
938 | unplug_work, | 979 | unplug_work, |
980 | go_diskless, | ||
939 | md_sync_work; | 981 | md_sync_work; |
940 | struct timer_list resync_timer; | 982 | struct timer_list resync_timer; |
941 | struct timer_list md_sync_timer; | 983 | struct timer_list md_sync_timer; |
984 | #ifdef DRBD_DEBUG_MD_SYNC | ||
985 | struct { | ||
986 | unsigned int line; | ||
987 | const char* func; | ||
988 | } last_md_mark_dirty; | ||
989 | #endif | ||
942 | 990 | ||
943 | /* Used after attach while negotiating new disk state. */ | 991 | /* Used after attach while negotiating new disk state. */ |
944 | union drbd_state new_state_tmp; | 992 | union drbd_state new_state_tmp; |
@@ -946,6 +994,7 @@ struct drbd_conf { | |||
946 | union drbd_state state; | 994 | union drbd_state state; |
947 | wait_queue_head_t misc_wait; | 995 | wait_queue_head_t misc_wait; |
948 | wait_queue_head_t state_wait; /* upon each state change. */ | 996 | wait_queue_head_t state_wait; /* upon each state change. */ |
997 | wait_queue_head_t net_cnt_wait; | ||
949 | unsigned int send_cnt; | 998 | unsigned int send_cnt; |
950 | unsigned int recv_cnt; | 999 | unsigned int recv_cnt; |
951 | unsigned int read_cnt; | 1000 | unsigned int read_cnt; |
@@ -974,12 +1023,16 @@ struct drbd_conf { | |||
974 | unsigned long rs_start; | 1023 | unsigned long rs_start; |
975 | /* cumulated time in PausedSyncX state [unit jiffies] */ | 1024 | /* cumulated time in PausedSyncX state [unit jiffies] */ |
976 | unsigned long rs_paused; | 1025 | unsigned long rs_paused; |
1026 | /* skipped because csum was equal [unit BM_BLOCK_SIZE] */ | ||
1027 | unsigned long rs_same_csum; | ||
1028 | #define DRBD_SYNC_MARKS 8 | ||
1029 | #define DRBD_SYNC_MARK_STEP (3*HZ) | ||
977 | /* block not up-to-date at mark [unit BM_BLOCK_SIZE] */ | 1030 | /* block not up-to-date at mark [unit BM_BLOCK_SIZE] */ |
978 | unsigned long rs_mark_left; | 1031 | unsigned long rs_mark_left[DRBD_SYNC_MARKS]; |
979 | /* marks's time [unit jiffies] */ | 1032 | /* marks's time [unit jiffies] */ |
980 | unsigned long rs_mark_time; | 1033 | unsigned long rs_mark_time[DRBD_SYNC_MARKS]; |
981 | /* skipped because csum was equeal [unit BM_BLOCK_SIZE] */ | 1034 | /* current index into rs_mark_{left,time} */ |
982 | unsigned long rs_same_csum; | 1035 | int rs_last_mark; |
983 | 1036 | ||
984 | /* where does the admin want us to start? (sector) */ | 1037 | /* where does the admin want us to start? (sector) */ |
985 | sector_t ov_start_sector; | 1038 | sector_t ov_start_sector; |
@@ -1012,10 +1065,10 @@ struct drbd_conf { | |||
1012 | spinlock_t epoch_lock; | 1065 | spinlock_t epoch_lock; |
1013 | unsigned int epochs; | 1066 | unsigned int epochs; |
1014 | enum write_ordering_e write_ordering; | 1067 | enum write_ordering_e write_ordering; |
1015 | struct list_head active_ee; /* IO in progress */ | 1068 | struct list_head active_ee; /* IO in progress (P_DATA gets written to disk) */ |
1016 | struct list_head sync_ee; /* IO in progress */ | 1069 | struct list_head sync_ee; /* IO in progress (P_RS_DATA_REPLY gets written to disk) */ |
1017 | struct list_head done_ee; /* send ack */ | 1070 | struct list_head done_ee; /* send ack */ |
1018 | struct list_head read_ee; /* IO in progress */ | 1071 | struct list_head read_ee; /* IO in progress (any read) */ |
1019 | struct list_head net_ee; /* zero-copy network send in progress */ | 1072 | struct list_head net_ee; /* zero-copy network send in progress */ |
1020 | struct hlist_head *ee_hash; /* is proteced by req_lock! */ | 1073 | struct hlist_head *ee_hash; /* is proteced by req_lock! */ |
1021 | unsigned int ee_hash_s; | 1074 | unsigned int ee_hash_s; |
@@ -1026,7 +1079,8 @@ struct drbd_conf { | |||
1026 | int next_barrier_nr; | 1079 | int next_barrier_nr; |
1027 | struct hlist_head *app_reads_hash; /* is proteced by req_lock */ | 1080 | struct hlist_head *app_reads_hash; /* is proteced by req_lock */ |
1028 | struct list_head resync_reads; | 1081 | struct list_head resync_reads; |
1029 | atomic_t pp_in_use; | 1082 | atomic_t pp_in_use; /* allocated from page pool */ |
1083 | atomic_t pp_in_use_by_net; /* sendpage()d, still referenced by tcp */ | ||
1030 | wait_queue_head_t ee_wait; | 1084 | wait_queue_head_t ee_wait; |
1031 | struct page *md_io_page; /* one page buffer for md_io */ | 1085 | struct page *md_io_page; /* one page buffer for md_io */ |
1032 | struct page *md_io_tmpp; /* for logical_block_size != 512 */ | 1086 | struct page *md_io_tmpp; /* for logical_block_size != 512 */ |
@@ -1054,6 +1108,15 @@ struct drbd_conf { | |||
1054 | u64 ed_uuid; /* UUID of the exposed data */ | 1108 | u64 ed_uuid; /* UUID of the exposed data */ |
1055 | struct mutex state_mutex; | 1109 | struct mutex state_mutex; |
1056 | char congestion_reason; /* Why we where congested... */ | 1110 | char congestion_reason; /* Why we where congested... */ |
1111 | atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */ | ||
1112 | atomic_t rs_sect_ev; /* for submitted resync data rate, both */ | ||
1113 | int rs_last_sect_ev; /* counter to compare with */ | ||
1114 | int rs_last_events; /* counter of read or write "events" (unit sectors) | ||
1115 | * on the lower level device when we last looked. */ | ||
1116 | int c_sync_rate; /* current resync rate after syncer throttle magic */ | ||
1117 | struct fifo_buffer rs_plan_s; /* correction values of resync planer */ | ||
1118 | int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ | ||
1119 | int rs_planed; /* resync sectors already planed */ | ||
1057 | }; | 1120 | }; |
1058 | 1121 | ||
1059 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) | 1122 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) |
@@ -1138,6 +1201,8 @@ extern void drbd_free_resources(struct drbd_conf *mdev); | |||
1138 | extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, | 1201 | extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, |
1139 | unsigned int set_size); | 1202 | unsigned int set_size); |
1140 | extern void tl_clear(struct drbd_conf *mdev); | 1203 | extern void tl_clear(struct drbd_conf *mdev); |
1204 | enum drbd_req_event; | ||
1205 | extern void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what); | ||
1141 | extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *); | 1206 | extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *); |
1142 | extern void drbd_free_sock(struct drbd_conf *mdev); | 1207 | extern void drbd_free_sock(struct drbd_conf *mdev); |
1143 | extern int drbd_send(struct drbd_conf *mdev, struct socket *sock, | 1208 | extern int drbd_send(struct drbd_conf *mdev, struct socket *sock, |
@@ -1150,12 +1215,12 @@ extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_f | |||
1150 | extern int _drbd_send_state(struct drbd_conf *mdev); | 1215 | extern int _drbd_send_state(struct drbd_conf *mdev); |
1151 | extern int drbd_send_state(struct drbd_conf *mdev); | 1216 | extern int drbd_send_state(struct drbd_conf *mdev); |
1152 | extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, | 1217 | extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, |
1153 | enum drbd_packets cmd, struct p_header *h, | 1218 | enum drbd_packets cmd, struct p_header80 *h, |
1154 | size_t size, unsigned msg_flags); | 1219 | size_t size, unsigned msg_flags); |
1155 | #define USE_DATA_SOCKET 1 | 1220 | #define USE_DATA_SOCKET 1 |
1156 | #define USE_META_SOCKET 0 | 1221 | #define USE_META_SOCKET 0 |
1157 | extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket, | 1222 | extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket, |
1158 | enum drbd_packets cmd, struct p_header *h, | 1223 | enum drbd_packets cmd, struct p_header80 *h, |
1159 | size_t size); | 1224 | size_t size); |
1160 | extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, | 1225 | extern int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, |
1161 | char *data, size_t size); | 1226 | char *data, size_t size); |
@@ -1167,7 +1232,7 @@ extern int drbd_send_ack(struct drbd_conf *mdev, enum drbd_packets cmd, | |||
1167 | extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd, | 1232 | extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum drbd_packets cmd, |
1168 | struct p_block_req *rp); | 1233 | struct p_block_req *rp); |
1169 | extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd, | 1234 | extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum drbd_packets cmd, |
1170 | struct p_data *dp); | 1235 | struct p_data *dp, int data_size); |
1171 | extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd, | 1236 | extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum drbd_packets cmd, |
1172 | sector_t sector, int blksize, u64 block_id); | 1237 | sector_t sector, int blksize, u64 block_id); |
1173 | extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, | 1238 | extern int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, |
@@ -1201,7 +1266,13 @@ extern void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) | |||
1201 | extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local); | 1266 | extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local); |
1202 | extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local); | 1267 | extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local); |
1203 | extern int drbd_md_test_flag(struct drbd_backing_dev *, int); | 1268 | extern int drbd_md_test_flag(struct drbd_backing_dev *, int); |
1269 | #ifndef DRBD_DEBUG_MD_SYNC | ||
1204 | extern void drbd_md_mark_dirty(struct drbd_conf *mdev); | 1270 | extern void drbd_md_mark_dirty(struct drbd_conf *mdev); |
1271 | #else | ||
1272 | #define drbd_md_mark_dirty(m) drbd_md_mark_dirty_(m, __LINE__ , __func__ ) | ||
1273 | extern void drbd_md_mark_dirty_(struct drbd_conf *mdev, | ||
1274 | unsigned int line, const char *func); | ||
1275 | #endif | ||
1205 | extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, | 1276 | extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, |
1206 | int (*io_fn)(struct drbd_conf *), | 1277 | int (*io_fn)(struct drbd_conf *), |
1207 | void (*done)(struct drbd_conf *, int), | 1278 | void (*done)(struct drbd_conf *, int), |
@@ -1209,6 +1280,7 @@ extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, | |||
1209 | extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); | 1280 | extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); |
1210 | extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); | 1281 | extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); |
1211 | extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); | 1282 | extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); |
1283 | extern void drbd_go_diskless(struct drbd_conf *mdev); | ||
1212 | 1284 | ||
1213 | 1285 | ||
1214 | /* Meta data layout | 1286 | /* Meta data layout |
@@ -1264,6 +1336,8 @@ struct bm_extent { | |||
1264 | * Bit 1 ==> local node thinks this block needs to be synced. | 1336 | * Bit 1 ==> local node thinks this block needs to be synced. |
1265 | */ | 1337 | */ |
1266 | 1338 | ||
1339 | #define SLEEP_TIME (HZ/10) | ||
1340 | |||
1267 | #define BM_BLOCK_SHIFT 12 /* 4k per bit */ | 1341 | #define BM_BLOCK_SHIFT 12 /* 4k per bit */ |
1268 | #define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT) | 1342 | #define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT) |
1269 | /* (9+3) : 512 bytes @ 8 bits; representing 16M storage | 1343 | /* (9+3) : 512 bytes @ 8 bits; representing 16M storage |
@@ -1335,11 +1409,13 @@ struct bm_extent { | |||
1335 | #endif | 1409 | #endif |
1336 | 1410 | ||
1337 | /* Sector shift value for the "hash" functions of tl_hash and ee_hash tables. | 1411 | /* Sector shift value for the "hash" functions of tl_hash and ee_hash tables. |
1338 | * With a value of 6 all IO in one 32K block make it to the same slot of the | 1412 | * With a value of 8 all IO in one 128K block make it to the same slot of the |
1339 | * hash table. */ | 1413 | * hash table. */ |
1340 | #define HT_SHIFT 6 | 1414 | #define HT_SHIFT 8 |
1341 | #define DRBD_MAX_SEGMENT_SIZE (1U<<(9+HT_SHIFT)) | 1415 | #define DRBD_MAX_SEGMENT_SIZE (1U<<(9+HT_SHIFT)) |
1342 | 1416 | ||
1417 | #define DRBD_MAX_SIZE_H80_PACKET (1 << 15) /* The old header only allows packets up to 32Kib data */ | ||
1418 | |||
1343 | /* Number of elements in the app_reads_hash */ | 1419 | /* Number of elements in the app_reads_hash */ |
1344 | #define APP_R_HSIZE 15 | 1420 | #define APP_R_HSIZE 15 |
1345 | 1421 | ||
@@ -1369,6 +1445,7 @@ extern unsigned long drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_ | |||
1369 | /* bm_find_next variants for use while you hold drbd_bm_lock() */ | 1445 | /* bm_find_next variants for use while you hold drbd_bm_lock() */ |
1370 | extern unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo); | 1446 | extern unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo); |
1371 | extern unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo); | 1447 | extern unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo); |
1448 | extern unsigned long _drbd_bm_total_weight(struct drbd_conf *mdev); | ||
1372 | extern unsigned long drbd_bm_total_weight(struct drbd_conf *mdev); | 1449 | extern unsigned long drbd_bm_total_weight(struct drbd_conf *mdev); |
1373 | extern int drbd_bm_rs_done(struct drbd_conf *mdev); | 1450 | extern int drbd_bm_rs_done(struct drbd_conf *mdev); |
1374 | /* for receive_bitmap */ | 1451 | /* for receive_bitmap */ |
@@ -1421,7 +1498,8 @@ extern void resync_after_online_grow(struct drbd_conf *); | |||
1421 | extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local); | 1498 | extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local); |
1422 | extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, | 1499 | extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, |
1423 | int force); | 1500 | int force); |
1424 | enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev); | 1501 | extern enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev); |
1502 | extern void drbd_try_outdate_peer_async(struct drbd_conf *mdev); | ||
1425 | extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); | 1503 | extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); |
1426 | 1504 | ||
1427 | /* drbd_worker.c */ | 1505 | /* drbd_worker.c */ |
@@ -1467,10 +1545,12 @@ extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int); | |||
1467 | extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int); | 1545 | extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int); |
1468 | extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int); | 1546 | extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int); |
1469 | extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int); | 1547 | extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int); |
1548 | extern int w_restart_disk_io(struct drbd_conf *, struct drbd_work *, int); | ||
1470 | 1549 | ||
1471 | extern void resync_timer_fn(unsigned long data); | 1550 | extern void resync_timer_fn(unsigned long data); |
1472 | 1551 | ||
1473 | /* drbd_receiver.c */ | 1552 | /* drbd_receiver.c */ |
1553 | extern int drbd_rs_should_slow_down(struct drbd_conf *mdev); | ||
1474 | extern int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, | 1554 | extern int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, |
1475 | const unsigned rw, const int fault_type); | 1555 | const unsigned rw, const int fault_type); |
1476 | extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); | 1556 | extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); |
@@ -1479,7 +1559,10 @@ extern struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, | |||
1479 | sector_t sector, | 1559 | sector_t sector, |
1480 | unsigned int data_size, | 1560 | unsigned int data_size, |
1481 | gfp_t gfp_mask) __must_hold(local); | 1561 | gfp_t gfp_mask) __must_hold(local); |
1482 | extern void drbd_free_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e); | 1562 | extern void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, |
1563 | int is_net); | ||
1564 | #define drbd_free_ee(m,e) drbd_free_some_ee(m, e, 0) | ||
1565 | #define drbd_free_net_ee(m,e) drbd_free_some_ee(m, e, 1) | ||
1483 | extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev, | 1566 | extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev, |
1484 | struct list_head *head); | 1567 | struct list_head *head); |
1485 | extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, | 1568 | extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, |
@@ -1487,6 +1570,7 @@ extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, | |||
1487 | extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled); | 1570 | extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled); |
1488 | extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed); | 1571 | extern void _drbd_clear_done_ee(struct drbd_conf *mdev, struct list_head *to_be_freed); |
1489 | extern void drbd_flush_workqueue(struct drbd_conf *mdev); | 1572 | extern void drbd_flush_workqueue(struct drbd_conf *mdev); |
1573 | extern void drbd_free_tl_hash(struct drbd_conf *mdev); | ||
1490 | 1574 | ||
1491 | /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to | 1575 | /* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to |
1492 | * mess with get_fs/set_fs, we know we are KERNEL_DS always. */ | 1576 | * mess with get_fs/set_fs, we know we are KERNEL_DS always. */ |
@@ -1600,6 +1684,8 @@ void drbd_bcast_ee(struct drbd_conf *mdev, | |||
1600 | #define susp_MASK 1 | 1684 | #define susp_MASK 1 |
1601 | #define user_isp_MASK 1 | 1685 | #define user_isp_MASK 1 |
1602 | #define aftr_isp_MASK 1 | 1686 | #define aftr_isp_MASK 1 |
1687 | #define susp_nod_MASK 1 | ||
1688 | #define susp_fen_MASK 1 | ||
1603 | 1689 | ||
1604 | #define NS(T, S) \ | 1690 | #define NS(T, S) \ |
1605 | ({ union drbd_state mask; mask.i = 0; mask.T = T##_MASK; mask; }), \ | 1691 | ({ union drbd_state mask; mask.i = 0; mask.T = T##_MASK; mask; }), \ |
@@ -1856,13 +1942,6 @@ static inline sector_t drbd_md_ss__(struct drbd_conf *mdev, | |||
1856 | } | 1942 | } |
1857 | 1943 | ||
1858 | static inline void | 1944 | static inline void |
1859 | _drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) | ||
1860 | { | ||
1861 | list_add_tail(&w->list, &q->q); | ||
1862 | up(&q->s); | ||
1863 | } | ||
1864 | |||
1865 | static inline void | ||
1866 | drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w) | 1945 | drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w) |
1867 | { | 1946 | { |
1868 | unsigned long flags; | 1947 | unsigned long flags; |
@@ -1899,19 +1978,19 @@ static inline void request_ping(struct drbd_conf *mdev) | |||
1899 | static inline int drbd_send_short_cmd(struct drbd_conf *mdev, | 1978 | static inline int drbd_send_short_cmd(struct drbd_conf *mdev, |
1900 | enum drbd_packets cmd) | 1979 | enum drbd_packets cmd) |
1901 | { | 1980 | { |
1902 | struct p_header h; | 1981 | struct p_header80 h; |
1903 | return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h)); | 1982 | return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h)); |
1904 | } | 1983 | } |
1905 | 1984 | ||
1906 | static inline int drbd_send_ping(struct drbd_conf *mdev) | 1985 | static inline int drbd_send_ping(struct drbd_conf *mdev) |
1907 | { | 1986 | { |
1908 | struct p_header h; | 1987 | struct p_header80 h; |
1909 | return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING, &h, sizeof(h)); | 1988 | return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING, &h, sizeof(h)); |
1910 | } | 1989 | } |
1911 | 1990 | ||
1912 | static inline int drbd_send_ping_ack(struct drbd_conf *mdev) | 1991 | static inline int drbd_send_ping_ack(struct drbd_conf *mdev) |
1913 | { | 1992 | { |
1914 | struct p_header h; | 1993 | struct p_header80 h; |
1915 | return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h)); | 1994 | return drbd_send_cmd(mdev, USE_META_SOCKET, P_PING_ACK, &h, sizeof(h)); |
1916 | } | 1995 | } |
1917 | 1996 | ||
@@ -2013,7 +2092,7 @@ static inline void inc_unacked(struct drbd_conf *mdev) | |||
2013 | static inline void put_net_conf(struct drbd_conf *mdev) | 2092 | static inline void put_net_conf(struct drbd_conf *mdev) |
2014 | { | 2093 | { |
2015 | if (atomic_dec_and_test(&mdev->net_cnt)) | 2094 | if (atomic_dec_and_test(&mdev->net_cnt)) |
2016 | wake_up(&mdev->misc_wait); | 2095 | wake_up(&mdev->net_cnt_wait); |
2017 | } | 2096 | } |
2018 | 2097 | ||
2019 | /** | 2098 | /** |
@@ -2044,10 +2123,14 @@ static inline int get_net_conf(struct drbd_conf *mdev) | |||
2044 | 2123 | ||
2045 | static inline void put_ldev(struct drbd_conf *mdev) | 2124 | static inline void put_ldev(struct drbd_conf *mdev) |
2046 | { | 2125 | { |
2126 | int i = atomic_dec_return(&mdev->local_cnt); | ||
2047 | __release(local); | 2127 | __release(local); |
2048 | if (atomic_dec_and_test(&mdev->local_cnt)) | 2128 | D_ASSERT(i >= 0); |
2129 | if (i == 0) { | ||
2130 | if (mdev->state.disk == D_FAILED) | ||
2131 | drbd_go_diskless(mdev); | ||
2049 | wake_up(&mdev->misc_wait); | 2132 | wake_up(&mdev->misc_wait); |
2050 | D_ASSERT(atomic_read(&mdev->local_cnt) >= 0); | 2133 | } |
2051 | } | 2134 | } |
2052 | 2135 | ||
2053 | #ifndef __CHECKER__ | 2136 | #ifndef __CHECKER__ |
@@ -2179,11 +2262,16 @@ static inline int drbd_state_is_stable(union drbd_state s) | |||
2179 | return 1; | 2262 | return 1; |
2180 | } | 2263 | } |
2181 | 2264 | ||
2265 | static inline int is_susp(union drbd_state s) | ||
2266 | { | ||
2267 | return s.susp || s.susp_nod || s.susp_fen; | ||
2268 | } | ||
2269 | |||
2182 | static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) | 2270 | static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) |
2183 | { | 2271 | { |
2184 | int mxb = drbd_get_max_buffers(mdev); | 2272 | int mxb = drbd_get_max_buffers(mdev); |
2185 | 2273 | ||
2186 | if (mdev->state.susp) | 2274 | if (is_susp(mdev->state)) |
2187 | return 0; | 2275 | return 0; |
2188 | if (test_bit(SUSPEND_IO, &mdev->flags)) | 2276 | if (test_bit(SUSPEND_IO, &mdev->flags)) |
2189 | return 0; | 2277 | return 0; |