Blame view

block/blk-exec.c 2.62 KB
86db1e297   Jens Axboe   block: continue l...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   * Functions related to setting various queue properties from drivers
   */
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/bio.h>
  #include <linux/blkdev.h>
  
  #include "blk.h"
  
  /*
   * for max sense size
   */
  #include <scsi/scsi_cmnd.h>
  
  /**
   * blk_end_sync_rq - executes a completion event on a request
   * @rq: request to complete
710027a48   Randy Dunlap   Add some block/ s...
19
   * @error: end I/O status of the request
86db1e297   Jens Axboe   block: continue l...
20
   */
681a561b7   FUJITA Tomonori   block: unexport b...
21
  static void blk_end_sync_rq(struct request *rq, int error)
86db1e297   Jens Axboe   block: continue l...
22
23
24
25
26
27
28
29
30
31
32
33
  {
  	struct completion *waiting = rq->end_io_data;
  
  	rq->end_io_data = NULL;
  	__blk_put_request(rq->q, rq);
  
  	/*
  	 * complete last, if this is a stack request the process (and thus
  	 * the rq pointer) could be invalid right after this complete()
  	 */
  	complete(waiting);
  }
86db1e297   Jens Axboe   block: continue l...
34
35
36
37
38
39
40
41
42
43
  
  /**
   * blk_execute_rq_nowait - insert a request into queue for execution
   * @q:		queue to insert the request in
   * @bd_disk:	matching gendisk
   * @rq:		request to insert
   * @at_head:    insert request at head or tail of queue
   * @done:	I/O completion handler
   *
   * Description:
710027a48   Randy Dunlap   Add some block/ s...
44
   *    Insert a fully prepared request at the back of the I/O scheduler queue
86db1e297   Jens Axboe   block: continue l...
45
46
47
48
49
50
51
52
53
   *    for execution.  Don't wait for completion.
   */
  void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
  			   struct request *rq, int at_head,
  			   rq_end_io_fn *done)
  {
  	int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
  
  	rq->rq_disk = bd_disk;
86db1e297   Jens Axboe   block: continue l...
54
55
56
57
58
  	rq->end_io = done;
  	WARN_ON(irqs_disabled());
  	spin_lock_irq(q->queue_lock);
  	__elv_add_request(q, rq, where, 1);
  	__generic_unplug_device(q);
9a2d43b75   Bartlomiej Zolnierkiewicz   block: handle blk...
59
60
61
  	/* the queue is stopped so it won't be plugged+unplugged */
  	if (blk_pm_resume_request(rq))
  		q->request_fn(q);
86db1e297   Jens Axboe   block: continue l...
62
63
64
65
66
67
68
69
70
71
72
73
  	spin_unlock_irq(q->queue_lock);
  }
  EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
  
  /**
   * blk_execute_rq - insert a request into queue for execution
   * @q:		queue to insert the request in
   * @bd_disk:	matching gendisk
   * @rq:		request to insert
   * @at_head:    insert request at head or tail of queue
   *
   * Description:
710027a48   Randy Dunlap   Add some block/ s...
74
   *    Insert a fully prepared request at the back of the I/O scheduler queue
86db1e297   Jens Axboe   block: continue l...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
   *    for execution and wait for completion.
   */
  int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
  		   struct request *rq, int at_head)
  {
  	DECLARE_COMPLETION_ONSTACK(wait);
  	char sense[SCSI_SENSE_BUFFERSIZE];
  	int err = 0;
  
  	/*
  	 * we need an extra reference to the request, so we can look at
  	 * it after io completion
  	 */
  	rq->ref_count++;
  
  	if (!rq->sense) {
  		memset(sense, 0, sizeof(sense));
  		rq->sense = sense;
  		rq->sense_len = 0;
  	}
  
  	rq->end_io_data = &wait;
  	blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
  	wait_for_completion(&wait);
  
  	if (rq->errors)
  		err = -EIO;
  
  	return err;
  }
86db1e297   Jens Axboe   block: continue l...
105
  EXPORT_SYMBOL(blk_execute_rq);