1
2
3
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/bio.h>
7#include <linux/blkdev.h>
8#include <linux/sched/sysctl.h>
9
10#include "blk.h"
11
12
13
14
15#include <scsi/scsi_cmnd.h>
16
17
18
19
20
21
22static void blk_end_sync_rq(struct request *rq, int error)
23{
24 struct completion *waiting = rq->end_io_data;
25
26 rq->end_io_data = NULL;
27 __blk_put_request(rq->q, rq);
28
29
30
31
32
33 complete(waiting);
34}
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51void 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 int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
56 bool is_pm_resume;
57
58 WARN_ON(irqs_disabled());
59
60 rq->rq_disk = bd_disk;
61 rq->end_io = done;
62
63
64
65
66 is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
67
68 spin_lock_irq(q->queue_lock);
69
70 if (unlikely(blk_queue_dying(q))) {
71 rq->cmd_flags |= REQ_QUIET;
72 rq->errors = -ENXIO;
73 __blk_end_request_all(rq, rq->errors);
74 spin_unlock_irq(q->queue_lock);
75 return;
76 }
77
78 __elv_add_request(q, rq, where);
79 __blk_run_queue(q);
80
81 if (is_pm_resume)
82 __blk_run_queue_uncond(q);
83 spin_unlock_irq(q->queue_lock);
84}
85EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
86
87
88
89
90
91
92
93
94
95
96
97
98int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
99 struct request *rq, int at_head)
100{
101 DECLARE_COMPLETION_ONSTACK(wait);
102 char sense[SCSI_SENSE_BUFFERSIZE];
103 int err = 0;
104 unsigned long hang_check;
105
106
107
108
109
110 rq->ref_count++;
111
112 if (!rq->sense) {
113 memset(sense, 0, sizeof(sense));
114 rq->sense = sense;
115 rq->sense_len = 0;
116 }
117
118 rq->end_io_data = &wait;
119 blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
120
121
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 wait_for_completion_io(&wait);
127
128 if (rq->errors)
129 err = -EIO;
130
131 return err;
132}
133EXPORT_SYMBOL(blk_execute_rq);
134