Branch data Line data Source code
1 : : /*
2 : : * Functions related to setting various queue properties from drivers
3 : : */
4 : : #include <linux/kernel.h>
5 : : #include <linux/module.h>
6 : : #include <linux/bio.h>
7 : : #include <linux/blkdev.h>
8 : : #include <linux/blk-mq.h>
9 : : #include <linux/sched/sysctl.h>
10 : :
11 : : #include "blk.h"
12 : :
13 : : /*
14 : : * for max sense size
15 : : */
16 : : #include <scsi/scsi_cmnd.h>
17 : :
18 : : /**
19 : : * blk_end_sync_rq - executes a completion event on a request
20 : : * @rq: request to complete
21 : : * @error: end I/O status of the request
22 : : */
23 : 0 : static void blk_end_sync_rq(struct request *rq, int error)
24 : : {
25 : 67985 : struct completion *waiting = rq->end_io_data;
26 : :
27 : 67985 : rq->end_io_data = NULL;
28 : :
29 : : /*
30 : : * complete last, if this is a stack request the process (and thus
31 : : * the rq pointer) could be invalid right after this complete()
32 : : */
33 : 67985 : complete(waiting);
34 : 67985 : }
35 : :
36 : : /**
37 : : * blk_execute_rq_nowait - insert a request into queue for execution
38 : : * @q: queue to insert the request in
39 : : * @bd_disk: matching gendisk
40 : : * @rq: request to insert
41 : : * @at_head: insert request at head or tail of queue
42 : : * @done: I/O completion handler
43 : : *
44 : : * Description:
45 : : * Insert a fully prepared request at the back of the I/O scheduler queue
46 : : * for execution. Don't wait for completion.
47 : : *
48 : : * Note:
49 : : * This function will invoke @done directly if the queue is dead.
50 : : */
51 : 0 : void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
52 : : struct request *rq, int at_head,
53 : : rq_end_io_fn *done)
54 : : {
55 [ - + ]: 67985 : int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
56 : : bool is_pm_resume;
57 : :
58 [ - + ]: 67985 : WARN_ON(irqs_disabled());
59 : :
60 : 67985 : rq->rq_disk = bd_disk;
61 : 67985 : rq->end_io = done;
62 : :
63 [ - + ]: 67985 : if (q->mq_ops) {
64 : 0 : blk_mq_insert_request(q, rq, true);
65 : 0 : return;
66 : : }
67 : :
68 : : /*
69 : : * need to check this before __blk_run_queue(), because rq can
70 : : * be freed before that returns.
71 : : */
72 : 67985 : is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
73 : :
74 : 67985 : spin_lock_irq(q->queue_lock);
75 : :
76 [ - + ]: 67985 : if (unlikely(blk_queue_dying(q))) {
77 : 0 : rq->cmd_flags |= REQ_QUIET;
78 : 0 : rq->errors = -ENXIO;
79 : 0 : __blk_end_request_all(rq, rq->errors);
80 : 0 : spin_unlock_irq(q->queue_lock);
81 : : return;
82 : : }
83 : :
84 : 67985 : __elv_add_request(q, rq, where);
85 : 67985 : __blk_run_queue(q);
86 : : /* the queue is stopped so it won't be run */
87 [ - + ]: 67985 : if (is_pm_resume)
88 : 0 : __blk_run_queue_uncond(q);
89 : 67985 : spin_unlock_irq(q->queue_lock);
90 : : }
91 : : EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
92 : :
93 : : /**
94 : : * blk_execute_rq - insert a request into queue for execution
95 : : * @q: queue to insert the request in
96 : : * @bd_disk: matching gendisk
97 : : * @rq: request to insert
98 : : * @at_head: insert request at head or tail of queue
99 : : *
100 : : * Description:
101 : : * Insert a fully prepared request at the back of the I/O scheduler queue
102 : : * for execution and wait for completion.
103 : : */
104 : 0 : int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
105 : : struct request *rq, int at_head)
106 : : {
107 : 67985 : DECLARE_COMPLETION_ONSTACK(wait);
108 : : char sense[SCSI_SENSE_BUFFERSIZE];
109 : : int err = 0;
110 : : unsigned long hang_check;
111 : :
112 [ - + ]: 67985 : if (!rq->sense) {
113 : 0 : memset(sense, 0, sizeof(sense));
114 : 0 : rq->sense = sense;
115 : 0 : rq->sense_len = 0;
116 : : }
117 : :
118 : 67985 : rq->end_io_data = &wait;
119 : 67985 : blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
120 : :
121 : : /* Prevent hang_check timer from firing at us during very long I/O */
122 : : hang_check = sysctl_hung_task_timeout_secs;
123 : : if (hang_check)
124 : : while (!wait_for_completion_io_timeout(&wait, hang_check * (HZ/2)));
125 : : else
126 : 67985 : wait_for_completion_io(&wait);
127 : :
128 [ - + ]: 67985 : if (rq->errors)
129 : : err = -EIO;
130 : :
131 : 67985 : return err;
132 : : }
133 : : EXPORT_SYMBOL(blk_execute_rq);
|