linux/block/blk-flush.c
<<
.7.7.74/spalue.74spal class="lxr_search">.7.7 v3">.7.7Search.7.74/spalue.74input typ v3hidden" nam v3ajax_lookup" idv3ajax_lookup" > v3">.e 4div idv3file_contents"u
. .14/a>4spal class="comment">/*4/spalue. .24/a>4spal class="comment"> * Func vals to sequence FLUSH and FUA writes.4/spalue. .34/a>4spal class="comment"> *4/spalue. .44/a>4spal class="comment"> * Copyright (C) 2011           Max Planck Institute for Gravitational Physics4/spalue. .54/a>4spal class="comment"> * Copyright (C) 2011           Tejun Heo <tj@kernel.org>4/spalue. .64/a>4spal class="comment"> *4/spalue. .74/a>4spal class="comment"> * This file is released under the GPLo2>4/spalue. .84/a>4spal class="comment"> *4/spalue. .94/a>4spal class="comment"> * REQ_{FLUSH|FUA} requests are decomposed to sequences consisted of three4/spalue. optia>4spal class="comment"> * on valal steps - PREFLUSH, DATA and POSTFLUSH - according to the request4/spalue. 114/a>4spal class="comment"> * properties and hardware capability>4/spalue. 124/a>4spal class="comment"> *4/spalue. 134/a>4spal class="comment"> * If a request doesn't have data, only REQ_FLUSH makes sense, which. 144/a>4spal class="comment"> * indicates a simple flush request.  If there is data, REQ_FLUSH indicates. 154/a>4spal class="comment"> * that the device cache should be flushed before the data is executed, and. 164/a>4spal class="comment"> * REQ_FUA meals that the data must be 
	 non-volatile media 
	 request4/spalue. 174/a>4spal class="comment"> * comple val>4/spalue. 184/a>4spal class="comment"> *4/spalue. 194/a>4spal class="comment"> * If the device doesn't have writeback cache, FLUSH and FUA don't make any4/spalue. 2ptia>4spal class="comment"> * difference.  The requests are either comple ed immediately if there's no4/spalue. 214/a>4spal class="comment"> * data or executed as normal requests otherwise>4/spalue. 224/a>4spal class="comment"> *4/spalue. 234/a>4spal class="comment"> * If the device has writeback cache and supports FUA, REQ_FLUSH is. 244/a>4spal class="comment"> * tralslated to PREFLUSH but REQ_FUA is passed down directly with DATA>4/spalue. 254/a>4spal class="comment"> *4/spalue. 264/a>4spal class="comment"> * If the device has writeback cache and doesn't support FUA, REQ_FLUSH is. 274/a>4spal class="comment"> * tralslated to PREFLUSH and REQ_FUA to POSTFLUSH>4/spalue. 284/a>4spal class="comment"> *4/spalue. 294/a>4spal class="comment"> * The actual execut"
	 of flush is double buffered.  Whenever a request4/spalue. 3ptia>4spal class="comment"> * needs to execute PRE or POSTFLUSH, it queues at4/spalue. 314/a>4spal class="comment"> * q->flush_queue[q->flush_pending_idx].  Once certail criteria are met, a4/spalue. 324/a>4spal class="comment"> * flush is issued and the pending_idx is toggled.  When the flush4/spalue. 334/a>4spal class="comment"> * comple es, all the requests which were pending are proceeded to the next4/spalue. 344/a>4spal class="comment"> * step.  This allows arbitrary merging of different typ s of FLUSH/FUA4/spalue. 354/a>4spal class="comment"> * requests.4/spalue. 364/a>4spal class="comment"> *4/spalue. 374/a>4spal class="comment"> * Currently, the following condi vals are used to de ermine when to issue4/spalue. 384/a>4spal class="comment"> * flush.4/spalue. 394/a>4spal class="comment"> *4/spalue. 4ptia>4spal class="comment"> * C1. At any given time, only one flush shall be il progress.  This makes4/spalue. 414/a>4spal class="comment"> *     double buffering sufficient.4/spalue. 424/a>4spal class="comment"> *4/spalue. 434/a>4spal class="comment"> * C2. Flush is deferred if any request is executing DATA of its sequence.4/spalue. 444/a>4spal class="comment"> *     This avoids issuing separate POSTFLUSH s for requests which shared4/spalue. 454/a>4spal class="comment"> * . 464/a>4spal class="comment"> *4/spalue. 474/a>4spal class="comment"> * C3. The second condi val is ignored if there is a request which has4/spalue. 484/a>4spal class="comment"> *     waited longer thal FLUSH_PENDING_TIMEOUT.  This is to avoid4/spalue. 494/a>4spal class="comment"> *     starva val in the unlikely case where there are continuous stream of4/spalue. 5ptia>4spal class="comment"> *     FUA (without FLUSH) requests.4/spalue. 514/a>4spal class="comment"> *4/spalue. 524/a>4spal class="comment"> * For devices which support FUA, it isn't clear whether C2 (and thus C3)4/spalue. 534/a>4spal class="comment"> * is beneficial.4/spalue. 544/a>4spal class="comment"> *4/spalue. 554/a>4spal class="comment"> * Note that a sequenced FLUSH/FUA request with DATA is comple ed twice.4/spalue. 564/a>4spal class="comment"> * Once while executing DATA and agail after the whole sequence is. 574/a>4spal class="comment"> * comple e.  The first comple val updates the contailed bio but doesn't. 584/a>4spal class="comment"> * finish it so that the bio submitter is notified only after the whole. 594/a>4spal class="comment"> * sequence is comple e.  This is implemented by testing REQ_FLUSH_SEQ in4/spalue. 6ptia>4spal class="comment"> * req_bio_endio().4/spalue. 614/a>4spal class="comment"> *4/spalue. 624/a>4spal class="comment"> * The above peculiarity requires that each FLUSH/FUA request has only one4/spalue. 634/a>4spal class="comment"> * bio attached to it, which is guaranteed as they aren't allowed to be4/spalue. 644/a>4spal class="comment"> * merged in the usual way>4/spalue. 654/a>4spal class="comment"> */4/spalue. 664/a>e. 674/a>#include <linux/kernel.h4/a>>e. 684/a>#include <linux/module.h4/a>>e. 694/a>#include <linux/bio.h4/a>>e. 704/a>#include <linux/blkdev.h4/a>>e. 714/a>#include <linux/gfp.h4/a>>e. 724/a>e. 734/a>#include "blk.h4/a>"e. 744/a>e. 754/a>4spal class="comment">/* FLUSH/FUA sequences */4/spalue. 764/a>enum {e. 774/a>        4a href="+code=REQ_FSEQ_PREFLUSH" class="sref">REQ_FSEQ_PREFLUSH4/a>       = (1 << 0), 4spal class="comment">/* pre-flushing il progress */4/spalue. 784/a>        4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/a>           = (1 << 1), 4spal class="comment">/* data write il progress */4/spalue. 794/a>        4a href="+code=REQ_FSEQ_POSTFLUSH" class="sref">REQ_FSEQ_POSTFLUSH4/a>      = (1 << 2), 4spal class="comment">/* post-flushing il progress */4/spalue. 804/a>        4a href="+code=REQ_FSEQ_DONE" class="sref">REQ_FSEQ_DONE4/a>           = (1 << 3),e. 814/a>e. 824/a>        4a href="+code=REQ_FSEQ_ACTIONS" class="sref">REQ_FSEQ_ACTIONS4/a>        = 4a href="+code=REQ_FSEQ_PREFLUSH" class="sref">REQ_FSEQ_PREFLUSH4/a> | 4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/a> |e. 834/a>                                  4a href="+code=REQ_FSEQ_POSTFLUSH" class="sref">REQ_FSEQ_POSTFLUSH4/a>,e. 844/a>e. 854/a>        4spal class="comment">/*4/spalue. 864/a>4spal class="comment">         * If flush has been pending longer thal the following timeout,4/spalue. 874/a>4spal class="comment">         * it's issued even if flush_data requests are still il flight.4/spalue. 884/a>4spal class="comment">         */4/spalue. 894/a>        4a href="+code=FLUSH_PENDING_TIMEOUT" class="sref">FLUSH_PENDING_TIMEOUT4/a>   = 5 * 4a href="+code=HZ" class="sref">HZ4/a>,e. 904/a>};e. 914/a>e. 924/a>static 4a href="+code=bool" class="sref">bool4/a> 4a href="+code=blk_kick_flush" class="sref">blk_kick_flush4/a>(struct 4a href="+code=request_queue" class="sref">request_queue4/a> *4a href="+code=q" class="sref">q4/a>);e. 934/a>e. 944/a>static unsigned int 4a href="+code=blk_flush_policy" class="sref">blk_flush_policy4/a>(unsigned int 4a href="+code=fflags" class="sref">fflags4/a>, struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>)e. 954/a>{e. 964/a>        unsigned int 4a href="+code=policy" class="sref">policy4/a> = 0;e. 974/a>e. 984/a>        if (4a href="+code=blk_rq_sectors" class="sref">blk_rq_sectors4/a>(4a href="+code=rq" class="sref">rq4/a>))e. 994/a>                4a href="+code=policy" class="sref">policy4/a> |= 4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/a>;e.1004/a>e.1014/a>        if (4a href="+code=fflags" class="sref">fflags4/a> & 4a href="+code=REQ_FLUSH" class="sref">REQ_FLUSH4/a>) {e.1024/a>                if (4a href="+code=rq" class="sref">rq4/a>->4a href="+code=cmd_flags" class="sref">cmd_flags4/a> & 4a href="+code=REQ_FLUSH" class="sref">REQ_FLUSH4/a>)e.1034/a>                        4a href="+code=policy" class="sref">policy4/a> |= 4a href="+code=REQ_FSEQ_PREFLUSH" class="sref">REQ_FSEQ_PREFLUSH4/a>;e.1044/a>                if (!(4a href="+code=fflags" class="sref">fflags4/a> & 4a href="+code=REQ_FUA" class="sref">REQ_FUA4/a>) && (4a href="+code=rq" class="sref">rq4/a>->4a href="+code=cmd_flags" class="sref">cmd_flags4/a> & 4a href="+code=REQ_FUA" class="sref">REQ_FUA4/a>))e.1054/a>                        4a href="+code=policy" class="sref">policy4/a> |= 4a href="+code=REQ_FSEQ_POSTFLUSH" class="sref">REQ_FSEQ_POSTFLUSH4/a>;e.1064/a>        }e.1074/a>        return 4a href="+code=policy" class="sref">policy4/a>;e.1084/a>}e.1094/a>e.1optia>static unsigned int 4a href="+code=blk_flush_cur_seq" class="sref">blk_flush_cur_seq4/a>(struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>)e.1114/a>{e.1124/a>        return 1 << 4a href="+code=ffz" class="sref">ffz4/a>(4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=seq" class="sref">seq4/a>);e.1134/a>}e.1144/a>e.1154/a>static void 4a href="+code=blk_flush_restore_request" class="sref">blk_flush_restore_request4/a>(struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>)e.1164/a>{e.1174/a>        4spal class="comment">/*4/spalue.1184/a>4spal class="comment">         * After flush data comple val, @rq->bio is %NULL but we need to4/spalue.1194/a>4spal class="comment">         * comple e the bio agail.  @rq->biotail is guaranteed to equal the4/spalue.12ptia>4spal class="comment">         * origilal @rq->bio.  Restore it.4/spalue.1214/a>4spal class="comment">         */4/spalue.1224/a>        4a href="+code=rq" class="sref">rq4/a>->4a href="+code=bio" class="sref">bio4/a> = 4a href="+code=rq" class="sref">rq4/a>->4a href="+code=biotail" class="sref">biotail4/a>;e.1234/a>e.1244/a>        4spal class="comment">/* make @rq a normal request */4/spalue.1254/a>        4a href="+code=rq" class="sref">rq4/a>->4a href="+code=cmd_flags" class="sref">cmd_flags4/a> &= ~4a href="+code=REQ_FLUSH_SEQ" class="sref">REQ_FLUSH_SEQ4/a>;e.1264/a>        4a href="+code=rq" class="sref">rq4/a>->4a href="+code=end_io" class="sref">end_io4/a> = 4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=saved_end_io" class="sref">saved_end_io4/a>;e.1274/a>}e.1284/a>e.1294/a>4spal class="comment">/**4/spalue.13ptia>4spal class="comment"> * blk_flush_comple e_seq - comple e flush sequence4/spalue.1314/a>4spal class="comment"> * @rq: FLUSH/FUA request being sequenced4/spalue.1324/a>4spal class="comment"> * @seq: sequences to comple e (mask of %REQ_FSEQ_*, cal be zero)4/spalue.1334/a>4spal class="comment"> * @error: whether al error occurred4/spalue.1344/a>4spal class="comment"> *4/spalue.1354/a>4spal class="comment"> * @rq just comple ed @seq part of its flush sequence, record the4/spalue.1364/a>4spal class="comment"> * comple val and trigger the next step.4/spalue.1374/a>4spal class="comment"> *4/spalue.1384/a>4spal class="comment"> * CONTEXT:4/spalue.1394/a>4spal class="comment"> * spin_lock_irq(q->queue_lock)4/spalue.14ptia>4spal class="comment"> *4/spalue.1414/a>4spal class="comment"> * RETURNS:4/spalue.1424/a>4spal class="comment"> * %true if requests were added to the dispatch queue, %false otherwise>4/spalue.1434/a>4spal class="comment"> */4/spalue.1444/a>static 4a href="+code=bool" class="sref">bool4/a> 4a href="+code=blk_flush_comple e_seq" class="sref">blk_flush_comple e_seq4/a>(struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>, unsigned int 4a href="+code=seq" class="sref">seq4/a>,e.1454/a>                                   int 4a href="+code=error" class="sref">error4/a>)e.1464/a>{e.1474/a>        struct 4a href="+code=request_queue" class="sref">request_queue4/a> *4a href="+code=q" class="sref">q4/a> = 4a href="+code=rq" class="sref">rq4/a>->4a href="+code=q" class="sref">q4/a>;e.1484/a>        struct 4a href="+code=list_head" class="sref">list_head4/a> *4a href="+code=pending" class="sref">pending4/a> = &4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_queue" class="sref">flush_queue4/a>[4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_idx" class="sref">flush_pending_idx4/a>];e.1494/a>        4a href="+code=bool" class="sref">bool4/a> 4a href="+code=queued" class="sref">queued4/a> = 4a href="+code=false" class="sref">false4/a>;e.1504/a>e.1514/a>        4a href="+code=BUG_ON" class="sref">BUG_ON4/a>(4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=seq" class="sref">seq4/a> & 4a href="+code=seq" class="sref">seq4/a>);e.1524/a>        4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=seq" class="sref">seq4/a> |= 4a href="+code=seq" class="sref">seq4/a>;e.1534/a>e.1544/a>        if (4a href="+code=likely" class="sref">likely4/a>(!4a href="+code=error" class="sref">error4/a>))e.1554/a>                4a href="+code=seq" class="sref">seq4/a> = 4a href="+code=blk_flush_cur_seq" class="sref">blk_flush_cur_seq4/a>(4a href="+code=rq" class="sref">rq4/a>);e.1564/a>        elsee.1574/a>                4a href="+code=seq" class="sref">seq4/a> = 4a href="+code=REQ_FSEQ_DONE" class="sref">REQ_FSEQ_DONE4/a>;e.1584/a>e.1594/a>        switch (4a href="+code=seq" class="sref">seq4/a>) {e.1604/a>        case 4a href="+code=REQ_FSEQ_PREFLUSH" class="sref">REQ_FSEQ_PREFLUSH4/a>:e.1614/a>        case 4a href="+code=REQ_FSEQ_POSTFLUSH" class="sref">REQ_FSEQ_POSTFLUSH4/a>:e.1624/a>                4spal class="comment">/* queue for flush */4/spalue.1634/a>                if (4a href="+code=list_empty" class="sref">list_empty4/a>(4a href="+code=pending" class="sref">pending4/a>))e.1644/a>                        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_since" class="sref">flush_pending_since4/a> = 4a href="+code=jiffies" class="sref">jiffies4/a>;e.1654/a>                4a href="+code=list_move_tail" class="sref">list_move_tail4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>, 4a href="+code=pending" class="sref">pending4/a>);e.1664/a>                break;e.1674/a>e.1684/a>        case 4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/a>:e.1694/a>                4a href="+code=list_move_tail" class="sref">list_move_tail4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>, &4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_data_in_flight" class="sref">flush_data_in_flight4/a>);e.1704/a>                4a href="+code=list_add" class="sref">list_add4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=queuelist" class="sref">queuelist4/a>, &4a href="+code=q" class="sref">q4/a>->4a href="+code=queue_head" class="sref">queue_head4/a>);e.1714/a>                4a href="+code=queued" class="sref">queued4/a> = 4a href="+code=true" class="sref">true4/a>;e.1724/a>                break;e.1734/a>e.1744/a>        case 4a href="+code=REQ_FSEQ_DONE" class="sref">REQ_FSEQ_DONE4/a>:e.1754/a>                4spal class="comment">/*4/spalue.1764/a>4spal class="comment">                 * @rq was previously adjusted by blk_flush_issue() for4/spalue.1774/a>4spal class="comment">                 * flush sequencing and may already have gone through the4/spalue.1784/a>4spal class="comment">                 * flush data request comple val path.  Restore @rq for4/spalue.1794/a>4spal class="comment">                 * normal comple val and end it.4/spalue.18ptia>4spal class="comment">                 */4/spalue.1814/a>                4a href="+code=BUG_ON" class="sref">BUG_ON4/a>(!4a href="+code=list_empty" class="sref">list_empty4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=queuelist" class="sref">queuelist4/a>));e.1824/a>                4a href="+code=list_del_init" class="sref">list_del_init4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>);e.1834/a>                4a href="+code=blk_flush_restore_request" class="sref">blk_flush_restore_request4/a>(4a href="+code=rq" class="sref">rq4/a>);e.1844/a>                4a href="+code=__blk_end_request_all" class="sref">__blk_end_request_all4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=error" class="sref">error4/a>);e.1854/a>                break;e.1864/a>e.1874/a>        default:e.1884/a>                4a href="+code=BUG" class="sref">BUG4/a>();e.1894/a>        }e.1904/a>e.1914/a>        return 4a href="+code=blk_kick_flush" class="sref">blk_kick_flush4/a>(4a href="+code=q" class="sref">q4/a>) | 4a href="+code=queued" class="sref">queued4/a>;e.1924/a>}e.1934/a>e.1944/a>static void 4a href="+code=flush_end_io" class="sref">flush_end_io4/a>(struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=flush_rq" class="sref">flush_rq4/a>, int 4a href="+code=error" class="sref">error4/a>)e.1954/a>{e.1964/a>        struct 4a href="+code=request_queue" class="sref">request_queue4/a> *4a href="+code=q" class="sref">q4/a> = 4a href="+code=flush_rq" class="sref">flush_rq4/a>->4a href="+code=q" class="sref">q4/a>;e.1974/a>        struct 4a href="+code=list_head" class="sref">list_head4/a> *4a href="+code=running" class="sref">running4/a> = &4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_queue" class="sref">flush_queue4/a>[4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_running_idx" class="sref">flush_running_idx4/a>];e.1984/a>        4a href="+code=bool" class="sref">bool4/a> 4a href="+code=queued" class="sref">queued4/a> = 4a href="+code=false" class="sref">false4/a>;e.1994/a>        struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>, *4a href="+code=n" class="sref">n4/a>;e.2004/a>e.2014/a>        4a href="+code=BUG_ON" class="sref">BUG_ON4/a>(4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_idx" class="sref">flush_pending_idx4/a> == 4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_running_idx" class="sref">flush_running_idx4/a>);e.2024/a>e.2034/a>        4spal class="comment">/* account comple val of the flush request */4/spalue.2044/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_running_idx" class="sref">flush_running_idx4/a> ^= 1;e.2054/a>        4a href="+code=elv_comple ed_request" class="sref">elv_comple ed_request4/a>(4a href="+code=q" class="sref">q4/a>, 4a href="+code=flush_rq" class="sref">flush_rq4/a>);e.2064/a>e.2074/a>        4spal class="comment">/* and push the waiting requests to the next stage */4/spalue.2084/a>        4a href="+code=list_for_each_entry_safe" class="sref">list_for_each_entry_safe4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=n" class="sref">n4/a>, 4a href="+code=running" class="sref">running4/a>, 4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>) {e.2094/a>                unsigned int 4a href="+code=seq" class="sref">seq4/a> = 4a href="+code=blk_flush_cur_seq" class="sref">blk_flush_cur_seq4/a>(4a href="+code=rq" class="sref">rq4/a>);e.2104/a>e.2114/a>                4a href="+code=BUG_ON" class="sref">BUG_ON4/a>(4a href="+code=seq" class="sref">seq4/a> != 4a href="+code=REQ_FSEQ_PREFLUSH" class="sref">REQ_FSEQ_PREFLUSH4/a> && 4a href="+code=seq" class="sref">seq4/a> != 4a href="+code=REQ_FSEQ_POSTFLUSH" class="sref">REQ_FSEQ_POSTFLUSH4/a>);e.2124/a>                4a href="+code=queued" class="sref">queued4/a> |= 4a href="+code=blk_flush_comple e_seq" class="sref">blk_flush_comple e_seq4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=seq" class="sref">seq4/a>, 4a href="+code=error" class="sref">error4/a>);e.2134/a>        }e.2144/a>e.2154/a>        4spal class="comment">/*4/spalue.2164/a>4spal class="comment">         * Kick the queue to avoid stall for two cases:4/spalue.2174/a>4spal class="comment">         * 1. Moving a request silently to empty queue_head may stall the4/spalue.2184/a>4spal class="comment">         * queue>4/spalue.2194/a>4spal class="comment">         * 2. When flush request is running il non-queueable queue, the4/spalue.22ptia>4spal class="comment">         * queue is hold. Restart the queue after flush request is finished4/spalue.2214/a>4spal class="comment">         * to avoid stall>4/spalue.2224/a>4spal class="comment">         * This func val is called from request comple val path and calling4/spalue.2234/a>4spal class="comment">         * directly into request_fn may confuse the driver.  Always use4/spalue.2244/a>4spal class="comment">         * kblockd>4/spalue.2254/a>4spal class="comment">         */4/spalue.2264/a>        if (4a href="+code=queued" class="sref">queued4/a> || 4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_queue_delayed" class="sref">flush_queue_delayed4/a>)e.2274/a>                4a href="+code=blk_run_queue_async" class="sref">blk_run_queue_async4/a>(4a href="+code=q" class="sref">q4/a>);e.2284/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_queue_delayed" class="sref">flush_queue_delayed4/a> = 0;e.2294/a>}e.2304/a>e.2314/a>4spal class="comment">/**4/spalue.2324/a>4spal class="comment"> * blk_kick_flush - consider issuing flush request4/spalue.2334/a>4spal class="comment"> * @q: request_queue being kicked4/spalue.2344/a>4spal class="comment"> *4/spalue.2354/a>4spal class="comment"> * Flush related states of @q have changed, consider issuing flush request>4/spalue.2364/a>4spal class="comment"> * Please read the comment at the top of this file for more info>4/spalue.2374/a>4spal class="comment"> *4/spalue.2384/a>4spal class="comment"> * CONTEXT:4/spalue.2394/a>4spal class="comment"> * spin_lock_irq(q->queue_lock)4/spalue.24ptia>4spal class="comment"> *4/spalue.2414/a>4spal class="comment"> * RETURNS:4/spalue.2424/a>4spal class="comment"> * %true if flush was issued, %false otherwise>4/spalue.2434/a>4spal class="comment"> */4/spalue.2444/a>static 4a href="+code=bool" class="sref">bool4/a> 4a href="+code=blk_kick_flush" class="sref">blk_kick_flush4/a>(struct 4a href="+code=request_queue" class="sref">request_queue4/a> *4a href="+code=q" class="sref">q4/a>)e.2454/a>{e.2464/a>        struct 4a href="+code=list_head" class="sref">list_head4/a> *4a href="+code=pending" class="sref">pending4/a> = &4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_queue" class="sref">flush_queue4/a>[4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_idx" class="sref">flush_pending_idx4/a>];e.2474/a>        struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=first_rq" class="sref">first_rq4/a> =e.2484/a>                4a href="+code=list_first_entry" class="sref">list_first_entry4/a>(4a href="+code=pending" class="sref">pending4/a>, struct 4a href="+code=request" class="sref">request4/a>, 4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>);e.2494/a>e.2504/a>        4spal class="comment">/* C1 described at the top of this file */4/spalue.2514/a>        if (4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_idx" class="sref">flush_pending_idx4/a> != 4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_running_idx" class="sref">flush_running_idx4/a> || 4a href="+code=list_empty" class="sref">list_empty4/a>(4a href="+code=pending" class="sref">pending4/a>))e.2524/a>                return 4a href="+code=false" class="sref">false4/a>;e.2534/a>e.2544/a>        4spal class="comment">/* C2 and C3 */4/spalue.2554/a>        if (!4a href="+code=list_empty" class="sref">list_empty4/a>(&4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_data_in_flight" class="sref">flush_data_in_flight4/a>) &&e.2564/a>            4a href="+code=time_before" class="sref">time_before4/a>(4a href="+code=jiffies" class="sref">jiffies4/a>,e.2574/a>                        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_since" class="sref">flush_pending_since4/a> + 4a href="+code=FLUSH_PENDING_TIMEOUT" class="sref">FLUSH_PENDING_TIMEOUT4/a>))e.2584/a>                return 4a href="+code=false" class="sref">false4/a>;e.2594/a>e.2604/a>        4spal class="comment">/*4/spalue.2614/a>4spal class="comment">         * Issue flush and toggle pending_idx.  This makes pending_idx4/spalue.2624/a>4spal class="comment">         * different from running_idx, which means flush is il flight.4/spalue.2634/a>4spal class="comment">         */4/spalue.2644/a>        4a href="+code=blk_rq_init" class="sref">blk_rq_init4/a>(4a href="+code=q" class="sref">q4/a>, &4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_rq" class="sref">flush_rq4/a>);e.2654/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_rq" class="sref">flush_rq4/a>.4a href="+code=cmd_type" class="sref">cmd_type4/a> = 4a href="+code=REQ_TYPE_FS" class="sref">REQ_TYPE_FS4/a>;e.2664/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_rq" class="sref">flush_rq4/a>.4a href="+code=cmd_flags" class="sref">cmd_flags4/a> = 4a href="+code=WRITE_FLUSH" class="sref">WRITE_FLUSH4/a> | 4a href="+code=REQ_FLUSH_SEQ" class="sref">REQ_FLUSH_SEQ4/a>;e.2674/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_rq" class="sref">flush_rq4/a>.4a href="+code=rq_disk" class="sref">rq_disk4/a> = 4a href="+code=first_rq" class="sref">first_rq4/a>->4a href="+code=rq_disk" class="sref">rq_disk4/a>;e.2684/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_rq" class="sref">flush_rq4/a>.4a href="+code=end_io" class="sref">end_io4/a> = 4a href="+code=flush_end_io" class="sref">flush_end_io4/a>;e.2694/a>e.2704/a>        4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_pending_idx" class="sref">flush_pending_idx4/a> ^= 1;e.2714/a>        4a href="+code=list_add_tail" class="sref">list_add_tail4/a>(&4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_rq" class="sref">flush_rq4/a>.4a href="+code=queuelist" class="sref">queuelist4/a>, &4a href="+code=q" class="sref">q4/a>->4a href="+code=queue_head" class="sref">queue_head4/a>);e.2724/a>        return 4a href="+code=true" class="sref">true4/a>;e.2734/a>}e.2744/a>e.2754/a>static void 4a href="+code=flush_data_end_io" class="sref">flush_data_end_io4/a>(struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>, int 4a href="+code=error" class="sref">error4/a>)e.2764/a>{e.2774/a>        struct 4a href="+code=request_queue" class="sref">request_queue4/a> *4a href="+code=q" class="sref">q4/a> = 4a href="+code=rq" class="sref">rq4/a>->4a href="+code=q" class="sref">q4/a>;e.2784/a>e.2794/a>        4spal class="comment">/*4/spalue.28ptia>4spal class="comment">         * After populating an empty queue, kick it to avoid stall>  Read4/spalue.2814/a>4spal class="comment">         * the comment in flush_end_io().4/spalue.2824/a>4spal class="comment">         */4/spalue.2834/a>        if (4a href="+code=blk_flush_comple e_seq" class="sref">blk_flush_comple e_seq4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/a>, 4a href="+code=error" class="sref">error4/a>))e.2844/a>                4a href="+code=blk_run_queue_async" class="sref">blk_run_queue_async4/a>(4a href="+code=q" class="sref">q4/a>);e.2854/a>}e.2864/a>e.2874/a>4spal class="comment">/**4/spalue.2884/a>4spal class="comment"> * blk_insert_flush - insert a new FLUSH/FUA request4/spalue.2894/a>4spal class="comment"> * @rq: request to insert4/spalue.29ptia>4spal class="comment"> *4/spalue.2914/a>4spal class="comment"> * To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions.4/spalue.2924/a>4spal class="comment"> * @rq is being submitted.  Analyze what needs to be done and put it on the4/spalue.2934/a>4spal class="comment"> * right queue>4/spalue.2944/a>4spal class="comment"> *4/spalue.2954/a>4spal class="comment"> * CONTEXT:4/spalue.2964/a>4spal class="comment"> * spin_lock_irq(q->queue_lock)4/spalue.2974/a>4spal class="comment"> */4/spalue.2984/a>void 4a href="+code=blk_insert_flush" class="sref">blk_insert_flush4/a>(struct 4a href="+code=request" class="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>)e.2994/a>{e.3004/a>        struct 4a href="+code=request_queue" class="sref">request_queue4/a> *4a href="+code=q" class="sref">q4/a> = 4a href="+code=rq" class="sref">rq4/a>->4a href="+code=q" class="sref">q4/a>;e.3014/a>        unsigned int 4a href="+code=fflags" class="sref">fflags4/a> = 4a href="+code=q" class="sref">q4/a>->4a href="+code=flush_flags" class="sref">flush_flags4/a>;   4spal class="comment">/* may change, cache */4/spalue.3024/a>        unsigned int 4a href="+code=policy" class="sref">policy4/a> = 4a href="+code=blk_flush_policy" class="sref">blk_flush_policy4/a>(4a href="+code=fflags" class="sref">fflags4/a>, 4a href="+code=rq" class="sref">rq4/a>);e.3034/a>e.3044/a>        4spal class="comment">/*4/spalue.3054/a>4spal class="comment">         * @policy now records what operations need to be done.  Adjust4/spalue.3064/a>4spal class="comment">         * REQ_FLUSH and FUA for the driver.4/spalue.3074/a>4spal class="comment">         */4/spalue.3084/a>        4a href="+code=rq" class="sref">rq4/a>->4a href="+code=cmd_flags" class="sref">cmd_flags4/a> &= ~4a href="+code=REQ_FLUSH" class="sref">REQ_FLUSH4/a>;e.3094/a>        if (!(4a href="+code=fflags" class="sref">fflags4/a> & 4a href="+code=REQ_FUA" class="sref">REQ_FUA4/a>))e.3104/a>                4a href="+code=rq" class="sref">rq4/a>->4a href="+code=cmd_flags" class="sref">cmd_flags4/a> &= ~4a href="+code=REQ_FUA" class="sref">REQ_FUA4/a>;e.3114/a>e.3124/a>        4spal class="comment">/*4/spalue.3134/a>4spal class="comment">         * An empty flush handed down from a stacking driver may4/spalue.3144/a>4spal class="comment">         * translate into nothing if the underlying device does not4/spalue.3154/a>4spal class="comment">         * advertise a write-back cache.  In this case, simply4/spalue.3164/a>4spal class="comment">         * comple e the request>4/spalue.3174/a>4spal class="comment">         */4/spalue.3184/a>        if (!4a href="+code=policy" class="sref">policy4/a>) {e.3194/a>                4a href="+code=__blk_end_bidi_request" class="sref">__blk_end_bidi_request4/a>(4a href="+code=rq" class="sref">rq4/a>, 0, 0, 0);e.3204/a>                return;e.3214/a>        }e.3224/a>e.3234/a>        4a href="+code=BUG_ON" class="sref">BUG_ON4/a>(4a href="+code=rq" class="sref">rq4/a>->4a href="+code=bio" class="sref">bio4/a> != 4a href="+code=rq" class="sref">rq4/a>->4a href="+code=biotail" class="sref">biotail4/a>); 4spal class="comment">/*assumes zero or single bio rq */4/spalue.3244/a>e.3254/a>        4spal class="comment">/*4/spalue.3264/a>4spal class="comment">         * If there's data but flush is not necessary, the request can be4/spalue.3274/a>4spal class="comment">         * processed directly without going through flush machinery.  Queue4/spalue.3284/a>4spal class="comment">         * for normal execution>4/spalue.3294/a>4spal class="comment">         */4/spalue.3304/a>        if ((4a href="+code=policy" class="sref">policy4/a> & 4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/a>) &&e.3314/a>            !(4a href="+code=policy" class="sref">policy4/a> & (4a href="+code=REQ_FSEQ_PREFLUSH" class="sref">REQ_FSEQ_PREFLUSH4/a> | 4a href="+code=REQ_FSEQ_POSTFLUSH" class="sref">REQ_FSEQ_POSTFLUSH4/a>))) {e.3324/a>                4a href="+code=list_add_tail" class="sref">list_add_tail4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=queuelist" class="sref">queuelist4/a>, &4a href="+code=q" class="sref">q4/a>->4a href="+code=queue_head" class="sref">queue_head4/a>);e.3334/a>                return;e.3344/a>        }e.3354/a>e.3364/a>        4spal class="comment">/*4/spalue.3374/a>4spal class="comment">         * " idv3L333" class=ent">8tldf * " idv3L333" class=ent">8tldf * " idv3L3dk-fluEra hreps fiorwise>4L337" idv3L337" class="line" nam v3L338">.3284/a>4spal class="comment">3* CON3EXT:4/spalue.23943a>4spal class="comment">3* spi3_lock_irq(q->queue_lock)4/k-flush.c#L330" idv3L330" class="line" nam v3L340">.24pt3a>4spal class="comment">3*4/sp34s="sref">q4/a>->4a href="memse;4a href="+code=memse;"sref">rq4/a>->4a href="+code=queuelist" class="sref">queuelist4/h4/a>(struct 4a hrefuest" cla#L320sizeof4/a>->4a href="+code=bio" class="sref">bio4/a> != 4a hreh4/a>(struct 4a hrefuest" cla" idv3L182" class="line" nam v3L341">.24143a>4spal class="comment">3* RET34d_tail" class="sref">list_adINIT_LIST_HEAD(struct 4a hrefINIT_LIST_HEAD"sref">rq4/a>->4a href="+code=queuelist" class="sref">queuelist4/h4/a>(struct 4a hrefuest" clalist4/a>);e.24243a>4spal class="comment">3* എ_tail" class="sref">list_ad="+code=cmd_flags" class="sref">cmd_flags4/a> &= ~4a href="+code=REQ_FUA" clae_seq" class="srefSH_SEQ4/a>;e.24343a>4spal class="comment">3*/4/s34 class="sref">BUG_ON4/a>(4a ="+code=queuelist" class="sref">queuelist4/h4/a>(struct 4a hrefuest" clalist4/a>);e(struct 4a hresavedd_io4/aef">rq4/a>->4a href="+code=q" class="sref">q4/a>;e.3344/a>static 4a href="+code=3ool" 34init" class="sref">blk_rq_in="+code=q" class="sref">q4/a>;eflush_end_io4/a_end_io4/a>(struct 4a href="+code=request" claidv3L267" class="line" nam v3L345">.3354/a>{e.24643a>        struct 4a href3"+cod34s="sref">q4/a>->4a href="">blk_flush_comple e_seq4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=REQ_FSEQ_DATA" class="sref">REQ_FSEQ_DATA4/aACTION href="block/blk-fluTA4/aACTION _PREFLUSH" f">REQ_FUA4/a>;ep; (4a href="+code=REQ_FSEQ_PRE20" idv3L320" class="line" nam v3L347">.24743a>        struct 4a href3"+cod3=requeidv3L335" class="line" nam v3L348">.24843a>                4a hre3="+co3479" idv3L279" class="line" nam v3L349">.24943a>e.25043a>        4spal class="c3mment35ue.24143a>        if (4a href="+3ode=q35 called from __elv_add_requestlue.24243a>                return34a hr35s being submitted.  Analyze wL288" idv3L288" class="line" nam v3L353">.24343a>e88" idv3L288" class="line" nam v3L354">.3344/a>        4spal class="c3mment35ue.25543a>        if (!4a href="3code=35XT:4/spalue.24643a>            4a href="+3ode=t35lock_irq(q->queue_lock)4/spflush.c#L296" idv3L296" class="line" nam v3L357">.25743a>                      3 4a h35lue.25843a>                return34a hr35nsert_flush - insert a new FL#L330" idv3L330" class="line" nam v3L359">.25943a>eblk_inseaborequest"eseq4/a>(4a href="+coaborequest"es class="sref">request4/a> *4a href/a> *4a href="+code=q" class="sref">q4/a>)e.26043a>        4spal class="c3mment3>/*4/sidv3L332" class="line" nam v3L361">.26143a>4spal class="comment">3     36d_tail" classs="sref">request4/a> *4a href="+code=rq" class="sref">rq4/a>, *4a href="+code=n" class="sref">n4/a>;e.26243a>4spal class="comment">3     362_tail" classref">policy4/a> = 4ik/blk-flush.c#Li00" idv3L200" class="line" nam v3L363">.24343a>4spal class="comment">3     3604" idv3L304" class="line" nam v3L364">.26443a>        4a href="+code3blk_r36/*4/spalue.26543a>        4a href="+code3q" cl36 * advertise a write-back cache.  In tRush.c#s/k-flush.c/blk-e reqs "ble.26643a>        4a href="+code3q" cl36 * If there's data but flush is noblock/k/blk-flk/blk-fblock/blJust rq" claef="block/bl.26743a>        4a href="+code3q" cl36 */4/spalue.26843a>        4a href="+code3q" cl3ss="sref">q4/a>->4a href="ef">list_for_each_entry_safe4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=n" class="sref">n4/a>, 4a href="+code=running" class="sref>q4/a>->4a href="+code=flush_data_in_flight" class="sref">flush_data_in_flight4/a>) &&eflush4/a>.4a href="+code=list" class="sref">list4/a>) {e.26943a>erq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>);e.27043a>        4a href="+code3q" cl37=rq" class="sref">rq4/a>->4a hrefbf="+code=rq" class="srefeq4/a>(4a href="+code=rq"rq" class="sref">rq4/a>);e.27143a>        4a href="+code3list_37lush.c#L322" idv3L322" class="line" nam v3L372">.27243a>        return 4a href3"+cod3723" idv3L323" class="line" nam v3L373">.27343a>}e.27443a>e.26543a>static void 4a href="+3ode=f37 * advertise a write-back cache.  In tlock/bl.27643a>{e.27743a>        struct 4a href3"+cod3=request_queuef="b4/a>);epolicy4/a> = 4ik/blk-flush.c#Li00"  <i">policy4/a> = 4ARRAY_SIZEk/blk-flush.c#LARRAY_SIZE">rq4/a>);eflush_queue4/a>[4a href="+code=q" class="sref">q4/)i">policy4/a> = 4ik/blk-flush.c#Li00" ++" idv3L209" class="line" nam v3L378">.27843a>elist_firstst_for_each_entry_safe4/a>(4a href="+code=rq" class="sref">rq4/a>, 4a href="+code=n" class="sref">n4/a>, 4a href="+code=running" class="sref>q4/a>->4a href="+code=flush_data_in_flight" class="sref">flush_[4a href="+code=q" class="sref">q4/a>->4a href="ik/blk-flush.c#Li00" ]idv3L257" class="line" nam v3L379">.27943a>        4spal class="c3mment37=__blk_end_bidi_requeeeeeeeeeeeeeeeeeeeeeeeeeeflush4/a>.4a href="+code=list" class="sref">list4/a>) {e.28pt3a>4spal class="comment">3     38=rq" class="sref">rq4di_request" class="srefl_init4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=flush" class="sref">flush4/a>.4a href="+code=list" class="sref">list4/a>);e.28143a>4spal class="comment">3     38=BUG_ON" class="sref"di_request" class="srefbf="+code=rq" class="srefeq4/a>(4a href="+code=rq"rq" class="sref">rq4/a>);e.28243a>4spal class="comment">3     38=list_add_tail" classdi_request" class="srefl_inil4/a>(&4a href="+code=rq" class="sref">rq4/a>->4a href="+code=queuelist" class="sref">queuelist4/a>, &4a href="+code=q" class="sref">q4/a>->4a href="+code=queue_head" class="sref">queue_head4/a>);e.27343a>        if (4a href="+3ode=b38f="block/blk-flush.c#idv3L322" class="line" nam v3L384">.28443a>                4a hre3="+co38lush.c#L335" idv3L335" class="line" nam v3L385">.28543a>}e.28643a>e.28743a>4spal class="comment">3**4/s3alueflubioequesef="+code=list" clasbioequesef="+ class="sref">request4/a> *f="+code=rq" class="sref">a>;eerror4/a>)e.28843a>4spal class="comment">3* blk3insertidv3L209" class="line" nam v3L389">.27943a>4spal class="comment">3* @rq38flags" class="sreerror4/a>)e.29pt3a>4spal class="comment">3*4/sp39=rq" class="sref">rq4/a>->4a hrefclear_b&4a href="+coclear_b&a">rq4/a>);eq4/a>->4a href="f="+code=rq" class="sref""sref">biotail4/a>); 4&= ~4a href="+cod 4&=333" idv3L333" class="line" nam v3L391">.29143a>4spal class="comment">3* To 39class="sref">q4/a>->4a href="f="+code=rq" class="sref""sref">biotail4/a>); 4&privathref="+code=q" c 4&privath76" idv3L276" class="line" nam v3L392">.28243a>4spal class="comment">3* @rq39=list_add_tail" class="sref">list_ad class="mp;4a href="+cocclass="">rq4/a>);ebiotail4/a>); 4&privathref="+code=q" c 4&privath76" iidv3L333" class="line" nam v3L393">.27343a>4spal class="comment">3* rig39 class="sref">BUG_ON4/a>(4a bioe/blcode=list" clasbioe/bl">rq4/a>);e.28443a>4spal class="comment">3*4/sp3lue.29543a>4spal class="comment">3* CON3936" idv3L336" class="line" nam v3L396">.29643a>4spal class="comment">3* spi3_lock_irq(q->queue_lock)4.c#L288" idv3L288" class="line" nam v3L397">.29743a>4spal class="comment">3*/4/s3alue.29843a>void 4a href="+code=bl3_inse39nsert_flush - insert a new FLU@bdev:="sref"lass=devk-flu This makesf="L318" idv3L318" class="line" nam v3L399">.29943a>{e.30044a>        struct 4a href4"+cod40ue.30044a>4spal class="comment">4 href40 called from __elv_add_requesL297" idv3L297" class="line" nam v3L402">.30044a>4spal class="comment">4 href40s being submitted.  Analyze whD4/spaplue<#L296" idv3L296" class="line" nam v3L403">.30344a>e.30444a>        4spal class="c4mment40ue.30444a>4spal class="comment">4     4  * @policy now records what #bbbbwikesto.ot nWAIT amp;be4/spalpa flustht4/&L316"  href=es=foninerha#L315" idv3L315" class="line" nam v3L406">.30644a>4spal class="comment">4     4  * REQ_FLUSH and FUA for the#bbbbr/blk-flspalpst"e"sre somvice ernalaed4/spf="h devr may4l4/s#L329" idv3L329" class="line" nam v3L407">.30744a>4spal class="comment">4     4  */4/spalue.30844a>        4a href="+code4rq" c4ass="sef">error4/a>)e(4a href="+cdev_uerequest4/a> *fa hrelk/blkeq4/a>(4a href="+ hrelk/blkref">a>;en4/a>, 4a href="+cogfp_lcode=list" clasgfp_lref">>, 4a href="+cogfp_maskcode=list" clasgfp_mask">n4/dv3L318" class="line" nam v3L409">.30844a>{ea>;e.31044a>                4a hre4="+co41/*4/sidv3L332" class="line" nam v3L411">.31144a>elist_adDECLARE_COMPLETION_ONSTACK="+code=flush_eDECLARE_COMPLETION_ONSTACK">rq4/a>);e.31244a>        4spal class="c4mment4>/*4/spaluerequest4/a> *4a href/a> *4a href="+code=q" class="sref">q4/a>)e.30344a>4spal class="comment">4     413*4/spaluerequest4/a> *f="+code=rq" class="sref">a>;e.30444a>4spal class="comment">4     41lush.c#L335" ef">error4/a>)e.31544a>4spal class="comment">4     4136" idv3L336" class="line" nam v3L416">.31644a>4spal class="comment">4     41s="sref">q4/aq4/a>->4a href="flk/eq4/a>(4a href="lk/">n4"sref">biotail4/a>); d href="block/blk-flu d href"sre29s="sref">flush_enNULL="block/blk-fluNULL76" idv3L276" class="line" nam v3L417">.30744a>4spal class="comment">4     41f="+code=q" class="srsref">t-"sref">flush_enENXIO="block/blk-fluENXIOref"idv3L333" class="line" nam v3L418">.30844a>        if (!4a href="4code=4179" idv3L279" class="line" nam v3L419">.31944a>                4a hre4="+co4e=__blk_end_bi>)eblk_fdev_gef/a> *4a href="+code=qfdev_gef/a> *4">rq4/a>);en4iidv3L333" class="line" nam v3L420">.32044a>                return4epolicy4/a>) {eck/blk-flush.c#L245" idv3L245" class="line" nam v3L421">.32144a>        }et-"sref">flush_enENXIO="block/blk-fluENXIOref"idv3L333" class="line" nam v3L422">.32244a>e.32344a>        4a href="+code4BUG_O42/* account comple val of the flush reL318" idv3L318" class="line" nam v3L424">.32444a>e.31544a>        4spal class="c4mment42 * advertise a write-back cache.  In t(e.g. loopflk/blk-ry.  Quea block/bllush)blockeflu Thto bawise>4L337" idv3L337" class="line" nam v3L426">.32644a>4spal class="comment">4     4  * If there's data but flush is nocess-rylllpanic. Ensurenecessbe4/abr/blk-flfunclue< blass=lu Thto L337" idv3L337" class="line" nam v3L427">.30744a>4spal class="comment">4     4  * processed directly without going thale"" nam L337" idv3L337" class="line" nam v3L428">.30844a>4spal class="comment">4     4  * for normal execution>4/spalue.32944a>4spal class="comment">4     42flags" class="sref>->4a href="+code=queue_head" class="sref">queue_headlockss="sref_fde=running" claslockss="sref_fd45" idv3L245" class="line" nam v3L430">.33044a>        if ((4a href="4code=43f="block/blk-flush.c#L321" t-"sref">flush_enENXIO="block/blk-fluENXIOref"idv3L333" class="line" nam v3L431">.33144a>            !(4a href=4+code4312" idv3L312" class="line" nam v3L432">.33244a>                4a hre4="+co432_tail" class="sref">list_adf="+code=rq" class="sref">class="sref">blk_fioelefoccode=list" clasbioelefoc">rq4/a>);en4/0" idv3L320" class="line" nam v3L433">.33344a>                return4eBUG_ON4/a>(4a bio+code=rq" class="sref""sref">biotail4/a>); 4&_io4/a>(struct 4a hre 4&_io4/aref">class="sref">blk_fioequesef="+code=list" clasbioequesef="+ claidv3L320" class="line" nam v3L434">.32444a>        }eblk_rq_inbio+code=rq" class="sref""sref">biotail4/a>); 4&flk/eq4/a>(4a href="4&flk/45"  class="sref">blk_fdeveq4/a>(4a href="lk/">n4idv3L320" class="line" nam v3L435">.31544a>eq4/a>->4a href="f="+code=rq" class="sref""sref">biotail4/a>); 4&privathref="+code=q" c 4&privath76"  cl>q4/a>->4a href="wa&4a href="+cowa&aref"idv3L320" class="line" nam v3L436">.32644a>        4spal class="c4mment4387" idv3L287" class="line" nam v3L437">.33744a>4spal class="comment">4     43s="sref">q4/a>->4a href="bioege;4a href="+code=bioege;">rq4/a>);e.32844a>4spal class="comment">4* CON43s="sref">q4/a>->4a href="e done_f="+code=rq" classe done_f="">rq4/a>);e, 4a href="+cof="+code=rq" class="sref"iidv3L333" class="line" nam v3L439">.32944a>4spal class="comment">4* spi43=__blk_end_bi>)erq4/a>->4a hrefwa&4a href="+cowa&aref"iidv3L333" class="line" nam v3L440">.24pt4a>4spal class="comment">4*4/sp44s="srdv3L333" class="line" nam v3L441">.33144a>4spal class="comment">4* RET44d_tail" class=ple val of the flush reL318" idv3L318" class="line" nam v3L442">.24244a>4spal class="comment">4* Ř * different from running_idx, which mTk-flush.c must " claeale"h.c#L focalue< i t-sref 4&sec cl,/spL318" idv3L318" class="line" nam v3L443">.33344a>4spal class="comment">4*/4/s44 * An empty flush handed down from a sit.sup.or#s/kt. F="blon-"bloclushush.cs,block/33" clac#L327" idv3L327" class="line" nam v3L444">.33444a>static 4a href="+code=4ool" 44 * translate into nothing if the undercopi7;ELEVATbass="spos(rqc#L282" idv3L282" class="line" nam v3L445">.33544a>{e.24644a>        struct 4a href4"+cod44s="sref">q4/aq4/a>->4a href="h.c#L_sec cl="+code=flush_enr2#L_sec cl76" idv3L276" class="line" nam v3L447">.24744a>        struct 4a href4"+cod44f="+code=q" class="sa>;eclass="sref">blk_fio+code=rq" class="sref""sref">biotail4/a>); 4&sec cl="+code=flush_e 4&sec clref"idv3L320" class="line" nam v3L448">.24844a>                4a hre4="+co4479" idv3L279" class="line" nam v3L449">.24944a>erq4/a>);e, 4a href="+coBIO_UPTODATEk/blk-flush.c#LBIO_UPTODATE"sre idv3L310" class="line" nam v3L450">.25044a>        4spal class="c4mment45=rq" class="sref">rq4/a>->4a href=e;4a href="+code=re;"sre29"-"sref">flush_enEIO="block/blk-fluEIOref"idv3L333" class="line" nam v3L451">.24144a>        if (4a href="+4ode=q4512" idv3L312" class="line" nam v3L452">.24244a>                return44a hr452_tail" class="sref">list_adf="e/blcode=list" clasbioe/bl">rq4/a>);e.24344a>etrue4/a>;e.33444a>        4spal class="c4mment45ue.25544a>        if (!4a href="4code=45XT:4/ssref">flush_enEXPORT_SYMBOL="block/blk-fluEXPORT_SYMBOL">rq4/a>);e.24644a>            4a href="+4ode=t45lock_i/pre_i/div>


i/div>