···141141an IO scheduler name to this file will attempt to load that IO scheduler142142module, if it isn't already present in the system.143143144144+write_cache (RW)145145+----------------146146+When read, this file will display whether the device has write back147147+caching enabled or not. It will return "write back" for the former148148+case, and "write through" for the latter. Writing to this file can149149+change the kernels view of the device, but it doesn't alter the150150+device state. This means that it might not be safe to toggle the151151+setting from "write back" to "write through", since that will also152152+eliminate cache flushes issued by the kernel.144153145154146155Jens Axboe <jens.axboe@oracle.com>, February 2009
-11
block/bio.c
···311311 bio_endio(__bio_chain_endio(bio));312312}313313314314-/*315315- * Increment chain count for the bio. Make sure the CHAIN flag update316316- * is visible before the raised count.317317- */318318-static inline void bio_inc_remaining(struct bio *bio)319319-{320320- bio_set_flag(bio, BIO_CHAIN);321321- smp_mb__before_atomic();322322- atomic_inc(&bio->__bi_remaining);323323-}324324-325314/**326315 * bio_chain - chain bio completions327316 * @bio: the target bio
+3-2
block/blk-core.c
···15231523 * blk_add_request_payload - add a payload to a request15241524 * @rq: request to update15251525 * @page: page backing the payload15261526+ * @offset: offset in page15261527 * @len: length of the payload.15271528 *15281529 * This allows to later add a payload to an already submitted request by···15341533 * discard requests should ever use it.15351534 */15361535void blk_add_request_payload(struct request *rq, struct page *page,15371537- unsigned int len)15361536+ int offset, unsigned int len)15381537{15391538 struct bio *bio = rq->bio;1540153915411540 bio->bi_io_vec->bv_page = page;15421542- bio->bi_io_vec->bv_offset = 0;15411541+ bio->bi_io_vec->bv_offset = offset;15431542 bio->bi_io_vec->bv_len = len;1544154315451544 bio->bi_iter.bi_size = len;
+92-142
block/blk-lib.c
···991010#include "blk.h"11111212-struct bio_batch {1313- atomic_t done;1414- int error;1515- struct completion *wait;1616-};1717-1818-static void bio_batch_end_io(struct bio *bio)1212+static struct bio *next_bio(struct bio *bio, int rw, unsigned int nr_pages,1313+ gfp_t gfp)1914{2020- struct bio_batch *bb = bio->bi_private;1515+ struct bio *new = bio_alloc(gfp, nr_pages);21162222- if (bio->bi_error && bio->bi_error != -EOPNOTSUPP)2323- bb->error = bio->bi_error;2424- if (atomic_dec_and_test(&bb->done))2525- complete(bb->wait);2626- bio_put(bio);1717+ if (bio) {1818+ bio_chain(bio, new);1919+ submit_bio(rw, bio);2020+ }2121+2222+ return new;2723}2424+2525+int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,2626+ sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop)2727+{2828+ struct request_queue *q = bdev_get_queue(bdev);2929+ struct bio *bio = *biop;3030+ unsigned int granularity;3131+ int alignment;3232+3333+ if (!q)3434+ return -ENXIO;3535+ if (!blk_queue_discard(q))3636+ return -EOPNOTSUPP;3737+ if ((type & REQ_SECURE) && !blk_queue_secdiscard(q))3838+ return -EOPNOTSUPP;3939+4040+ /* Zero-sector (unknown) and one-sector granularities are the same. */4141+ granularity = max(q->limits.discard_granularity >> 9, 1U);4242+ alignment = (bdev_discard_alignment(bdev) >> 9) % granularity;4343+4444+ while (nr_sects) {4545+ unsigned int req_sects;4646+ sector_t end_sect, tmp;4747+4848+ /* Make sure bi_size doesn't overflow */4949+ req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9);5050+5151+ /**5252+ * If splitting a request, and the next starting sector would be5353+ * misaligned, stop the discard at the previous aligned sector.5454+ */5555+ end_sect = sector + req_sects;5656+ tmp = end_sect;5757+ if (req_sects < nr_sects &&5858+ sector_div(tmp, granularity) != alignment) {5959+ end_sect = end_sect - alignment;6060+ sector_div(end_sect, granularity);6161+ end_sect = end_sect * granularity + alignment;6262+ req_sects = end_sect - sector;6363+ }6464+6565+ bio = next_bio(bio, type, 1, gfp_mask);6666+ bio->bi_iter.bi_sector = sector;6767+ bio->bi_bdev = bdev;6868+6969+ bio->bi_iter.bi_size = req_sects << 9;7070+ nr_sects -= req_sects;7171+ sector = end_sect;7272+7373+ /*7474+ * We can loop for a long time in here, if someone does7575+ * full device discards (like mkfs). Be nice and allow7676+ * us to schedule out to avoid softlocking if preempt7777+ * is disabled.7878+ */7979+ cond_resched();8080+ }8181+8282+ *biop = bio;8383+ return 0;8484+}8585+EXPORT_SYMBOL(__blkdev_issue_discard);28862987/**3088 * blkdev_issue_discard - queue a discard···9840int blkdev_issue_discard(struct block_device *bdev, sector_t sector,9941 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)10042{101101- DECLARE_COMPLETION_ONSTACK(wait);102102- struct request_queue *q = bdev_get_queue(bdev);10343 int type = REQ_WRITE | REQ_DISCARD;104104- unsigned int granularity;105105- int alignment;106106- struct bio_batch bb;107107- struct bio *bio;108108- int ret = 0;4444+ struct bio *bio = NULL;10945 struct blk_plug plug;4646+ int ret;11047111111- if (!q)112112- return -ENXIO;113113-114114- if (!blk_queue_discard(q))115115- return -EOPNOTSUPP;116116-117117- /* Zero-sector (unknown) and one-sector granularities are the same. */118118- granularity = max(q->limits.discard_granularity >> 9, 1U);119119- alignment = (bdev_discard_alignment(bdev) >> 9) % granularity;120120-121121- if (flags & BLKDEV_DISCARD_SECURE) {122122- if (!blk_queue_secdiscard(q))123123- return -EOPNOTSUPP;4848+ if (flags & BLKDEV_DISCARD_SECURE)12449 type |= REQ_SECURE;125125- }126126-127127- atomic_set(&bb.done, 1);128128- bb.error = 0;129129- bb.wait = &wait;1305013151 blk_start_plug(&plug);132132- while (nr_sects) {133133- unsigned int req_sects;134134- sector_t end_sect, tmp;135135-136136- bio = bio_alloc(gfp_mask, 1);137137- if (!bio) {138138- ret = -ENOMEM;139139- break;140140- }141141-142142- /* Make sure bi_size doesn't overflow */143143- req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9);144144-145145- /*146146- * If splitting a request, and the next starting sector would be147147- * misaligned, stop the discard at the previous aligned sector.148148- */149149- end_sect = sector + req_sects;150150- tmp = end_sect;151151- if (req_sects < nr_sects &&152152- sector_div(tmp, granularity) != alignment) {153153- end_sect = end_sect - alignment;154154- sector_div(end_sect, granularity);155155- end_sect = end_sect * granularity + alignment;156156- req_sects = end_sect - sector;157157- }158158-159159- bio->bi_iter.bi_sector = sector;160160- bio->bi_end_io = bio_batch_end_io;161161- bio->bi_bdev = bdev;162162- bio->bi_private = &bb;163163-164164- bio->bi_iter.bi_size = req_sects << 9;165165- nr_sects -= req_sects;166166- sector = end_sect;167167-168168- atomic_inc(&bb.done);169169- submit_bio(type, bio);170170-171171- /*172172- * We can loop for a long time in here, if someone does173173- * full device discards (like mkfs). Be nice and allow174174- * us to schedule out to avoid softlocking if preempt175175- * is disabled.176176- */177177- cond_resched();5252+ ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, type,5353+ &bio);5454+ if (!ret && bio) {5555+ ret = submit_bio_wait(type, bio);5656+ if (ret == -EOPNOTSUPP)5757+ ret = 0;17858 }17959 blk_finish_plug(&plug);18060181181- /* Wait for bios in-flight */182182- if (!atomic_dec_and_test(&bb.done))183183- wait_for_completion_io(&wait);184184-185185- if (bb.error)186186- return bb.error;18761 return ret;18862}18963EXPORT_SYMBOL(blkdev_issue_discard);···135145 sector_t nr_sects, gfp_t gfp_mask,136146 struct page *page)137147{138138- DECLARE_COMPLETION_ONSTACK(wait);139148 struct request_queue *q = bdev_get_queue(bdev);140149 unsigned int max_write_same_sectors;141141- struct bio_batch bb;142142- struct bio *bio;150150+ struct bio *bio = NULL;143151 int ret = 0;144152145153 if (!q)···146158 /* Ensure that max_write_same_sectors doesn't overflow bi_size */147159 max_write_same_sectors = UINT_MAX >> 9;148160149149- atomic_set(&bb.done, 1);150150- bb.error = 0;151151- bb.wait = &wait;152152-153161 while (nr_sects) {154154- bio = bio_alloc(gfp_mask, 1);155155- if (!bio) {156156- ret = -ENOMEM;157157- break;158158- }159159-162162+ bio = next_bio(bio, REQ_WRITE | REQ_WRITE_SAME, 1, gfp_mask);160163 bio->bi_iter.bi_sector = sector;161161- bio->bi_end_io = bio_batch_end_io;162164 bio->bi_bdev = bdev;163163- bio->bi_private = &bb;164165 bio->bi_vcnt = 1;165166 bio->bi_io_vec->bv_page = page;166167 bio->bi_io_vec->bv_offset = 0;···163186 bio->bi_iter.bi_size = nr_sects << 9;164187 nr_sects = 0;165188 }166166-167167- atomic_inc(&bb.done);168168- submit_bio(REQ_WRITE | REQ_WRITE_SAME, bio);169189 }170190171171- /* Wait for bios in-flight */172172- if (!atomic_dec_and_test(&bb.done))173173- wait_for_completion_io(&wait);174174-175175- if (bb.error)176176- return bb.error;177177- return ret;191191+ if (bio)192192+ ret = submit_bio_wait(REQ_WRITE | REQ_WRITE_SAME, bio);193193+ return ret != -EOPNOTSUPP ? ret : 0;178194}179195EXPORT_SYMBOL(blkdev_issue_write_same);180196···186216 sector_t nr_sects, gfp_t gfp_mask)187217{188218 int ret;189189- struct bio *bio;190190- struct bio_batch bb;219219+ struct bio *bio = NULL;191220 unsigned int sz;192192- DECLARE_COMPLETION_ONSTACK(wait);193221194194- atomic_set(&bb.done, 1);195195- bb.error = 0;196196- bb.wait = &wait;197197-198198- ret = 0;199222 while (nr_sects != 0) {200200- bio = bio_alloc(gfp_mask,201201- min(nr_sects, (sector_t)BIO_MAX_PAGES));202202- if (!bio) {203203- ret = -ENOMEM;204204- break;205205- }206206-223223+ bio = next_bio(bio, WRITE,224224+ min(nr_sects, (sector_t)BIO_MAX_PAGES),225225+ gfp_mask);207226 bio->bi_iter.bi_sector = sector;208227 bio->bi_bdev = bdev;209209- bio->bi_end_io = bio_batch_end_io;210210- bio->bi_private = &bb;211228212229 while (nr_sects != 0) {213230 sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects);···204247 if (ret < (sz << 9))205248 break;206249 }207207- ret = 0;208208- atomic_inc(&bb.done);209209- submit_bio(WRITE, bio);210250 }211251212212- /* Wait for bios in-flight */213213- if (!atomic_dec_and_test(&bb.done))214214- wait_for_completion_io(&wait);215215-216216- if (bb.error)217217- return bb.error;218218- return ret;252252+ if (bio)253253+ return submit_bio_wait(WRITE, bio);254254+ return 0;219255}220256221257/**
+12
block/blk-mq-tag.c
···474474}475475EXPORT_SYMBOL(blk_mq_all_tag_busy_iter);476476477477+void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,478478+ busy_tag_iter_fn *fn, void *priv)479479+{480480+ int i;481481+482482+ for (i = 0; i < tagset->nr_hw_queues; i++) {483483+ if (tagset->tags && tagset->tags[i])484484+ blk_mq_all_tag_busy_iter(tagset->tags[i], fn, priv);485485+ }486486+}487487+EXPORT_SYMBOL(blk_mq_tagset_busy_iter);488488+477489void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,478490 void *priv)479491{
···779779 * discarded on disk. This allows us to report completion on the full780780 * amount of blocks described by the request.781781 */782782- blk_add_request_payload(rq, page, len);782782+ blk_add_request_payload(rq, page, 0, len);783783 ret = scsi_init_io(cmd);784784 rq->__data_len = nr_bytes;785785
+11
include/linux/bio.h
···703703}704704705705/*706706+ * Increment chain count for the bio. Make sure the CHAIN flag update707707+ * is visible before the raised count.708708+ */709709+static inline void bio_inc_remaining(struct bio *bio)710710+{711711+ bio_set_flag(bio, BIO_CHAIN);712712+ smp_mb__before_atomic();713713+ atomic_inc(&bio->__bi_remaining);714714+}715715+716716+/*706717 * bio_set is used to allow other portions of the IO system to707718 * allocate their own private memory pools for bio and iovec structures.708719 * These memory pools in turn all allocate from the bio_slab