aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_nl.c')
-rw-r--r--drivers/block/drbd/drbd_nl.c282
1 files changed, 219 insertions, 63 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 0bac9c8246bc..f35db29cac76 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -343,7 +343,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
343 (char[20]) { }, /* address family */ 343 (char[20]) { }, /* address family */
344 (char[60]) { }, /* address */ 344 (char[60]) { }, /* address */
345 NULL }; 345 NULL };
346 char mb[12]; 346 char mb[14];
347 char *argv[] = {usermode_helper, cmd, mb, NULL }; 347 char *argv[] = {usermode_helper, cmd, mb, NULL };
348 struct drbd_connection *connection = first_peer_device(device)->connection; 348 struct drbd_connection *connection = first_peer_device(device)->connection;
349 struct sib_info sib; 349 struct sib_info sib;
@@ -352,7 +352,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
352 if (current == connection->worker.task) 352 if (current == connection->worker.task)
353 set_bit(CALLBACK_PENDING, &connection->flags); 353 set_bit(CALLBACK_PENDING, &connection->flags);
354 354
355 snprintf(mb, 12, "minor-%d", device_to_minor(device)); 355 snprintf(mb, 14, "minor-%d", device_to_minor(device));
356 setup_khelper_env(connection, envp); 356 setup_khelper_env(connection, envp);
357 357
358 /* The helper may take some time. 358 /* The helper may take some time.
@@ -387,7 +387,7 @@ int drbd_khelper(struct drbd_device *device, char *cmd)
387 return ret; 387 return ret;
388} 388}
389 389
390static int conn_khelper(struct drbd_connection *connection, char *cmd) 390enum drbd_peer_state conn_khelper(struct drbd_connection *connection, char *cmd)
391{ 391{
392 char *envp[] = { "HOME=/", 392 char *envp[] = { "HOME=/",
393 "TERM=linux", 393 "TERM=linux",
@@ -442,19 +442,17 @@ static enum drbd_fencing_p highest_fencing_policy(struct drbd_connection *connec
442 } 442 }
443 rcu_read_unlock(); 443 rcu_read_unlock();
444 444
445 if (fp == FP_NOT_AVAIL) {
446 /* IO Suspending works on the whole resource.
447 Do it only for one device. */
448 vnr = 0;
449 peer_device = idr_get_next(&connection->peer_devices, &vnr);
450 drbd_change_state(peer_device->device, CS_VERBOSE | CS_HARD, NS(susp_fen, 0));
451 }
452
453 return fp; 445 return fp;
454} 446}
455 447
448static bool resource_is_supended(struct drbd_resource *resource)
449{
450 return resource->susp || resource->susp_fen || resource->susp_nod;
451}
452
456bool conn_try_outdate_peer(struct drbd_connection *connection) 453bool conn_try_outdate_peer(struct drbd_connection *connection)
457{ 454{
455 struct drbd_resource * const resource = connection->resource;
458 unsigned int connect_cnt; 456 unsigned int connect_cnt;
459 union drbd_state mask = { }; 457 union drbd_state mask = { };
460 union drbd_state val = { }; 458 union drbd_state val = { };
@@ -462,21 +460,41 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
462 char *ex_to_string; 460 char *ex_to_string;
463 int r; 461 int r;
464 462
465 spin_lock_irq(&connection->resource->req_lock); 463 spin_lock_irq(&resource->req_lock);
466 if (connection->cstate >= C_WF_REPORT_PARAMS) { 464 if (connection->cstate >= C_WF_REPORT_PARAMS) {
467 drbd_err(connection, "Expected cstate < C_WF_REPORT_PARAMS\n"); 465 drbd_err(connection, "Expected cstate < C_WF_REPORT_PARAMS\n");
468 spin_unlock_irq(&connection->resource->req_lock); 466 spin_unlock_irq(&resource->req_lock);
469 return false; 467 return false;
470 } 468 }
471 469
472 connect_cnt = connection->connect_cnt; 470 connect_cnt = connection->connect_cnt;
473 spin_unlock_irq(&connection->resource->req_lock); 471 spin_unlock_irq(&resource->req_lock);
474 472
475 fp = highest_fencing_policy(connection); 473 fp = highest_fencing_policy(connection);
476 switch (fp) { 474 switch (fp) {
477 case FP_NOT_AVAIL: 475 case FP_NOT_AVAIL:
478 drbd_warn(connection, "Not fencing peer, I'm not even Consistent myself.\n"); 476 drbd_warn(connection, "Not fencing peer, I'm not even Consistent myself.\n");
479 goto out; 477 spin_lock_irq(&resource->req_lock);
478 if (connection->cstate < C_WF_REPORT_PARAMS) {
479 _conn_request_state(connection,
480 (union drbd_state) { { .susp_fen = 1 } },
481 (union drbd_state) { { .susp_fen = 0 } },
482 CS_VERBOSE | CS_HARD | CS_DC_SUSP);
483 /* We are no longer suspended due to the fencing policy.
484 * We may still be suspended due to the on-no-data-accessible policy.
485 * If that was OND_IO_ERROR, fail pending requests. */
486 if (!resource_is_supended(resource))
487 _tl_restart(connection, CONNECTION_LOST_WHILE_PENDING);
488 }
489 /* Else: in case we raced with a connection handshake,
490 * let the handshake figure out if we maybe can RESEND,
491 * and do not resume/fail pending requests here.
492 * Worst case is we stay suspended for now, which may be
493 * resolved by either re-establishing the replication link, or
494 * the next link failure, or eventually the administrator. */
495 spin_unlock_irq(&resource->req_lock);
496 return false;
497
480 case FP_DONT_CARE: 498 case FP_DONT_CARE:
481 return true; 499 return true;
482 default: ; 500 default: ;
@@ -485,17 +503,17 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
485 r = conn_khelper(connection, "fence-peer"); 503 r = conn_khelper(connection, "fence-peer");
486 504
487 switch ((r>>8) & 0xff) { 505 switch ((r>>8) & 0xff) {
488 case 3: /* peer is inconsistent */ 506 case P_INCONSISTENT: /* peer is inconsistent */
489 ex_to_string = "peer is inconsistent or worse"; 507 ex_to_string = "peer is inconsistent or worse";
490 mask.pdsk = D_MASK; 508 mask.pdsk = D_MASK;
491 val.pdsk = D_INCONSISTENT; 509 val.pdsk = D_INCONSISTENT;
492 break; 510 break;
493 case 4: /* peer got outdated, or was already outdated */ 511 case P_OUTDATED: /* peer got outdated, or was already outdated */
494 ex_to_string = "peer was fenced"; 512 ex_to_string = "peer was fenced";
495 mask.pdsk = D_MASK; 513 mask.pdsk = D_MASK;
496 val.pdsk = D_OUTDATED; 514 val.pdsk = D_OUTDATED;
497 break; 515 break;
498 case 5: /* peer was down */ 516 case P_DOWN: /* peer was down */
499 if (conn_highest_disk(connection) == D_UP_TO_DATE) { 517 if (conn_highest_disk(connection) == D_UP_TO_DATE) {
500 /* we will(have) create(d) a new UUID anyways... */ 518 /* we will(have) create(d) a new UUID anyways... */
501 ex_to_string = "peer is unreachable, assumed to be dead"; 519 ex_to_string = "peer is unreachable, assumed to be dead";
@@ -505,7 +523,7 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
505 ex_to_string = "peer unreachable, doing nothing since disk != UpToDate"; 523 ex_to_string = "peer unreachable, doing nothing since disk != UpToDate";
506 } 524 }
507 break; 525 break;
508 case 6: /* Peer is primary, voluntarily outdate myself. 526 case P_PRIMARY: /* Peer is primary, voluntarily outdate myself.
509 * This is useful when an unconnected R_SECONDARY is asked to 527 * This is useful when an unconnected R_SECONDARY is asked to
510 * become R_PRIMARY, but finds the other peer being active. */ 528 * become R_PRIMARY, but finds the other peer being active. */
511 ex_to_string = "peer is active"; 529 ex_to_string = "peer is active";
@@ -513,7 +531,9 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
513 mask.disk = D_MASK; 531 mask.disk = D_MASK;
514 val.disk = D_OUTDATED; 532 val.disk = D_OUTDATED;
515 break; 533 break;
516 case 7: 534 case P_FENCING:
535 /* THINK: do we need to handle this
536 * like case 4, or more like case 5? */
517 if (fp != FP_STONITH) 537 if (fp != FP_STONITH)
518 drbd_err(connection, "fence-peer() = 7 && fencing != Stonith !!!\n"); 538 drbd_err(connection, "fence-peer() = 7 && fencing != Stonith !!!\n");
519 ex_to_string = "peer was stonithed"; 539 ex_to_string = "peer was stonithed";
@@ -529,13 +549,11 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
529 drbd_info(connection, "fence-peer helper returned %d (%s)\n", 549 drbd_info(connection, "fence-peer helper returned %d (%s)\n",
530 (r>>8) & 0xff, ex_to_string); 550 (r>>8) & 0xff, ex_to_string);
531 551
532 out:
533
534 /* Not using 552 /* Not using
535 conn_request_state(connection, mask, val, CS_VERBOSE); 553 conn_request_state(connection, mask, val, CS_VERBOSE);
536 here, because we might were able to re-establish the connection in the 554 here, because we might were able to re-establish the connection in the
537 meantime. */ 555 meantime. */
538 spin_lock_irq(&connection->resource->req_lock); 556 spin_lock_irq(&resource->req_lock);
539 if (connection->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &connection->flags)) { 557 if (connection->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &connection->flags)) {
540 if (connection->connect_cnt != connect_cnt) 558 if (connection->connect_cnt != connect_cnt)
541 /* In case the connection was established and droped 559 /* In case the connection was established and droped
@@ -544,7 +562,7 @@ bool conn_try_outdate_peer(struct drbd_connection *connection)
544 else 562 else
545 _conn_request_state(connection, mask, val, CS_VERBOSE); 563 _conn_request_state(connection, mask, val, CS_VERBOSE);
546 } 564 }
547 spin_unlock_irq(&connection->resource->req_lock); 565 spin_unlock_irq(&resource->req_lock);
548 566
549 return conn_highest_pdsk(connection) <= D_OUTDATED; 567 return conn_highest_pdsk(connection) <= D_OUTDATED;
550} 568}
@@ -1154,51 +1172,160 @@ static int drbd_check_al_size(struct drbd_device *device, struct disk_conf *dc)
1154 return 0; 1172 return 0;
1155} 1173}
1156 1174
1175static void blk_queue_discard_granularity(struct request_queue *q, unsigned int granularity)
1176{
1177 q->limits.discard_granularity = granularity;
1178}
1179
1180static unsigned int drbd_max_discard_sectors(struct drbd_connection *connection)
1181{
1182 /* when we introduced REQ_WRITE_SAME support, we also bumped
1183 * our maximum supported batch bio size used for discards. */
1184 if (connection->agreed_features & DRBD_FF_WSAME)
1185 return DRBD_MAX_BBIO_SECTORS;
1186 /* before, with DRBD <= 8.4.6, we only allowed up to one AL_EXTENT_SIZE. */
1187 return AL_EXTENT_SIZE >> 9;
1188}
1189
1190static void decide_on_discard_support(struct drbd_device *device,
1191 struct request_queue *q,
1192 struct request_queue *b,
1193 bool discard_zeroes_if_aligned)
1194{
1195 /* q = drbd device queue (device->rq_queue)
1196 * b = backing device queue (device->ldev->backing_bdev->bd_disk->queue),
1197 * or NULL if diskless
1198 */
1199 struct drbd_connection *connection = first_peer_device(device)->connection;
1200 bool can_do = b ? blk_queue_discard(b) : true;
1201
1202 if (can_do && b && !b->limits.discard_zeroes_data && !discard_zeroes_if_aligned) {
1203 can_do = false;
1204 drbd_info(device, "discard_zeroes_data=0 and discard_zeroes_if_aligned=no: disabling discards\n");
1205 }
1206 if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_TRIM)) {
1207 can_do = false;
1208 drbd_info(connection, "peer DRBD too old, does not support TRIM: disabling discards\n");
1209 }
1210 if (can_do) {
1211 /* We don't care for the granularity, really.
1212 * Stacking limits below should fix it for the local
1213 * device. Whether or not it is a suitable granularity
1214 * on the remote device is not our problem, really. If
1215 * you care, you need to use devices with similar
1216 * topology on all peers. */
1217 blk_queue_discard_granularity(q, 512);
1218 q->limits.max_discard_sectors = drbd_max_discard_sectors(connection);
1219 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
1220 } else {
1221 queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
1222 blk_queue_discard_granularity(q, 0);
1223 q->limits.max_discard_sectors = 0;
1224 }
1225}
1226
1227static void fixup_discard_if_not_supported(struct request_queue *q)
1228{
1229 /* To avoid confusion, if this queue does not support discard, clear
1230 * max_discard_sectors, which is what lsblk -D reports to the user.
1231 * Older kernels got this wrong in "stack limits".
1232 * */
1233 if (!blk_queue_discard(q)) {
1234 blk_queue_max_discard_sectors(q, 0);
1235 blk_queue_discard_granularity(q, 0);
1236 }
1237}
1238
1239static void decide_on_write_same_support(struct drbd_device *device,
1240 struct request_queue *q,
1241 struct request_queue *b, struct o_qlim *o)
1242{
1243 struct drbd_peer_device *peer_device = first_peer_device(device);
1244 struct drbd_connection *connection = peer_device->connection;
1245 bool can_do = b ? b->limits.max_write_same_sectors : true;
1246
1247 if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) {
1248 can_do = false;
1249 drbd_info(peer_device, "peer does not support WRITE_SAME\n");
1250 }
1251
1252 if (o) {
1253 /* logical block size; queue_logical_block_size(NULL) is 512 */
1254 unsigned int peer_lbs = be32_to_cpu(o->logical_block_size);
1255 unsigned int me_lbs_b = queue_logical_block_size(b);
1256 unsigned int me_lbs = queue_logical_block_size(q);
1257
1258 if (me_lbs_b != me_lbs) {
1259 drbd_warn(device,
1260 "logical block size of local backend does not match (drbd:%u, backend:%u); was this a late attach?\n",
1261 me_lbs, me_lbs_b);
1262 /* rather disable write same than trigger some BUG_ON later in the scsi layer. */
1263 can_do = false;
1264 }
1265 if (me_lbs_b != peer_lbs) {
1266 drbd_warn(peer_device, "logical block sizes do not match (me:%u, peer:%u); this may cause problems.\n",
1267 me_lbs, peer_lbs);
1268 if (can_do) {
1269 drbd_dbg(peer_device, "logical block size mismatch: WRITE_SAME disabled.\n");
1270 can_do = false;
1271 }
1272 me_lbs = max(me_lbs, me_lbs_b);
1273 /* We cannot change the logical block size of an in-use queue.
1274 * We can only hope that access happens to be properly aligned.
1275 * If not, the peer will likely produce an IO error, and detach. */
1276 if (peer_lbs > me_lbs) {
1277 if (device->state.role != R_PRIMARY) {
1278 blk_queue_logical_block_size(q, peer_lbs);
1279 drbd_warn(peer_device, "logical block size set to %u\n", peer_lbs);
1280 } else {
1281 drbd_warn(peer_device,
1282 "current Primary must NOT adjust logical block size (%u -> %u); hope for the best.\n",
1283 me_lbs, peer_lbs);
1284 }
1285 }
1286 }
1287 if (can_do && !o->write_same_capable) {
1288 /* If we introduce an open-coded write-same loop on the receiving side,
1289 * the peer would present itself as "capable". */
1290 drbd_dbg(peer_device, "WRITE_SAME disabled (peer device not capable)\n");
1291 can_do = false;
1292 }
1293 }
1294
1295 blk_queue_max_write_same_sectors(q, can_do ? DRBD_MAX_BBIO_SECTORS : 0);
1296}
1297
1157static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backing_dev *bdev, 1298static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backing_dev *bdev,
1158 unsigned int max_bio_size) 1299 unsigned int max_bio_size, struct o_qlim *o)
1159{ 1300{
1160 struct request_queue * const q = device->rq_queue; 1301 struct request_queue * const q = device->rq_queue;
1161 unsigned int max_hw_sectors = max_bio_size >> 9; 1302 unsigned int max_hw_sectors = max_bio_size >> 9;
1162 unsigned int max_segments = 0; 1303 unsigned int max_segments = 0;
1163 struct request_queue *b = NULL; 1304 struct request_queue *b = NULL;
1305 struct disk_conf *dc;
1306 bool discard_zeroes_if_aligned = true;
1164 1307
1165 if (bdev) { 1308 if (bdev) {
1166 b = bdev->backing_bdev->bd_disk->queue; 1309 b = bdev->backing_bdev->bd_disk->queue;
1167 1310
1168 max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9); 1311 max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
1169 rcu_read_lock(); 1312 rcu_read_lock();
1170 max_segments = rcu_dereference(device->ldev->disk_conf)->max_bio_bvecs; 1313 dc = rcu_dereference(device->ldev->disk_conf);
1314 max_segments = dc->max_bio_bvecs;
1315 discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned;
1171 rcu_read_unlock(); 1316 rcu_read_unlock();
1172 1317
1173 blk_set_stacking_limits(&q->limits); 1318 blk_set_stacking_limits(&q->limits);
1174 blk_queue_max_write_same_sectors(q, 0);
1175 } 1319 }
1176 1320
1177 blk_queue_logical_block_size(q, 512);
1178 blk_queue_max_hw_sectors(q, max_hw_sectors); 1321 blk_queue_max_hw_sectors(q, max_hw_sectors);
1179 /* This is the workaround for "bio would need to, but cannot, be split" */ 1322 /* This is the workaround for "bio would need to, but cannot, be split" */
1180 blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); 1323 blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
1181 blk_queue_segment_boundary(q, PAGE_SIZE-1); 1324 blk_queue_segment_boundary(q, PAGE_SIZE-1);
1325 decide_on_discard_support(device, q, b, discard_zeroes_if_aligned);
1326 decide_on_write_same_support(device, q, b, o);
1182 1327
1183 if (b) { 1328 if (b) {
1184 struct drbd_connection *connection = first_peer_device(device)->connection;
1185
1186 blk_queue_max_discard_sectors(q, DRBD_MAX_DISCARD_SECTORS);
1187
1188 if (blk_queue_discard(b) &&
1189 (connection->cstate < C_CONNECTED || connection->agreed_features & FF_TRIM)) {
1190 /* We don't care, stacking below should fix it for the local device.
1191 * Whether or not it is a suitable granularity on the remote device
1192 * is not our problem, really. If you care, you need to
1193 * use devices with similar topology on all peers. */
1194 q->limits.discard_granularity = 512;
1195 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
1196 } else {
1197 blk_queue_max_discard_sectors(q, 0);
1198 queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
1199 q->limits.discard_granularity = 0;
1200 }
1201
1202 blk_queue_stack_limits(q, b); 1329 blk_queue_stack_limits(q, b);
1203 1330
1204 if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) { 1331 if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
@@ -1208,15 +1335,10 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
1208 q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages; 1335 q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
1209 } 1336 }
1210 } 1337 }
1211 /* To avoid confusion, if this queue does not support discard, clear 1338 fixup_discard_if_not_supported(q);
1212 * max_discard_sectors, which is what lsblk -D reports to the user. */
1213 if (!blk_queue_discard(q)) {
1214 blk_queue_max_discard_sectors(q, 0);
1215 q->limits.discard_granularity = 0;
1216 }
1217} 1339}
1218 1340
1219void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backing_dev *bdev) 1341void drbd_reconsider_queue_parameters(struct drbd_device *device, struct drbd_backing_dev *bdev, struct o_qlim *o)
1220{ 1342{
1221 unsigned int now, new, local, peer; 1343 unsigned int now, new, local, peer;
1222 1344
@@ -1259,7 +1381,7 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backin
1259 if (new != now) 1381 if (new != now)
1260 drbd_info(device, "max BIO size = %u\n", new); 1382 drbd_info(device, "max BIO size = %u\n", new);
1261 1383
1262 drbd_setup_queue_param(device, bdev, new); 1384 drbd_setup_queue_param(device, bdev, new, o);
1263} 1385}
1264 1386
1265/* Starts the worker thread */ 1387/* Starts the worker thread */
@@ -1348,6 +1470,43 @@ static bool write_ordering_changed(struct disk_conf *a, struct disk_conf *b)
1348 a->disk_drain != b->disk_drain; 1470 a->disk_drain != b->disk_drain;
1349} 1471}
1350 1472
1473static void sanitize_disk_conf(struct drbd_device *device, struct disk_conf *disk_conf,
1474 struct drbd_backing_dev *nbc)
1475{
1476 struct request_queue * const q = nbc->backing_bdev->bd_disk->queue;
1477
1478 if (disk_conf->al_extents < DRBD_AL_EXTENTS_MIN)
1479 disk_conf->al_extents = DRBD_AL_EXTENTS_MIN;
1480 if (disk_conf->al_extents > drbd_al_extents_max(nbc))
1481 disk_conf->al_extents = drbd_al_extents_max(nbc);
1482
1483 if (!blk_queue_discard(q)
1484 || (!q->limits.discard_zeroes_data && !disk_conf->discard_zeroes_if_aligned)) {
1485 if (disk_conf->rs_discard_granularity) {
1486 disk_conf->rs_discard_granularity = 0; /* disable feature */
1487 drbd_info(device, "rs_discard_granularity feature disabled\n");
1488 }
1489 }
1490
1491 if (disk_conf->rs_discard_granularity) {
1492 int orig_value = disk_conf->rs_discard_granularity;
1493 int remainder;
1494
1495 if (q->limits.discard_granularity > disk_conf->rs_discard_granularity)
1496 disk_conf->rs_discard_granularity = q->limits.discard_granularity;
1497
1498 remainder = disk_conf->rs_discard_granularity % q->limits.discard_granularity;
1499 disk_conf->rs_discard_granularity += remainder;
1500
1501 if (disk_conf->rs_discard_granularity > q->limits.max_discard_sectors << 9)
1502 disk_conf->rs_discard_granularity = q->limits.max_discard_sectors << 9;
1503
1504 if (disk_conf->rs_discard_granularity != orig_value)
1505 drbd_info(device, "rs_discard_granularity changed to %d\n",
1506 disk_conf->rs_discard_granularity);
1507 }
1508}
1509
1351int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) 1510int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
1352{ 1511{
1353 struct drbd_config_context adm_ctx; 1512 struct drbd_config_context adm_ctx;
@@ -1395,10 +1554,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
1395 if (!expect(new_disk_conf->resync_rate >= 1)) 1554 if (!expect(new_disk_conf->resync_rate >= 1))
1396 new_disk_conf->resync_rate = 1; 1555 new_disk_conf->resync_rate = 1;
1397 1556
1398 if (new_disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) 1557 sanitize_disk_conf(device, new_disk_conf, device->ldev);
1399 new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN;
1400 if (new_disk_conf->al_extents > drbd_al_extents_max(device->ldev))
1401 new_disk_conf->al_extents = drbd_al_extents_max(device->ldev);
1402 1558
1403 if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX) 1559 if (new_disk_conf->c_plan_ahead > DRBD_C_PLAN_AHEAD_MAX)
1404 new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX; 1560 new_disk_conf->c_plan_ahead = DRBD_C_PLAN_AHEAD_MAX;
@@ -1457,6 +1613,9 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
1457 if (write_ordering_changed(old_disk_conf, new_disk_conf)) 1613 if (write_ordering_changed(old_disk_conf, new_disk_conf))
1458 drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH); 1614 drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH);
1459 1615
1616 if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned)
1617 drbd_reconsider_queue_parameters(device, device->ldev, NULL);
1618
1460 drbd_md_sync(device); 1619 drbd_md_sync(device);
1461 1620
1462 if (device->state.conn >= C_CONNECTED) { 1621 if (device->state.conn >= C_CONNECTED) {
@@ -1693,10 +1852,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
1693 if (retcode != NO_ERROR) 1852 if (retcode != NO_ERROR)
1694 goto fail; 1853 goto fail;
1695 1854
1696 if (new_disk_conf->al_extents < DRBD_AL_EXTENTS_MIN) 1855 sanitize_disk_conf(device, new_disk_conf, nbc);
1697 new_disk_conf->al_extents = DRBD_AL_EXTENTS_MIN;
1698 if (new_disk_conf->al_extents > drbd_al_extents_max(nbc))
1699 new_disk_conf->al_extents = drbd_al_extents_max(nbc);
1700 1856
1701 if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) { 1857 if (drbd_get_max_capacity(nbc) < new_disk_conf->disk_size) {
1702 drbd_err(device, "max capacity %llu smaller than disk size %llu\n", 1858 drbd_err(device, "max capacity %llu smaller than disk size %llu\n",
@@ -1838,7 +1994,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
1838 device->read_cnt = 0; 1994 device->read_cnt = 0;
1839 device->writ_cnt = 0; 1995 device->writ_cnt = 0;
1840 1996
1841 drbd_reconsider_max_bio_size(device, device->ldev); 1997 drbd_reconsider_queue_parameters(device, device->ldev, NULL);
1842 1998
1843 /* If I am currently not R_PRIMARY, 1999 /* If I am currently not R_PRIMARY,
1844 * but meta data primary indicator is set, 2000 * but meta data primary indicator is set,