diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-06-25 13:15:58 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-07-24 09:14:00 -0400 |
commit | db141b2f42b485b700465fe2401fbe65c65b190c (patch) | |
tree | 2af5670c18463173c7b9f5450bf09a90e463f986 /drivers/block | |
parent | 7ee1fb93f390f7a7231abec4e34e6ab20abeed45 (diff) |
drbd: fix max_bio_size to be unsigned
We capped our max_bio_size respectively max_hw_sectors with
min_t(int, lower level limit, our limit);
unfortunately, some drivers, e.g. the kvm virtio block driver, initialize their
limits to "-1U", and that is of course a smaller "int" value than our limit.
Impact: we started to request 16 MB resync requests,
which lead to protocol error and a reconnect loop.
Fix all relevant constants and parameters to be unsigned int.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 8 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 11 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 13 |
3 files changed, 17 insertions, 15 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2704af2ccf61..b2ca143d0053 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1136,8 +1136,8 @@ struct drbd_conf { | |||
1136 | int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ | 1136 | int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ |
1137 | int rs_planed; /* resync sectors already planned */ | 1137 | int rs_planed; /* resync sectors already planned */ |
1138 | atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ | 1138 | atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ |
1139 | int peer_max_bio_size; | 1139 | unsigned int peer_max_bio_size; |
1140 | int local_max_bio_size; | 1140 | unsigned int local_max_bio_size; |
1141 | }; | 1141 | }; |
1142 | 1142 | ||
1143 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) | 1143 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) |
@@ -1441,9 +1441,9 @@ struct bm_extent { | |||
1441 | * hash table. */ | 1441 | * hash table. */ |
1442 | #define HT_SHIFT 8 | 1442 | #define HT_SHIFT 8 |
1443 | #define DRBD_MAX_BIO_SIZE (1U<<(9+HT_SHIFT)) | 1443 | #define DRBD_MAX_BIO_SIZE (1U<<(9+HT_SHIFT)) |
1444 | #define DRBD_MAX_BIO_SIZE_SAFE (1 << 12) /* Works always = 4k */ | 1444 | #define DRBD_MAX_BIO_SIZE_SAFE (1U << 12) /* Works always = 4k */ |
1445 | 1445 | ||
1446 | #define DRBD_MAX_SIZE_H80_PACKET (1 << 15) /* The old header only allows packets up to 32Kib data */ | 1446 | #define DRBD_MAX_SIZE_H80_PACKET (1U << 15) /* The old header only allows packets up to 32Kib data */ |
1447 | 1447 | ||
1448 | /* Number of elements in the app_reads_hash */ | 1448 | /* Number of elements in the app_reads_hash */ |
1449 | #define APP_R_HSIZE 15 | 1449 | #define APP_R_HSIZE 15 |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 29a276425079..1ee1404769c2 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2209,7 +2209,8 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl | |||
2209 | { | 2209 | { |
2210 | struct p_sizes p; | 2210 | struct p_sizes p; |
2211 | sector_t d_size, u_size; | 2211 | sector_t d_size, u_size; |
2212 | int q_order_type, max_bio_size; | 2212 | int q_order_type; |
2213 | unsigned int max_bio_size; | ||
2213 | int ok; | 2214 | int ok; |
2214 | 2215 | ||
2215 | if (get_ldev_if_state(mdev, D_NEGOTIATING)) { | 2216 | if (get_ldev_if_state(mdev, D_NEGOTIATING)) { |
@@ -2218,7 +2219,7 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl | |||
2218 | u_size = mdev->ldev->dc.disk_size; | 2219 | u_size = mdev->ldev->dc.disk_size; |
2219 | q_order_type = drbd_queue_order_type(mdev); | 2220 | q_order_type = drbd_queue_order_type(mdev); |
2220 | max_bio_size = queue_max_hw_sectors(mdev->ldev->backing_bdev->bd_disk->queue) << 9; | 2221 | max_bio_size = queue_max_hw_sectors(mdev->ldev->backing_bdev->bd_disk->queue) << 9; |
2221 | max_bio_size = min_t(int, max_bio_size, DRBD_MAX_BIO_SIZE); | 2222 | max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE); |
2222 | put_ldev(mdev); | 2223 | put_ldev(mdev); |
2223 | } else { | 2224 | } else { |
2224 | d_size = 0; | 2225 | d_size = 0; |
@@ -2229,7 +2230,7 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags fl | |||
2229 | 2230 | ||
2230 | /* Never allow old drbd (up to 8.3.7) to see more than 32KiB */ | 2231 | /* Never allow old drbd (up to 8.3.7) to see more than 32KiB */ |
2231 | if (mdev->agreed_pro_version <= 94) | 2232 | if (mdev->agreed_pro_version <= 94) |
2232 | max_bio_size = min_t(int, max_bio_size, DRBD_MAX_SIZE_H80_PACKET); | 2233 | max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET); |
2233 | 2234 | ||
2234 | p.d_size = cpu_to_be64(d_size); | 2235 | p.d_size = cpu_to_be64(d_size); |
2235 | p.u_size = cpu_to_be64(u_size); | 2236 | p.u_size = cpu_to_be64(u_size); |
@@ -3981,9 +3982,9 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) | |||
3981 | 3982 | ||
3982 | spin_lock_irq(&mdev->req_lock); | 3983 | spin_lock_irq(&mdev->req_lock); |
3983 | if (mdev->state.conn < C_CONNECTED) { | 3984 | if (mdev->state.conn < C_CONNECTED) { |
3984 | int peer; | 3985 | unsigned int peer; |
3985 | peer = be32_to_cpu(buffer->la_peer_max_bio_size); | 3986 | peer = be32_to_cpu(buffer->la_peer_max_bio_size); |
3986 | peer = max_t(int, peer, DRBD_MAX_BIO_SIZE_SAFE); | 3987 | peer = max(peer, DRBD_MAX_BIO_SIZE_SAFE); |
3987 | mdev->peer_max_bio_size = peer; | 3988 | mdev->peer_max_bio_size = peer; |
3988 | } | 3989 | } |
3989 | spin_unlock_irq(&mdev->req_lock); | 3990 | spin_unlock_irq(&mdev->req_lock); |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index c47df7cf7f80..fb9dce8daa24 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -801,8 +801,8 @@ static int drbd_check_al_size(struct drbd_conf *mdev) | |||
801 | static void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size) | 801 | static void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size) |
802 | { | 802 | { |
803 | struct request_queue * const q = mdev->rq_queue; | 803 | struct request_queue * const q = mdev->rq_queue; |
804 | int max_hw_sectors = max_bio_size >> 9; | 804 | unsigned int max_hw_sectors = max_bio_size >> 9; |
805 | int max_segments = 0; | 805 | unsigned int max_segments = 0; |
806 | 806 | ||
807 | if (get_ldev_if_state(mdev, D_ATTACHING)) { | 807 | if (get_ldev_if_state(mdev, D_ATTACHING)) { |
808 | struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue; | 808 | struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue; |
@@ -835,7 +835,7 @@ static void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_ | |||
835 | 835 | ||
836 | void drbd_reconsider_max_bio_size(struct drbd_conf *mdev) | 836 | void drbd_reconsider_max_bio_size(struct drbd_conf *mdev) |
837 | { | 837 | { |
838 | int now, new, local, peer; | 838 | unsigned int now, new, local, peer; |
839 | 839 | ||
840 | now = queue_max_hw_sectors(mdev->rq_queue) << 9; | 840 | now = queue_max_hw_sectors(mdev->rq_queue) << 9; |
841 | local = mdev->local_max_bio_size; /* Eventually last known value, from volatile memory */ | 841 | local = mdev->local_max_bio_size; /* Eventually last known value, from volatile memory */ |
@@ -846,13 +846,14 @@ void drbd_reconsider_max_bio_size(struct drbd_conf *mdev) | |||
846 | mdev->local_max_bio_size = local; | 846 | mdev->local_max_bio_size = local; |
847 | put_ldev(mdev); | 847 | put_ldev(mdev); |
848 | } | 848 | } |
849 | local = min(local, DRBD_MAX_BIO_SIZE); | ||
849 | 850 | ||
850 | /* We may ignore peer limits if the peer is modern enough. | 851 | /* We may ignore peer limits if the peer is modern enough. |
851 | Because new from 8.3.8 onwards the peer can use multiple | 852 | Because new from 8.3.8 onwards the peer can use multiple |
852 | BIOs for a single peer_request */ | 853 | BIOs for a single peer_request */ |
853 | if (mdev->state.conn >= C_CONNECTED) { | 854 | if (mdev->state.conn >= C_CONNECTED) { |
854 | if (mdev->agreed_pro_version < 94) { | 855 | if (mdev->agreed_pro_version < 94) { |
855 | peer = min_t(int, mdev->peer_max_bio_size, DRBD_MAX_SIZE_H80_PACKET); | 856 | peer = min(mdev->peer_max_bio_size, DRBD_MAX_SIZE_H80_PACKET); |
856 | /* Correct old drbd (up to 8.3.7) if it believes it can do more than 32KiB */ | 857 | /* Correct old drbd (up to 8.3.7) if it believes it can do more than 32KiB */ |
857 | } else if (mdev->agreed_pro_version == 94) | 858 | } else if (mdev->agreed_pro_version == 94) |
858 | peer = DRBD_MAX_SIZE_H80_PACKET; | 859 | peer = DRBD_MAX_SIZE_H80_PACKET; |
@@ -860,10 +861,10 @@ void drbd_reconsider_max_bio_size(struct drbd_conf *mdev) | |||
860 | peer = DRBD_MAX_BIO_SIZE; | 861 | peer = DRBD_MAX_BIO_SIZE; |
861 | } | 862 | } |
862 | 863 | ||
863 | new = min_t(int, local, peer); | 864 | new = min(local, peer); |
864 | 865 | ||
865 | if (mdev->state.role == R_PRIMARY && new < now) | 866 | if (mdev->state.role == R_PRIMARY && new < now) |
866 | dev_err(DEV, "ASSERT FAILED new < now; (%d < %d)\n", new, now); | 867 | dev_err(DEV, "ASSERT FAILED new < now; (%u < %u)\n", new, now); |
867 | 868 | ||
868 | if (new != now) | 869 | if (new != now) |
869 | dev_info(DEV, "max BIO size = %u\n", new); | 870 | dev_info(DEV, "max BIO size = %u\n", new); |