return round_down(UINT_MAX, discard_granularity) >> SECTOR_SHIFT;
 }
 
+static void await_bio_endio(struct bio *bio)
+{
+       complete(bio->bi_private);
+       bio_put(bio);
+}
+
+/*
+ * await_bio_chain - ends @bio and waits for every chained bio to complete
+ */
+static void await_bio_chain(struct bio *bio)
+{
+       DECLARE_COMPLETION_ONSTACK_MAP(done,
+                       bio->bi_bdev->bd_disk->lockdep_map);
+
+       bio->bi_private = &done;
+       bio->bi_end_io = await_bio_endio;
+       bio_endio(bio);
+       blk_wait_io(&done);
+}
+
 int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
                sector_t nr_sects, gfp_t gfp_mask, struct bio **biop)
 {
                 * is disabled.
                 */
                cond_resched();
+               if (fatal_signal_pending(current)) {
+                       await_bio_chain(bio);
+                       return -EINTR;
+               }
        }
 
        *biop = bio;
                nr_sects -= len;
                sector += len;
                cond_resched();
+               if (fatal_signal_pending(current)) {
+                       await_bio_chain(bio);
+                       return -EINTR;
+               }
        }
 
        *biop = bio;
                                break;
                }
                cond_resched();
+               if (fatal_signal_pending(current)) {
+                       await_bio_chain(bio);
+                       return -EINTR;
+               }
        }
 
        *biop = bio;
                bio_put(bio);
        }
        blk_finish_plug(&plug);
-       if (ret && try_write_zeroes) {
+       if (ret && ret != -EINTR && try_write_zeroes) {
                if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
                        try_write_zeroes = false;
                        goto retry;
                sector += len;
                nr_sects -= len;
                cond_resched();
+               if (fatal_signal_pending(current)) {
+                       await_bio_chain(bio);
+                       ret = -EINTR;
+                       bio = NULL;
+                       break;
+               }
        }
        if (bio) {
                ret = submit_bio_wait(bio);