]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
block: add a queue flag for request stacking support
authorKiyoshi Ueda <k-ueda@ct.jp.nec.com>
Thu, 18 Sep 2008 14:46:13 +0000 (10:46 -0400)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 9 Oct 2008 06:56:18 +0000 (08:56 +0200)
This patch adds a queue flag to indicate the block device can be
used for request stacking.

Request stacking drivers need to stack their devices on top of
only devices of which q->request_fn is functional.
Since bio stacking drivers (e.g. md, loop) basically initialize
their queue using blk_alloc_queue() and don't set q->request_fn,
the check of (q->request_fn == NULL) looks enough for that purpose.

However, dm will become both types of stacking driver (bio-based and
request-based).  And dm will always set q->request_fn even if the dm
device is bio-based of which q->request_fn is not functional actually.
So we need something else to distinguish the type of the device.
Adding a queue flag is a solution for that.

The reason why dm always sets q->request_fn is to keep
the compatibility of dm user-space tools.
Currently, all dm user-space tools are using bio-based dm without
specifying the type of the dm device they use.
To use request-based dm without changing such tools, the kernel
must decide the type of the dm device automatically.
The automatic type decision can't be done at the device creation time
and needs to be deferred until such tools load a mapping table,
since the actual type is decided by dm target type included in
the mapping table.

So a dm device has to be initialized using blk_init_queue()
so that we can load either type of table.
Then, all queue stuffs are set (e.g. q->request_fn) and we have
no element to distinguish that it is bio-based or request-based,
even after a table is loaded and the type of the device is decided.

By the way, some stuffs of the queue (e.g. request_list, elevator)
are needless when the dm device is used as bio-based.
But the memory size is not so large (about 20[KB] per queue on ia64),
so I hope the memory loss can be acceptable for bio-based dm users.

Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
block/blk-core.c
include/linux/blkdev.h

index b8ffbfe85ca41101590d033a28a3997d572f3d00..fa212348c4c96df59b41325259d2215eed12abd6 100644 (file)
@@ -574,7 +574,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
        q->request_fn           = rfn;
        q->prep_rq_fn           = NULL;
        q->unplug_fn            = generic_unplug_device;
-       q->queue_flags          = (1 << QUEUE_FLAG_CLUSTER);
+       q->queue_flags          = (1 << QUEUE_FLAG_CLUSTER |
+                                  1 << QUEUE_FLAG_STACKABLE);
        q->queue_lock           = lock;
 
        blk_queue_segment_boundary(q, 0xffffffff);
index 964c246bc271a83538f38a2a0a44d9b71c909047..86f77ef127f48948943abb208568048f362a0f81 100644 (file)
@@ -441,6 +441,7 @@ struct request_queue
 #define QUEUE_FLAG_NOMERGES    10      /* disable merge attempts */
 #define QUEUE_FLAG_SAME_COMP   11      /* force complete on same CPU */
 #define QUEUE_FLAG_FAIL_IO     12      /* fake timeout */
+#define QUEUE_FLAG_STACKABLE   13      /* supports request stacking */
 
 static inline int queue_is_locked(struct request_queue *q)
 {
@@ -547,6 +548,8 @@ enum {
 #define blk_queue_stopped(q)   test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_nomerges(q)  test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
 #define blk_queue_flushing(q)  ((q)->ordseq)
+#define blk_queue_stackable(q) \
+       test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
 
 #define blk_fs_request(rq)     ((rq)->cmd_type == REQ_TYPE_FS)
 #define blk_pc_request(rq)     ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)