[PATCH] block: support larger block pc requests
[safe/jmp/linux-2.6] / include / linux / blkdev.h
index 55ef6ef..e1c7286 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_BLKDEV_H
 #define _LINUX_BLKDEV_H
 
+#include <linux/sched.h>
 #include <linux/major.h>
 #include <linux/genhd.h>
 #include <linux/list.h>
 
 #include <asm/scatterlist.h>
 
+#ifdef CONFIG_LBD
+# include <asm/div64.h>
+# define sector_div(a, b) do_div(a, b)
+#else
+# define sector_div(n, b)( \
+{ \
+       int _res; \
+       _res = (n) % (b); \
+       (n) /= (b); \
+       _res; \
+} \
+)
+#endif
+
+#ifdef CONFIG_BLOCK
+
 struct scsi_ioctl_command;
 
 struct request_queue;
@@ -90,7 +107,7 @@ struct io_context {
        atomic_t refcount;
        struct task_struct *task;
 
-       int (*set_ioprio)(struct io_context *, unsigned int);
+       unsigned int ioprio_changed;
 
        /*
         * For request batching
@@ -104,8 +121,7 @@ struct io_context {
 
 void put_io_context(struct io_context *ioc);
 void exit_io_context(void);
-struct io_context *current_io_context(gfp_t gfp_flags);
-struct io_context *get_io_context(gfp_t gfp_flags);
+struct io_context *get_io_context(gfp_t gfp_flags, int node);
 void copy_io_context(struct io_context **pdst, struct io_context **psrc);
 void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
 
@@ -141,6 +157,7 @@ enum rq_cmd_type_bits {
        REQ_TYPE_ATA_CMD,
        REQ_TYPE_ATA_TASK,
        REQ_TYPE_ATA_TASKFILE,
+       REQ_TYPE_ATA_PC,
 };
 
 /*
@@ -180,6 +197,8 @@ enum rq_flag_bits {
        __REQ_PREEMPT,          /* set for "ide_preempt" requests */
        __REQ_ORDERED_COLOR,    /* is before or after barrier */
        __REQ_RW_SYNC,          /* request is sync (O_DIRECT) */
+       __REQ_ALLOCED,          /* request came from our alloc pool */
+       __REQ_RW_META,          /* metadata io request */
        __REQ_NR_BITS,          /* stops here */
 };
 
