drbd: fix queue limit setup for discard
authorLars Ellenberg <lars.ellenberg@linbit.com>
Tue, 24 Mar 2015 20:46:29 +0000 (21:46 +0100)
committerJens Axboe <axboe@fb.com>
Wed, 25 Nov 2015 16:22:02 +0000 (09:22 -0700)
We cannot possibly support SECDISCARD, even if all backend devices would
support it: if our peer is currently unreachable, some instance of the
data may obviously still be recoverable.

We did not set discard_granularity at all.  We don't really care (yet),
we only pass them on, so for now, set our granularity to one sector.
blkdev_stack_limits() takes care of the rest.

If we decide we cannot support discards,
not only clear the (not user visible) QUEUE_FLAG_DISCARD,
but set both (user visible) discard_granularity and max_discard_sectors
to zero, to avoid confusion with e.g. lsblk -D.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/block/drbd/drbd_nl.c

index 5e4adff91d1d1f54bb336e6f9ddd4cc4d429de2f..4703f1ad7f927fbc49b847ae614c9ede43987386 100644 (file)
@@ -1168,21 +1168,20 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
        if (b) {
                struct drbd_connection *connection = first_peer_device(device)->connection;
 
+               blk_queue_max_discard_sectors(q, DRBD_MAX_DISCARD_SECTORS);
+
                if (blk_queue_discard(b) &&
                    (connection->cstate < C_CONNECTED || connection->agreed_features & FF_TRIM)) {
-                       /* For now, don't allow more than one activity log extent worth of data
-                        * to be discarded in one go. We may need to rework drbd_al_begin_io()
-                        * to allow for even larger discard ranges */
-                       blk_queue_max_discard_sectors(q, DRBD_MAX_DISCARD_SECTORS);
-
+                       /* We don't care, stacking below should fix it for the local device.
+                        * Whether or not it is a suitable granularity on the remote device
+                        * is not our problem, really. If you care, you need to
+                        * use devices with similar topology on all peers. */
+                       q->limits.discard_granularity = 512;
                        queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
-                       /* REALLY? Is stacking secdiscard "legal"? */
-                       if (blk_queue_secdiscard(b))
-                               queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
                } else {
                        blk_queue_max_discard_sectors(q, 0);
                        queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
-                       queue_flag_clear_unlocked(QUEUE_FLAG_SECDISCARD, q);
+                       q->limits.discard_granularity = 0;
                }
 
                blk_queue_stack_limits(q, b);
@@ -1194,6 +1193,12 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
                        q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
                }
        }
+       /* To avoid confusion, if this queue does not support discard, clear
+        * max_discard_sectors, which is what lsblk -D reports to the user.  */
+       if (!blk_queue_discard(q)) {
+               blk_queue_max_discard_sectors(q, 0);
+               q->limits.discard_granularity = 0;
+       }
 }
 
 void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backing_dev *bdev)