|
@@ -0,0 +1,82 @@
|
|
|
+/*
|
|
|
+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
+ * Copyright (C) 1994, Karl Keyte: Added support for disk statistics
|
|
|
+ * Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
|
|
|
+ * Queue request tables / lock, selectable elevator, Jens Axboe <axboe@suse.de>
|
|
|
+ * kernel-doc documentation started by NeilBrown <neilb@cse.unsw.edu.au>
|
|
|
+ * - July2000
|
|
|
+ * bio rewrite, highmem i/o, etc, Jens Axboe <axboe@suse.de> - may 2001
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * This handles all read/write requests to block devices
|
|
|
+ */
|
|
|
+#include <linux/kernel.h>
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/backing-dev.h>
|
|
|
+#include <linux/bio.h>
|
|
|
+#include <linux/blkdev.h>
|
|
|
+#include <linux/highmem.h>
|
|
|
+#include <linux/mm.h>
|
|
|
+#include <linux/kernel_stat.h>
|
|
|
+#include <linux/string.h>
|
|
|
+#include <linux/init.h>
|
|
|
+#include <linux/completion.h>
|
|
|
+#include <linux/slab.h>
|
|
|
+#include <linux/swap.h>
|
|
|
+#include <linux/writeback.h>
|
|
|
+#include <linux/task_io_accounting_ops.h>
|
|
|
+#include <linux/fault-inject.h>
|
|
|
+#include <linux/list_sort.h>
|
|
|
+#include <linux/delay.h>
|
|
|
+#include <linux/ratelimit.h>
|
|
|
+
|
|
|
+#define CREATE_TRACE_POINTS
|
|
|
+#include <trace/events/block.h>
|
|
|
+
|
|
|
+#include "blk.h"
|
|
|
+#include "blk-cgroup.h"
|
|
|
+
|
|
|
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
|
|
|
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
|
|
|
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
|
|
|
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug);
|
|
|
+
|
|
|
+DEFINE_IDA(blk_queue_ida);
|
|
|
+
|
|
|
+/*
|
|
|
+ * For the allocated request tables
|
|
|
+ */
|
|
|
+static struct kmem_cache *request_cachep;
|
|
|
+
|
|
|
+/*
|
|
|
+ * For queue allocation
|
|
|
+ */
|
|
|
+struct kmem_cache *blk_requestq_cachep;
|
|
|
+
|
|
|
+/*
|
|
|
+ * Controlling structure to kblockd
|
|
|
+ */
|
|
|
+static struct workqueue_struct *kblockd_workqueue;
|
|
|
+
|
|
|
+static void drive_stat_acct(struct request *rq, int new_io)
|
|
|
+{
|
|
|
+ struct hd_struct *part;
|
|
|
+ int rw = rq_data_dir(rq);
|
|
|
+ int cpu;
|
|
|
+
|
|
|
+ if (!blk_do_io_stat(rq))
|
|
|
+ return;
|
|
|
+
|
|
|
+ cpu = part_stat_lock();
|
|
|
+
|
|
|
+ if (!new_io) {
|
|
|
+ part = rq->part;
|
|
|
+ part_stat_inc(cpu, part, merges[rw]);
|
|
|
+ } else {
|
|
|
+ part = disk_map_sector_rcu(rq->rq_disk, blk_rq_pos(rq));
|
|
|
+ if (!hd_struct_try_get(part)) {
|
|
|
+ /*
|
|
|
+ * The partition is already being removed,
|
|
|
+ * the request will be accounted on the disk only
|
|
|
+ *
|