[PATCH] Remove ->waiting member from struct request
[safe/jmp/linux-2.6] / include / linux / blkdev.h
index 5d32731..604f231 100644 (file)
@@ -120,6 +120,86 @@ struct request_list {
        wait_queue_head_t wait[2];
 };
 
+/*
+ * request command types
+ */
+enum rq_cmd_type_bits {
+       REQ_TYPE_FS             = 1,    /* fs request */
+       REQ_TYPE_BLOCK_PC,              /* scsi command */
+       REQ_TYPE_SENSE,                 /* sense request */
+       REQ_TYPE_PM_SUSPEND,            /* suspend request */
+       REQ_TYPE_PM_RESUME,             /* resume request */
+       REQ_TYPE_PM_SHUTDOWN,           /* shutdown request */
+       REQ_TYPE_FLUSH,                 /* flush request */
+       REQ_TYPE_SPECIAL,               /* driver defined type */
+       REQ_TYPE_LINUX_BLOCK,           /* generic block layer message */
+       /*
+        * for ATA/ATAPI devices. this really doesn't belong here, ide should
+        * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver
+        * private REQ_LB opcodes to differentiate what type of request this is
+        */
+       REQ_TYPE_ATA_CMD,
+       REQ_TYPE_ATA_TASK,
+       REQ_TYPE_ATA_TASKFILE,
+};
+
+/*
+ * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being
+ * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a
+ * SCSI cdb.
+ *
+ * 0x00 -> 0x3f are driver private, to be used for whatever purpose they need,
+ * typically to differentiate REQ_TYPE_SPECIAL requests.
+ *
+ */
+enum {
+       /*
+        * just examples for now
+        */
+       REQ_LB_OP_EJECT = 0x40,         /* eject request */
+       REQ_LB_OP_FLUSH = 0x41,         /* flush device */
+};
+
+/*
+ * request type modified bits. first three bits match BIO_RW* bits, important
+ */
+enum rq_flag_bits {
+       __REQ_RW,               /* not set, read. set, write */
+       __REQ_FAILFAST,         /* no low level driver retries */
+       __REQ_SORTED,           /* elevator knows about this request */
+       __REQ_SOFTBARRIER,      /* may not be passed by ioscheduler */
+       __REQ_HARDBARRIER,      /* may not be passed by drive either */
+       __REQ_FUA,              /* forced unit access */
+       __REQ_NOMERGE,          /* don't touch this for merging */
+       __REQ_STARTED,          /* drive already may have started this one */
+       __REQ_DONTPREP,         /* don't call prep for this one */
+       __REQ_QUEUED,           /* uses queueing */
+       __REQ_ELVPRIV,          /* elevator private data attached */
+       __REQ_FAILED,           /* set if the request failed */
+       __REQ_QUIET,            /* don't worry about errors */
+       __REQ_PREEMPT,          /* set for "ide_preempt" requests */
+       __REQ_ORDERED_COLOR,    /* is before or after barrier */
+       __REQ_RW_SYNC,          /* request is sync (O_DIRECT) */
+       __REQ_NR_BITS,          /* stops here */
+};
+
+#define REQ_RW         (1 << __REQ_RW)
+#define REQ_FAILFAST   (1 << __REQ_FAILFAST)
+#define REQ_SORTED     (1 << __REQ_SORTED)
+#define REQ_SOFTBARRIER        (1 << __REQ_SOFTBARRIER)
+#define REQ_HARDBARRIER        (1 << __REQ_HARDBARRIER)
+#define REQ_FUA                (1 << __REQ_FUA)
+#define REQ_NOMERGE    (1 << __REQ_NOMERGE)
+#define REQ_STARTED    (1 << __REQ_STARTED)
+#define REQ_DONTPREP   (1 << __REQ_DONTPREP)
+#define REQ_QUEUED     (1 << __REQ_QUEUED)
+#define REQ_ELVPRIV    (1 << __REQ_ELVPRIV)
+#define REQ_FAILED     (1 << __REQ_FAILED)
+#define REQ_QUIET      (1 << __REQ_QUIET)
+#define REQ_PREEMPT    (1 << __REQ_PREEMPT)
+#define REQ_ORDERED_COLOR      (1 << __REQ_ORDERED_COLOR)
+#define REQ_RW_SYNC    (1 << __REQ_RW_SYNC)
+
 #define BLK_MAX_CDB    16
 
 /*
@@ -129,7 +209,8 @@ struct request {
        struct list_head queuelist;
        struct list_head donelist;
 
-       unsigned long flags;            /* see REQ_ bits below */
+       unsigned int cmd_flags;
+       enum rq_cmd_type_bits cmd_type;
 
        /* Maintain bio traversal state for part by part I/O submission.
         * hard_* are block layer internals, no driver should touch them!
@@ -148,14 +229,21 @@ struct request {
        struct bio *bio;
        struct bio *biotail;
 
+       struct hlist_node hash; /* merge hash */
+       struct rb_node rb_node; /* sort/lookup */
+
+       /*
+        * 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;
 
-       unsigned short ioprio;
+       void *completion_data;
 
        int rq_status;  /* should split this into a few status bits */
