diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-14 20:31:54 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-14 20:31:54 -0400 |
commit | 6dc6472581f693b5fc95aebedf67b4960fb85cf0 (patch) | |
tree | 06a5a9a08519950575505273eabced331ed51405 /block/blk-barrier.c | |
parent | ee673eaa72d8d185012b1027a05e25aba18c267f (diff) | |
parent | 8acd3a60bcca17c6d89c73cee3ad6057eb83ba1e (diff) |
Merge commit 'origin'
Manual fixup of conflicts on:
arch/powerpc/include/asm/dcr-regs.h
drivers/net/ibm_newemac/core.h
Diffstat (limited to 'block/blk-barrier.c')
-rw-r--r-- | block/blk-barrier.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/block/blk-barrier.c b/block/blk-barrier.c index a09ead19f9c5..5c99ff8d2db8 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c | |||
@@ -293,7 +293,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) | |||
293 | bio->bi_end_io = bio_end_empty_barrier; | 293 | bio->bi_end_io = bio_end_empty_barrier; |
294 | bio->bi_private = &wait; | 294 | bio->bi_private = &wait; |
295 | bio->bi_bdev = bdev; | 295 | bio->bi_bdev = bdev; |
296 | submit_bio(1 << BIO_RW_BARRIER, bio); | 296 | submit_bio(WRITE_BARRIER, bio); |
297 | 297 | ||
298 | wait_for_completion(&wait); | 298 | wait_for_completion(&wait); |
299 | 299 | ||
@@ -315,3 +315,73 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) | |||
315 | return ret; | 315 | return ret; |
316 | } | 316 | } |
317 | EXPORT_SYMBOL(blkdev_issue_flush); | 317 | EXPORT_SYMBOL(blkdev_issue_flush); |
318 | |||
319 | static void blkdev_discard_end_io(struct bio *bio, int err) | ||
320 | { | ||
321 | if (err) { | ||
322 | if (err == -EOPNOTSUPP) | ||
323 | set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); | ||
324 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
325 | } | ||
326 | |||
327 | bio_put(bio); | ||
328 | } | ||
329 | |||
330 | /** | ||
331 | * blkdev_issue_discard - queue a discard | ||
332 | * @bdev: blockdev to issue discard for | ||
333 | * @sector: start sector | ||
334 | * @nr_sects: number of sectors to discard | ||
335 | * @gfp_mask: memory allocation flags (for bio_alloc) | ||
336 | * | ||
337 | * Description: | ||
338 | * Issue a discard request for the sectors in question. Does not wait. | ||
339 | */ | ||
340 | int blkdev_issue_discard(struct block_device *bdev, | ||
341 | sector_t sector, sector_t nr_sects, gfp_t gfp_mask) | ||
342 | { | ||
343 | struct request_queue *q; | ||
344 | struct bio *bio; | ||
345 | int ret = 0; | ||
346 | |||
347 | if (bdev->bd_disk == NULL) | ||
348 | return -ENXIO; | ||
349 | |||
350 | q = bdev_get_queue(bdev); | ||
351 | if (!q) | ||
352 | return -ENXIO; | ||
353 | |||
354 | if (!q->prepare_discard_fn) | ||
355 | return -EOPNOTSUPP; | ||
356 | |||
357 | while (nr_sects && !ret) { | ||
358 | bio = bio_alloc(gfp_mask, 0); | ||
359 | if (!bio) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | bio->bi_end_io = blkdev_discard_end_io; | ||
363 | bio->bi_bdev = bdev; | ||
364 | |||
365 | bio->bi_sector = sector; | ||
366 | |||
367 | if (nr_sects > q->max_hw_sectors) { | ||
368 | bio->bi_size = q->max_hw_sectors << 9; | ||
369 | nr_sects -= q->max_hw_sectors; | ||
370 | sector += q->max_hw_sectors; | ||
371 | } else { | ||
372 | bio->bi_size = nr_sects << 9; | ||
373 | nr_sects = 0; | ||
374 | } | ||
375 | bio_get(bio); | ||
376 | submit_bio(DISCARD_BARRIER, bio); | ||
377 | |||
378 | /* Check if it failed immediately */ | ||
379 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) | ||
380 | ret = -EOPNOTSUPP; | ||
381 | else if (!bio_flagged(bio, BIO_UPTODATE)) | ||
382 | ret = -EIO; | ||
383 | bio_put(bio); | ||
384 | } | ||
385 | return ret; | ||
386 | } | ||
387 | EXPORT_SYMBOL(blkdev_issue_discard); | ||