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);