@@ -1154,6 +1154,59 @@ static int drbd_check_al_size(struct drbd_device *device, struct disk_conf *dc)
1154
1154
return 0 ;
1155
1155
}
1156
1156
1157
+ static void blk_queue_discard_granularity (struct request_queue * q , unsigned int granularity )
1158
+ {
1159
+ q -> limits .discard_granularity = granularity ;
1160
+ }
1161
+ static void decide_on_discard_support (struct drbd_device * device ,
1162
+ struct request_queue * q ,
1163
+ struct request_queue * b ,
1164
+ bool discard_zeroes_if_aligned )
1165
+ {
1166
+ /* q = drbd device queue (device->rq_queue)
1167
+ * b = backing device queue (device->ldev->backing_bdev->bd_disk->queue),
1168
+ * or NULL if diskless
1169
+ */
1170
+ struct drbd_connection * connection = first_peer_device (device )-> connection ;
1171
+ bool can_do = b ? blk_queue_discard (b ) : true;
1172
+
1173
+ if (can_do && b && !b -> limits .discard_zeroes_data && !discard_zeroes_if_aligned ) {
1174
+ can_do = false;
1175
+ drbd_info (device , "discard_zeroes_data=0 and discard_zeroes_if_aligned=no: disabling discards\n" );
1176
+ }
1177
+ if (can_do && connection -> cstate >= C_CONNECTED && !(connection -> agreed_features & FF_TRIM )) {
1178
+ can_do = false;
1179
+ drbd_info (connection , "peer DRBD too old, does not support TRIM: disabling discards\n" );
1180
+ }
1181
+ if (can_do ) {
1182
+ /* We don't care for the granularity, really.
1183
+ * Stacking limits below should fix it for the local
1184
+ * device. Whether or not it is a suitable granularity
1185
+ * on the remote device is not our problem, really. If
1186
+ * you care, you need to use devices with similar
1187
+ * topology on all peers. */
1188
+ blk_queue_discard_granularity (q , 512 );
1189
+ q -> limits .max_discard_sectors = DRBD_MAX_DISCARD_SECTORS ;
1190
+ queue_flag_set_unlocked (QUEUE_FLAG_DISCARD , q );
1191
+ } else {
1192
+ queue_flag_clear_unlocked (QUEUE_FLAG_DISCARD , q );
1193
+ blk_queue_discard_granularity (q , 0 );
1194
+ q -> limits .max_discard_sectors = 0 ;
1195
+ }
1196
+ }
1197
+
1198
+ static void fixup_discard_if_not_supported (struct request_queue * q )
1199
+ {
1200
+ /* To avoid confusion, if this queue does not support discard, clear
1201
+ * max_discard_sectors, which is what lsblk -D reports to the user.
1202
+ * Older kernels got this wrong in "stack limits".
1203
+ * */
1204
+ if (!blk_queue_discard (q )) {
1205
+ blk_queue_max_discard_sectors (q , 0 );
1206
+ blk_queue_discard_granularity (q , 0 );
1207
+ }
1208
+ }
1209
+
1157
1210
static void drbd_setup_queue_param (struct drbd_device * device , struct drbd_backing_dev * bdev ,
1158
1211
unsigned int max_bio_size )
1159
1212
{
@@ -1183,26 +1236,8 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
1183
1236
/* This is the workaround for "bio would need to, but cannot, be split" */
1184
1237
blk_queue_max_segments (q , max_segments ? max_segments : BLK_MAX_SEGMENTS );
1185
1238
blk_queue_segment_boundary (q , PAGE_SIZE - 1 );
1186
-
1239
+ decide_on_discard_support ( device , q , b , discard_zeroes_if_aligned );
1187
1240
if (b ) {
1188
- struct drbd_connection * connection = first_peer_device (device )-> connection ;
1189
-
1190
- blk_queue_max_discard_sectors (q , DRBD_MAX_DISCARD_SECTORS );
1191
-
1192
- if (blk_queue_discard (b ) && (b -> limits .discard_zeroes_data || discard_zeroes_if_aligned ) &&
1193
- (connection -> cstate < C_CONNECTED || connection -> agreed_features & FF_TRIM )) {
1194
- /* We don't care, stacking below should fix it for the local device.
1195
- * Whether or not it is a suitable granularity on the remote device
1196
- * is not our problem, really. If you care, you need to
1197
- * use devices with similar topology on all peers. */
1198
- q -> limits .discard_granularity = 512 ;
1199
- queue_flag_set_unlocked (QUEUE_FLAG_DISCARD , q );
1200
- } else {
1201
- blk_queue_max_discard_sectors (q , 0 );
1202
- queue_flag_clear_unlocked (QUEUE_FLAG_DISCARD , q );
1203
- q -> limits .discard_granularity = 0 ;
1204
- }
1205
-
1206
1241
blk_queue_stack_limits (q , b );
1207
1242
1208
1243
if (q -> backing_dev_info .ra_pages != b -> backing_dev_info .ra_pages ) {
@@ -1212,12 +1247,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
1212
1247
q -> backing_dev_info .ra_pages = b -> backing_dev_info .ra_pages ;
1213
1248
}
1214
1249
}
1215
- /* To avoid confusion, if this queue does not support discard, clear
1216
- * max_discard_sectors, which is what lsblk -D reports to the user. */
1217
- if (!blk_queue_discard (q )) {
1218
- blk_queue_max_discard_sectors (q , 0 );
1219
- q -> limits .discard_granularity = 0 ;
1220
- }
1250
+ fixup_discard_if_not_supported (q );
1221
1251
}
1222
1252
1223
1253
void drbd_reconsider_queue_parameters (struct drbd_device * device , struct drbd_backing_dev * bdev )
0 commit comments