-       struct gendisk *rq_disk;
        int errors;
+       struct gendisk *rq_disk;
        unsigned long start_time;
 
        /* Number of scatter-gather DMA addr+len pairs after
@@ -170,15 +258,16 @@ struct request {
         */
        unsigned short nr_hw_segments;
 
+       unsigned short ioprio;
+
        int tag;
-       char *buffer;
 
        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
@@ -187,92 +276,22 @@ struct request {
        unsigned char cmd[BLK_MAX_CDB];
 
        unsigned int data_len;
-       void *data;
-
        unsigned int sense_len;
+       void *data;
        void *sense;
 
        unsigned int timeout;
        int retries;
 
        /*
-        * For Power Management requests
-        */
-       struct request_pm_state *pm;
-
-       /*
-        * completion callback. end_io_data should be folded in with waiting
+        * completion callback.
         */
        rq_end_io_fn *end_io;
        void *end_io_data;
 };
 
 /*
- * first three bits match BIO_RW* bits, important
- */
-enum rq_flag_bits {
-       __REQ_RW,               /* not set, read. set, write */
-       __REQ_FAILFAST,         /* no low level driver retries */
-       __REQ_SORTED,           /* elevator knows about this request */
-       __REQ_SOFTBARRIER,      /* may not be passed by ioscheduler */
-       __REQ_HARDBARRIER,      /* may not be passed by drive either */
-       __REQ_FUA,              /* forced unit access */
-       __REQ_CMD,              /* is a regular fs rw request */
-       __REQ_NOMERGE,          /* don't touch this for merging */
-       __REQ_STARTED,          /* drive already may have started this one */
-       __REQ_DONTPREP,         /* don't call prep for this one */
-       __REQ_QUEUED,           /* uses queueing */
-       __REQ_ELVPRIV,          /* elevator private data attached */
-       /*
-        * for ATA/ATAPI devices
-        */
-       __REQ_PC,               /* packet command (special) */
-       __REQ_BLOCK_PC,         /* queued down pc from block layer */
-       __REQ_SENSE,            /* sense retrival */
-
-       __REQ_FAILED,           /* set if the request failed */
-       __REQ_QUIET,            /* don't worry about errors */
-       __REQ_SPECIAL,          /* driver suplied command */
-       __REQ_DRIVE_CMD,
-       __REQ_DRIVE_TASK,
-       __REQ_DRIVE_TASKFILE,
-       __REQ_PREEMPT,          /* set for "ide_preempt" requests */
-       __REQ_PM_SUSPEND,       /* suspend request */
-       __REQ_PM_RESUME,        /* resume request */
-       __REQ_PM_SHUTDOWN,      /* shutdown request */
-       __REQ_ORDERED_COLOR,    /* is before or after barrier */
-       __REQ_NR_BITS,          /* stops here */
-};
-
-#define REQ_RW         (1 << __REQ_RW)
-#define REQ_FAILFAST   (1 << __REQ_FAILFAST)
-#define REQ_SORTED     (1 << __REQ_SORTED)
-#define REQ_SOFTBARRIER        (1 << __REQ_SOFTBARRIER)
-#define REQ_HARDBARRIER        (1 << __REQ_HARDBARRIER)
-#define REQ_FUA                (1 << __REQ_FUA)
-#define REQ_CMD                (1 << __REQ_CMD)
-#define REQ_NOMERGE    (1 << __REQ_NOMERGE)
-#define REQ_STARTED    (1 << __REQ_STARTED)
-#define REQ_DONTPREP   (1 << __REQ_DONTPREP)
-#define REQ_QUEUED     (1 << __REQ_QUEUED)
-#define REQ_ELVPRIV    (1 << __REQ_ELVPRIV)
-#define REQ_PC         (1 << __REQ_PC)
-#define REQ_BLOCK_PC   (1 << __REQ_BLOCK_PC)
-#define REQ_SENSE      (1 << __REQ_SENSE)
-#define REQ_FAILED     (1 << __REQ_FAILED)
-#define REQ_QUIET      (1 << __REQ_QUIET)
-#define REQ_SPECIAL    (1 << __REQ_SPECIAL)
-#define REQ_DRIVE_CMD  (1 << __REQ_DRIVE_CMD)
-#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)
-#define REQ_DRIVE_TASKFILE     (1 << __REQ_DRIVE_TASKFILE)
-#define REQ_PREEMPT    (1 << __REQ_PREEMPT)
-#define REQ_PM_SUSPEND (1 << __REQ_PM_SUSPEND)
-#define REQ_PM_RESUME  (1 << __REQ_PM_RESUME)
-#define REQ_PM_SHUTDOWN        (1 << __REQ_PM_SHUTDOWN)
-#define REQ_ORDERED_COLOR      (1 << __REQ_ORDERED_COLOR)
-
-/*
- * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
+ * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME
  * requests. Some step values could eventually be made generic.
  */
 struct request_pm_state
@@ -421,9 +440,9 @@ struct request_queue
        unsigned int            sg_timeout;
        unsigned int            sg_reserved_size;
        int                     node;
