1 /* 2 * Functions related to generic helpers functions 3 */ 4 #include <linux/kernel.h> 5 #include <linux/module.h> 6 #include <linux/bio.h> 7 #include <linux/blkdev.h> 8 #include <linux/scatterlist.h> 9 10 #include "blk.h" 11 12 struct bio_batch { 13 atomic_t done; 14 unsigned long flags; 15 struct completion *wait; 16 }; 17 18 static void bio_batch_end_io(struct bio *bio, int err) 19 { 20 struct bio_batch *bb = bio->bi_private; 21 22 if (err && (err != -EOPNOTSUPP)) 23 clear_bit(BIO_UPTODATE, &bb->flags); 24 if (atomic_dec_and_test(&bb->done)) 25 complete(bb->wait); 26 bio_put(bio); 27 } 28 29 /** 30 * blkdev_issue_discard - queue a discard 31 * @bdev: blockdev to issue discard for 32 * @sector: start sector 33 * @nr_sects: number of sectors to discard 34 * @gfp_mask: memory allocation flags (for bio_alloc) 35 * @flags: BLKDEV_IFL_* flags to control behaviour 36 * 37 * Description: 38 * Issue a discard request for the sectors in question. 39 */ 40 int blkdev_issue_discard(struct block_device *bdev, sector_t sector, 41 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags) 42 { 43 DECLARE_COMPLETION_ONSTACK(wait); 44 struct request_queue *q = bdev_get_queue(bdev); 45 int type = REQ_WRITE | REQ_DISCARD; 46 unsigned int max_discard_sectors; 47 struct bio_batch bb; 48 struct bio *bio; 49 int ret = 0; 50 51 if (!q) 52 return -ENXIO; 53 54 if (!blk_queue_discard(q)) 55 return -EOPNOTSUPP; 56 57 /* 58 * Ensure that max_discard_sectors is of the proper 59 * granularity 60 */ 61 max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); 62 if (unlikely(!max_discard_sectors)) { 63 /* Avoid infinite loop below. Being cautious never hurts. */ 64 return -EOPNOTSUPP; 65 } else if (q->limits.discard_granularity) { 66 unsigned int disc_sects = q->limits.discard_granularity >> 9; 67 68 max_discard_sectors &= ~(disc_sects - 1); 69 } 70 71 if (flags & BLKDEV_DISCARD_SECURE) { 72 if (!blk_queue_secdiscard(q)) 73 return -EOPNOTSUPP; 74 type |= REQ_SECURE; 75 } 76 77 atomic_set(&bb.done, 1); 78 bb.flags = 1 << BIO_UPTODATE; 79 bb.wait = &wait; 80 81 while (nr_sects) { 82 bio = bio_alloc(gfp_mask, 1); 83 if (!bio) { 84 ret = -ENOMEM; 85 break; 86 } 87 88 bio->bi_sector = sector; 89 bio->bi_end_io = bio_batch_end_io; 90 bio->bi_bdev = bdev; 91 bio->bi_private = &bb; 92 93 if (nr_sects > max_discard_sectors) { 94 bio->bi_size = max_discard_sectors << 9; 95 nr_sects -= max_discard_sectors; 96 sector += max_discard_sectors; 97 } else { 98 bio->bi_size = nr_sects << 9; 99 nr_sects = 0; 100 } 101 102 atomic_inc(&bb.done); 103 submit_bio(type, bio); 104 } 105 106 /* Wait for bios in-flight */ 107 if (!atomic_dec_and_test(&bb.done)) 108 wait_for_completion(&wait); 109 110 if (!test_bit(BIO_UPTODATE, &bb.flags)) 111 ret = -EIO; 112 113 return ret; 114 } 115 EXPORT_SYMBOL(blkdev_issue_discard); 116 117 /** 118 * blkdev_issue_zeroout - generate number of zero filed write bios 119 * @bdev: blockdev to issue 120 * @sector: start sector 121 * @nr_sects: number of sectors to write 122 * @gfp_mask: memory allocation flags (for bio_alloc) 123 * 124 * Description: 125 * Generate and issue number of bios with zerofiled pages. 126 */ 127 128 int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, 129 sector_t nr_sects, gfp_t gfp_mask) 130 { 131 int ret; 132 struct bio *bio; 133 struct bio_batch bb; 134 unsigned int sz; 135 DECLARE_COMPLETION_ONSTACK(wait); 136 137 atomic_set(&bb.done, 1); 138 bb.flags = 1 << BIO_UPTODATE; 139 bb.wait = &wait; 140 141 ret = 0; 142 while (nr_sects != 0) { 143 bio = bio_alloc(gfp_mask, 144 min(nr_sects, (sector_t)BIO_MAX_PAGES)); 145 if (!bio) { 146 ret = -ENOMEM; 147 break; 148 } 149 150 bio->bi_sector = sector; 151 bio->bi_bdev = bdev; 152 bio->bi_end_io = bio_batch_end_io; 153 bio->bi_private = &bb; 154 155 while (nr_sects != 0) { 156 sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects); 157 ret = bio_add_page(bio, ZERO_PAGE(0), sz << 9, 0); 158 nr_sects -= ret >> 9; 159 sector += ret >> 9; 160 if (ret < (sz << 9)) 161 break; 162 } 163 ret = 0; 164 atomic_inc(&bb.done); 165 submit_bio(WRITE, bio); 166 } 167 168 /* Wait for bios in-flight */ 169 if (!atomic_dec_and_test(&bb.done)) 170 wait_for_completion(&wait); 171 172 if (!test_bit(BIO_UPTODATE, &bb.flags)) 173 /* One of bios in the batch was completed with error.*/ 174 ret = -EIO; 175 176 return ret; 177 } 178 EXPORT_SYMBOL(blkdev_issue_zeroout); 179