Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * elevator noop |
| 3 | */ |
| 4 | #include <linux/blkdev.h> |
| 5 | #include <linux/elevator.h> |
| 6 | #include <linux/bio.h> |
| 7 | #include <linux/module.h> |
| 8 | #include <linux/init.h> |
| 9 | |
| 10 | /* |
| 11 | * See if we can find a request that this buffer can be coalesced with. |
| 12 | */ |
| 13 | static int elevator_noop_merge(request_queue_t *q, struct request **req, |
| 14 | struct bio *bio) |
| 15 | { |
| 16 | struct list_head *entry = &q->queue_head; |
| 17 | struct request *__rq; |
| 18 | int ret; |
| 19 | |
| 20 | if ((ret = elv_try_last_merge(q, bio))) { |
| 21 | *req = q->last_merge; |
| 22 | return ret; |
| 23 | } |
| 24 | |
| 25 | while ((entry = entry->prev) != &q->queue_head) { |
| 26 | __rq = list_entry_rq(entry); |
| 27 | |
| 28 | if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) |
| 29 | break; |
| 30 | else if (__rq->flags & REQ_STARTED) |
| 31 | break; |
| 32 | |
| 33 | if (!blk_fs_request(__rq)) |
| 34 | continue; |
| 35 | |
| 36 | if ((ret = elv_try_merge(__rq, bio))) { |
| 37 | *req = __rq; |
| 38 | q->last_merge = __rq; |
| 39 | return ret; |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | return ELEVATOR_NO_MERGE; |
| 44 | } |
| 45 | |
| 46 | static void elevator_noop_merge_requests(request_queue_t *q, struct request *req, |
| 47 | struct request *next) |
| 48 | { |
| 49 | list_del_init(&next->queuelist); |
| 50 | } |
| 51 | |
| 52 | static void elevator_noop_add_request(request_queue_t *q, struct request *rq, |
| 53 | int where) |
| 54 | { |
| 55 | if (where == ELEVATOR_INSERT_FRONT) |
| 56 | list_add(&rq->queuelist, &q->queue_head); |
| 57 | else |
| 58 | list_add_tail(&rq->queuelist, &q->queue_head); |
| 59 | |
| 60 | /* |
| 61 | * new merges must not precede this barrier |
| 62 | */ |
| 63 | if (rq->flags & REQ_HARDBARRIER) |
| 64 | q->last_merge = NULL; |
| 65 | else if (!q->last_merge) |
| 66 | q->last_merge = rq; |
| 67 | } |
| 68 | |
| 69 | static struct request *elevator_noop_next_request(request_queue_t *q) |
| 70 | { |
| 71 | if (!list_empty(&q->queue_head)) |
| 72 | return list_entry_rq(q->queue_head.next); |
| 73 | |
| 74 | return NULL; |
| 75 | } |
| 76 | |
| 77 | static struct elevator_type elevator_noop = { |
| 78 | .ops = { |
| 79 | .elevator_merge_fn = elevator_noop_merge, |
| 80 | .elevator_merge_req_fn = elevator_noop_merge_requests, |
| 81 | .elevator_next_req_fn = elevator_noop_next_request, |
| 82 | .elevator_add_req_fn = elevator_noop_add_request, |
| 83 | }, |
| 84 | .elevator_name = "noop", |
| 85 | .elevator_owner = THIS_MODULE, |
| 86 | }; |
| 87 | |
| 88 | static int __init noop_init(void) |
| 89 | { |
| 90 | return elv_register(&elevator_noop); |
| 91 | } |
| 92 | |
| 93 | static void __exit noop_exit(void) |
| 94 | { |
| 95 | elv_unregister(&elevator_noop); |
| 96 | } |
| 97 | |
| 98 | module_init(noop_init); |
| 99 | module_exit(noop_exit); |
| 100 | |
| 101 | |
| 102 | MODULE_AUTHOR("Jens Axboe"); |
| 103 | MODULE_LICENSE("GPL"); |
| 104 | MODULE_DESCRIPTION("No-op IO scheduler"); |