-
+#ifdef CONFIG_BLK_DEV_IO_TRACE
        struct blk_trace        *blk_trace;
-
+#endif
        /*
         * reserved for flush operations
         */
@@ -438,9 +457,6 @@ struct request_queue
 
 #define RQ_INACTIVE            (-1)
 #define RQ_ACTIVE              1
-#define RQ_SCSI_BUSY           0xffff
-#define RQ_SCSI_DONE           0xfffe
-#define RQ_SCSI_DISCONNECTING  0xffe0
 
 #define QUEUE_FLAG_CLUSTER     0       /* cluster several segments into 1 */
 #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
@@ -497,25 +513,33 @@ enum {
 #define blk_queue_stopped(q)   test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_flushing(q)  ((q)->ordseq)
 
-#define blk_fs_request(rq)     ((rq)->flags & REQ_CMD)
-#define blk_pc_request(rq)     ((rq)->flags & REQ_BLOCK_PC)
-#define blk_noretry_request(rq)        ((rq)->flags & REQ_FAILFAST)
-#define blk_rq_started(rq)     ((rq)->flags & REQ_STARTED)
+#define blk_fs_request(rq)     ((rq)->cmd_type == REQ_TYPE_FS)
+#define blk_pc_request(rq)     ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
+#define blk_special_request(rq)        ((rq)->cmd_type == REQ_TYPE_SPECIAL)
+#define blk_sense_request(rq)  ((rq)->cmd_type == REQ_TYPE_SENSE)
+
+#define blk_noretry_request(rq)        ((rq)->cmd_flags & REQ_FAILFAST)
+#define blk_rq_started(rq)     ((rq)->cmd_flags & REQ_STARTED)
 
 #define blk_account_rq(rq)     (blk_rq_started(rq) && blk_fs_request(rq))
 
-#define blk_pm_suspend_request(rq)     ((rq)->flags & REQ_PM_SUSPEND)
-#define blk_pm_resume_request(rq)      ((rq)->flags & REQ_PM_RESUME)
+#define blk_pm_suspend_request(rq)     ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND)
+#define blk_pm_resume_request(rq)      ((rq)->cmd_type == REQ_TYPE_PM_RESUME)
 #define blk_pm_request(rq)     \
-       ((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+       (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq))
 
-#define blk_sorted_rq(rq)      ((rq)->flags & REQ_SORTED)
-#define blk_barrier_rq(rq)     ((rq)->flags & REQ_HARDBARRIER)
-#define blk_fua_rq(rq)         ((rq)->flags & REQ_FUA)
+#define blk_sorted_rq(rq)      ((rq)->cmd_flags & REQ_SORTED)
+#define blk_barrier_rq(rq)     ((rq)->cmd_flags & REQ_HARDBARRIER)
+#define blk_fua_rq(rq)         ((rq)->cmd_flags & REQ_FUA)
 
 #define list_entry_rq(ptr)     list_entry((ptr), struct request, queuelist)
 
-#define rq_data_dir(rq)                ((rq)->flags & 1)
+#define rq_data_dir(rq)                ((rq)->cmd_flags & 1)
+
+/*
+ * 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)
 
 static inline int blk_queue_full(struct request_queue *q, int rw)
 {
@@ -548,7 +572,7 @@ static inline void blk_clear_queue_full(struct request_queue *q, int rw)
 #define RQ_NOMERGE_FLAGS       \
        (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER)
 #define rq_mergeable(rq)       \
-       (!((rq)->flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
+       (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
 
 /*
  * noop, requests are automagically marked as active/inactive by I/O
@@ -686,21 +710,6 @@ static inline void blkdev_dequeue_request(struct request *req)
 }
 
 /*
- * This should be in elevator.h, but that requires pulling in rq and q
- */
-static inline void elv_dispatch_add_tail(struct request_queue *q,
-                                        struct request *rq)
-{
-       if (q->last_merge == rq)
-               q->last_merge = NULL;
-       q->nr_sorted--;
-
-       q->end_sector = rq_end_sector(rq);
-       q->boundary_rq = rq;
-       list_add_tail(&rq->queuelist, &q->queue_head);
-}
-
-/*
  * Access functions for manipulating queue properties
  */
 extern request_queue_t *blk_init_queue_node(request_fn_proc *rfn,
@@ -744,7 +753,7 @@ extern void blk_put_queue(request_queue_t *);
  */
 #define blk_queue_tag_depth(q)         ((q)->queue_tags->busy)
 #define blk_queue_tag_queue(q)         ((q)->queue_tags->busy < (q)->queue_tags->max_depth)
-#define blk_rq_tagged(rq)              ((rq)->flags & REQ_QUEUED)
+#define blk_rq_tagged(rq)              ((rq)->cmd_flags & REQ_QUEUED)
 extern int blk_queue_start_tag(request_queue_t *, struct request *);
 extern struct request *blk_queue_find_tag(request_queue_t *, int);
 extern void blk_queue_end_tag(request_queue_t *, struct request *);
@@ -753,6 +762,9 @@ 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);
 
 extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
 extern int blkdev_issue_flush(struct block_device *, sector_t *);