aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-06-25 13:15:58 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-07-24 09:14:00 -0400
commitdb141b2f42b485b700465fe2401fbe65c65b190c (patch)
tree2af5670c18463173c7b9f5450bf09a90e463f986 /drivers/block
parent7ee1fb93f390f7a7231abec4e34e6ab20abeed45 (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.h8
-rw-r--r--drivers/block/drbd/drbd_main.c11
-rw-r--r--drivers/block/drbd/drbd_nl.c13
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
1143static inline struct drbd_conf *minor_to_mdev(unsigned int minor) 1143static 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)
801static void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size) 801static 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
836void drbd_reconsider_max_bio_size(struct drbd_conf *mdev) 836void 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);