2 * Functions related to generic helpers functions
4 #include <linux/kernel.h>
5 #include <linux/module.h>
7 #include <linux/blkdev.h>
8 #include <linux/scatterlist.h>
12 static void blkdev_discard_end_io(struct bio *bio, int err)
15 if (err == -EOPNOTSUPP)
16 set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
17 clear_bit(BIO_UPTODATE, &bio->bi_flags);
21 complete(bio->bi_private);
22 __free_page(bio_page(bio));
28 * blkdev_issue_discard - queue a discard
29 * @bdev: blockdev to issue discard for
30 * @sector: start sector
31 * @nr_sects: number of sectors to discard
32 * @gfp_mask: memory allocation flags (for bio_alloc)
33 * @flags: BLKDEV_IFL_* flags to control behaviour
36 * Issue a discard request for the sectors in question.
38 int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
39 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
41 DECLARE_COMPLETION_ONSTACK(wait);
42 struct request_queue *q = bdev_get_queue(bdev);
43 int type = flags & BLKDEV_IFL_BARRIER ?
44 DISCARD_BARRIER : DISCARD_NOBARRIER;
52 if (!blk_queue_discard(q))
55 while (nr_sects && !ret) {
56 unsigned int sector_size = q->limits.logical_block_size;
57 unsigned int max_discard_sectors =
58 min(q->limits.max_discard_sectors, UINT_MAX >> 9);
60 bio = bio_alloc(gfp_mask, 1);
63 bio->bi_sector = sector;
64 bio->bi_end_io = blkdev_discard_end_io;
66 if (flags & BLKDEV_IFL_WAIT)
67 bio->bi_private = &wait;
70 * Add a zeroed one-sector payload as that's what
71 * our current implementations need. If we'll ever need
72 * more the interface will need revisiting.
74 page = alloc_page(gfp_mask | __GFP_ZERO);
77 if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size)
81 * And override the bio size - the way discard works we
82 * touch many more blocks on disk than the actual payload
85 if (nr_sects > max_discard_sectors) {
86 bio->bi_size = max_discard_sectors << 9;
87 nr_sects -= max_discard_sectors;
88 sector += max_discard_sectors;
90 bio->bi_size = nr_sects << 9;
95 submit_bio(type, bio);
97 if (flags & BLKDEV_IFL_WAIT)
98 wait_for_completion(&wait);
100 if (bio_flagged(bio, BIO_EOPNOTSUPP))
102 else if (!bio_flagged(bio, BIO_UPTODATE))
114 EXPORT_SYMBOL(blkdev_issue_discard);
120 struct completion *wait;
121 bio_end_io_t *end_io;
124 static void bio_batch_end_io(struct bio *bio, int err)
126 struct bio_batch *bb = bio->bi_private;
128 if (err == -EOPNOTSUPP)
129 set_bit(BIO_EOPNOTSUPP, &bb->flags);
131 clear_bit(BIO_UPTODATE, &bb->flags);
135 bb->end_io(bio, err);
136 atomic_inc(&bb->done);
143 * blkdev_issue_zeroout generate number of zero filed write bios
144 * @bdev: blockdev to issue
145 * @sector: start sector
146 * @nr_sects: number of sectors to write
147 * @gfp_mask: memory allocation flags (for bio_alloc)
148 * @flags: BLKDEV_IFL_* flags to control behaviour
151 * Generate and issue number of bios with zerofiled pages.
152 * Send barrier at the beginning and at the end if requested. This guarantie
153 * correct request ordering. Empty barrier allow us to avoid post queue flush.
156 int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
157 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
162 unsigned int sz, issued = 0;
163 DECLARE_COMPLETION_ONSTACK(wait);
165 atomic_set(&bb.done, 0);
166 bb.flags = 1 << BIO_UPTODATE;
170 if (flags & BLKDEV_IFL_BARRIER) {
171 /* issue async barrier before the data */
172 ret = blkdev_issue_flush(bdev, gfp_mask, NULL, 0);
177 while (nr_sects != 0) {
178 bio = bio_alloc(gfp_mask,
179 min(nr_sects, (sector_t)BIO_MAX_PAGES));
183 bio->bi_sector = sector;
185 bio->bi_end_io = bio_batch_end_io;
186 if (flags & BLKDEV_IFL_WAIT)
187 bio->bi_private = &bb;
189 while(nr_sects != 0) {
190 sz = min(PAGE_SIZE >> 9 , nr_sects);
192 /* bio has maximum size possible */
194 ret = bio_add_page(bio, ZERO_PAGE(0), sz << 9, 0);
195 nr_sects -= ret >> 9;
201 submit_bio(WRITE, bio);
204 * When all data bios are in flight. Send final barrier if requeted.
206 if (nr_sects == 0 && flags & BLKDEV_IFL_BARRIER)
207 ret = blkdev_issue_flush(bdev, gfp_mask, NULL,
208 flags & BLKDEV_IFL_WAIT);
211 if (flags & BLKDEV_IFL_WAIT)
212 /* Wait for bios in-flight */
213 while ( issued != atomic_read(&bb.done))
214 wait_for_completion(&wait);
216 if (!test_bit(BIO_UPTODATE, &bb.flags))
217 /* One of bios in the batch was completed with error.*/
223 if (test_bit(BIO_EOPNOTSUPP, &bb.flags)) {
232 EXPORT_SYMBOL(blkdev_issue_zeroout);