@@ -199,6 +218,8 @@ enum rq_flag_bits {
 #define REQ_PREEMPT    (1 << __REQ_PREEMPT)
 #define REQ_ORDERED_COLOR      (1 << __REQ_ORDERED_COLOR)
 #define REQ_RW_SYNC    (1 << __REQ_RW_SYNC)
+#define REQ_ALLOCED    (1 << __REQ_ALLOCED)
+#define REQ_RW_META    (1 << __REQ_RW_META)
 
 #define BLK_MAX_CDB    16
 
@@ -209,6 +230,8 @@ struct request {
        struct list_head queuelist;
        struct list_head donelist;
 
+       request_queue_t *q;
+
        unsigned int cmd_flags;
        enum rq_cmd_type_bits cmd_type;
 
@@ -217,12 +240,12 @@ struct request {
         */
 
        sector_t sector;                /* next sector to submit */
+       sector_t hard_sector;           /* next sector to complete */
        unsigned long nr_sectors;       /* no. of sectors left to submit */
+       unsigned long hard_nr_sectors;  /* no. of sectors left to complete */
        /* no. of sectors left to submit in the current segment */
        unsigned int current_nr_sectors;
 
-       sector_t hard_sector;           /* next sector to complete */
-       unsigned long hard_nr_sectors;  /* no. of sectors left to complete */
        /* no. of sectors left to complete in the current segment */
        unsigned int hard_cur_sectors;
 
@@ -230,13 +253,23 @@ struct request {
        struct bio *biotail;
 
        struct hlist_node hash; /* merge hash */
-       struct rb_node rb_node; /* sort/lookup */
+       /*
+        * The rb_node is only used inside the io scheduler, requests
+        * are pruned when moved to the dispatch queue. So let the
+        * completion_data share space with the rb_node.
+        */
+       union {
+               struct rb_node rb_node; /* sort/lookup */
+               void *completion_data;
+       };
 
+       /*
+        * two pointers are available for the IO schedulers, if they need
+        * more they have to dynamically allocate it.
+        */
        void *elevator_private;
-       void *completion_data;
+       void *elevator_private2;
 
-       int rq_status;  /* should split this into a few status bits */
-       int errors;
        struct gendisk *rq_disk;
        unsigned long start_time;
 
@@ -254,15 +287,13 @@ struct request {
 
        unsigned short ioprio;
 
+       void *special;
+       char *buffer;
+
        int tag;
+       int errors;
 
        int ref_count;
-       request_queue_t *q;
-       struct request_list *rl;
-
-       struct completion *waiting;
-       void *special;
-       char *buffer;
 
        /*
         * when request is used as a packet command carrier
@@ -279,7 +310,7 @@ struct request {
        int retries;
 
        /*
-        * completion callback. end_io_data should be folded in with waiting
+        * completion callback.
         */
        rq_end_io_fn *end_io;
        void *end_io_data;
@@ -450,9 +481,6 @@ struct request_queue
        struct mutex            sysfs_lock;
 };
 
-#define RQ_INACTIVE            (-1)
-#define RQ_ACTIVE              1
-
 #define QUEUE_FLAG_CLUSTER     0       /* cluster several segments into 1 */
 #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
 #define QUEUE_FLAG_STOPPED     2       /* queue is stopped */
@@ -535,6 +563,7 @@ enum {
  * We regard a request as sync, if it's a READ or a SYNC write.
  */
 #define rq_is_sync(rq)         (rq_data_dir((rq)) == READ || (rq)->cmd_flags & REQ_RW_SYNC)
+#define rq_is_meta(rq)         ((rq)->cmd_flags & REQ_RW_META)
 
 static inline int blk_queue_full(struct request_queue *q, int rw)
 {
@@ -570,12 +599,6 @@ static inline void blk_clear_queue_full(struct request_queue *q, int rw)
        (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
 
 /*
- * noop, requests are automagically marked as active/inactive by I/O
- * scheduler -- see elv_next_request
- */
-#define blk_queue_headactive(q, head_active)
-
-/*
  * q->prep_rq_fn return values
  */
 #define BLKPREP_OK             0       /* serve it */
@@ -612,11 +635,6 @@ static inline void blk_queue_bounce(request_queue_t *q, struct bio **bio)
        if ((rq->bio))                  \
                for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next)
 
-struct sec_size {
-       unsigned block_size;
-       unsigned block_size_bits;
-};
-
 extern int blk_register_queue(struct gendisk *disk);
 extern void blk_unregister_queue(struct gendisk *disk);
 extern void register_disk(struct gendisk *dev);
@@ -633,16 +651,38 @@ extern void blk_recount_segments(request_queue_t *, struct bio *);
 extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *);
 extern int sg_scsi_ioctl(struct file *, struct request_queue *,
                struct gendisk *, struct scsi_ioctl_command __user *);
+
+/*
+ * A queue has just exitted congestion.  Note this in the global counter of
+ * congested queues, and wake up anyone who was waiting for requests to be
+ * put back.
+ */
+static inline void blk_clear_queue_congested(request_queue_t *q, int rw)
+{
+       clear_bdi_congested(&q->backing_dev_info, rw);
+}
+
+/*
+ * A queue has just entered congestion.  Flag that in the queue's VM-visible
+ * state flags and increment the global gounter of congested queues.
+ */
+static inline void blk_set_queue_congested(request_queue_t *q, int rw)
+{
+       set_bdi_congested(&q->backing_dev_info, rw);
+}
+
 extern void blk_start_queue(request_queue_t *q);
 extern void blk_stop_queue(request_queue_t *q);
 extern void blk_sync_queue(struct request_queue *q);
 extern void __blk_stop_queue(request_queue_t *q);
 extern void blk_run_queue(request_queue_t *);
+extern void blk_start_queueing(request_queue_t *);
 extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *);
-extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
-extern int blk_rq_unmap_user(struct bio *, unsigned int);
+extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned long);
+extern int blk_rq_unmap_user(struct request *);
 extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
-extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
+extern int blk_rq_map_user_iov(request_queue_t *, struct request *,
+                              struct sg_iovec *, int, unsigned int);
 extern int blk_execute_rq(request_queue_t *, struct gendisk *,
                          struct request *, int);
 extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
@@ -681,16 +721,6 @@ extern void end_that_request_last(struct request *, int);
 extern void end_request(struct request *req, int uptodate);
 extern void blk_complete_request(struct request *);
 
-static inline int rq_all_done(struct request *rq, unsigned int nr_bytes)
-{
-       if (blk_fs_request(rq))
-               return (nr_bytes >= (rq->hard_nr_sectors << 9));
-       else if (blk_pc_request(rq))
-               return nr_bytes >= rq->data_len;
-
-       return 0;
-}
-
 /*
  * end_that_request_first/chunk() takes an uptodate argument. we account
  * any value <= as an io error. 0 means -EIO for compatability reasons,
@@ -756,10 +786,16 @@ extern int blk_queue_init_tags(request_queue_t *, int, struct blk_queue_tag *);
 extern void blk_queue_free_tags(request_queue_t *);
 extern int blk_queue_resize_tags(request_queue_t *, int);
 extern void blk_queue_invalidate_tags(request_queue_t *);
-extern long blk_congestion_wait(int rw, long timeout);
 extern struct blk_queue_tag *blk_init_tags(int);
 extern void blk_free_tags(struct blk_queue_tag *);
-extern void blk_congestion_end(int rw);
+
+static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
+                                               int tag)
+{
+       if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))
+               return NULL;
+       return bqt->tag_index[tag];
+}
 
 extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
 extern int blkdev_issue_flush(struct block_device *, sector_t *);
@@ -798,14 +834,6 @@ static inline int queue_dma_alignment(request_queue_t *q)
        return retval;
 }
 
-static inline int bdev_dma_aligment(struct block_device *bdev)
-{
-       return queue_dma_alignment(bdev_get_queue(bdev));
-}
-
-#define blk_finished_io(nsects)        do { } while (0)
-#define blk_started_io(nsects) do { } while (0)
-
 /* assumes size > 256 */
 static inline unsigned int blksize_bits(unsigned int size)
 {
@@ -835,24 +863,32 @@ struct work_struct;
 int kblockd_schedule_work(struct work_struct *work);
 void kblockd_flush(void);
 
-#ifdef CONFIG_LBD
-# include <asm/div64.h>
-# define sector_div(a, b) do_div(a, b)
-#else
-# define sector_div(n, b)( \
-{ \
-       int _res; \
-       _res = (n) % (b); \
-       (n) /= (b); \
-       _res; \
-} \
-)
-#endif 
-
 #define MODULE_ALIAS_BLOCKDEV(major,minor) \
        MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
 #define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \
        MODULE_ALIAS("block-major-" __stringify(major) "-*")
 
 
+#else /* CONFIG_BLOCK */
+/*
+ * stubs for when the block layer is configured out
+ */
+#define buffer_heads_over_limit 0
+
+static inline long blk_congestion_wait(int rw, long timeout)
+{
+       return io_schedule_timeout(timeout);
+}
+
+static inline long nr_blockdev_pages(void)
+{
+       return 0;
+}
+
+static inline void exit_io_context(void)
+{
+}
+
+#endif /* CONFIG_BLOCK */
+
 #endif