]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - include/linux/blkdev.h
block: unify flags for struct bio and struct request
[net-next-2.6.git] / include / linux / blkdev.h
index 6690e8bae7bb5946396577fcc12a9c85836cb7b5..3fc0f5908619e0b3fc878bbcec4b352faf1fbca7 100644 (file)
@@ -84,70 +84,6 @@ enum {
        REQ_LB_OP_FLUSH = 0x41,         /* flush request */
 };
 
-/*
- * request type modified bits. first four bits match BIO_RW* bits, important
- */
-enum rq_flag_bits {
-       __REQ_RW,               /* not set, read. set, write */
-       __REQ_FAILFAST_DEV,     /* no driver retries of device errors */
-       __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
-       __REQ_FAILFAST_DRIVER,  /* no driver retries of driver errors */
-       /* above flags must match BIO_RW_* */
-       __REQ_DISCARD,          /* request to discard sectors */
-       __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 (sync write or read) */
-       __REQ_ALLOCED,          /* request came from our alloc pool */
-       __REQ_RW_META,          /* metadata io request */
-       __REQ_COPY_USER,        /* contains copies of user pages */
-       __REQ_INTEGRITY,        /* integrity metadata has been remapped */
-       __REQ_NOIDLE,           /* Don't anticipate more IO after this one */
-       __REQ_IO_STAT,          /* account I/O stat */
-       __REQ_MIXED_MERGE,      /* merge of different types, fail separately */
-       __REQ_NR_BITS,          /* stops here */
-};
-
-#define REQ_RW         (1 << __REQ_RW)
-#define REQ_FAILFAST_DEV       (1 << __REQ_FAILFAST_DEV)
-#define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT)
-#define REQ_FAILFAST_DRIVER    (1 << __REQ_FAILFAST_DRIVER)
-#define REQ_DISCARD    (1 << __REQ_DISCARD)
-#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 REQ_ALLOCED    (1 << __REQ_ALLOCED)
-#define REQ_RW_META    (1 << __REQ_RW_META)
-#define REQ_COPY_USER  (1 << __REQ_COPY_USER)
-#define REQ_INTEGRITY  (1 << __REQ_INTEGRITY)
-#define REQ_NOIDLE     (1 << __REQ_NOIDLE)
-#define REQ_IO_STAT    (1 << __REQ_IO_STAT)
-#define REQ_MIXED_MERGE        (1 << __REQ_MIXED_MERGE)
-
-#define REQ_FAILFAST_MASK      (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | \
-                                REQ_FAILFAST_DRIVER)
-
 #define BLK_MAX_CDB    16
 
 /*
@@ -186,15 +122,19 @@ struct request {
        };
 
        /*
-        * two pointers are available for the IO schedulers, if they need
+        * Three pointers are available for the IO schedulers, if they need
         * more they have to dynamically allocate it.
         */
        void *elevator_private;
        void *elevator_private2;
+       void *elevator_private3;
 
        struct gendisk *rq_disk;
        unsigned long start_time;
-
+#ifdef CONFIG_BLK_CGROUP
+       unsigned long long start_time_ns;
+       unsigned long long io_start_time_ns;    /* when passed to hardware */
+#endif
        /* Number of scatter-gather DMA addr+len pairs after
         * physical address coalescing is performed.
         */
@@ -463,11 +403,13 @@ struct request_queue
 #define QUEUE_FLAG_IO_STAT     15      /* do IO stats */
 #define QUEUE_FLAG_DISCARD     16      /* supports DISCARD */
 #define QUEUE_FLAG_NOXMERGES   17      /* No extended merges */
+#define QUEUE_FLAG_ADD_RANDOM  18      /* Contributes to random pool */
 
 #define QUEUE_FLAG_DEFAULT     ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_CLUSTER) |            \
                                 (1 << QUEUE_FLAG_STACKABLE)    |       \
-                                (1 << QUEUE_FLAG_SAME_COMP))
+                                (1 << QUEUE_FLAG_SAME_COMP)    |       \
+                                (1 << QUEUE_FLAG_ADD_RANDOM))
 
 static inline int queue_is_locked(struct request_queue *q)
 {
@@ -592,38 +534,26 @@ enum {
        test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags)
 #define blk_queue_nonrot(q)    test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags)
 #define blk_queue_io_stat(q)   test_bit(QUEUE_FLAG_IO_STAT, &(q)->queue_flags)
+#define blk_queue_add_random(q)        test_bit(QUEUE_FLAG_ADD_RANDOM, &(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_queue_discard(q)   test_bit(QUEUE_FLAG_DISCARD, &(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)
-#define blk_special_request(rq)        ((rq)->cmd_type == REQ_TYPE_SPECIAL)
-#define blk_sense_request(rq)  ((rq)->cmd_type == REQ_TYPE_SENSE)
-
-#define blk_failfast_dev(rq)   ((rq)->cmd_flags & REQ_FAILFAST_DEV)
-#define blk_failfast_transport(rq) ((rq)->cmd_flags & REQ_FAILFAST_TRANSPORT)
-#define blk_failfast_driver(rq)        ((rq)->cmd_flags & REQ_FAILFAST_DRIVER)
-#define blk_noretry_request(rq)        (blk_failfast_dev(rq) ||        \
-                                blk_failfast_transport(rq) ||  \
-                                blk_failfast_driver(rq))
-#define blk_rq_started(rq)     ((rq)->cmd_flags & REQ_STARTED)
-#define blk_rq_io_stat(rq)     ((rq)->cmd_flags & REQ_IO_STAT)
-#define blk_rq_quiet(rq)       ((rq)->cmd_flags & REQ_QUIET)
-
-#define blk_account_rq(rq)     (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) 
-
-#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_noretry_request(rq) \
+       ((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
+                            REQ_FAILFAST_DRIVER))
+
+#define blk_account_rq(rq) \
+       (((rq)->cmd_flags & REQ_STARTED) && \
+        ((rq)->cmd_type == REQ_TYPE_FS || \
+         ((rq)->cmd_flags & REQ_DISCARD)))
+
 #define blk_pm_request(rq)     \
-       (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq))
+       ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
+        (rq)->cmd_type == REQ_TYPE_PM_RESUME)
 
 #define blk_rq_cpu_valid(rq)   ((rq)->cpu != -1)
-#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 blk_discard_rq(rq)     ((rq)->cmd_flags & REQ_DISCARD)
 #define blk_bidi_rq(rq)                ((rq)->next_rq != NULL)
 /* rq->queuelist of dequeued request must be list_empty() */
 #define blk_queued_rq(rq)      (!list_empty(&(rq)->queuelist))
@@ -637,7 +567,7 @@ enum {
  */
 static inline bool rw_is_sync(unsigned int rw_flags)
 {
-       return !(rw_flags & REQ_RW) || (rw_flags & REQ_RW_SYNC);
+       return !(rw_flags & REQ_WRITE) || (rw_flags & REQ_SYNC);
 }
 
 static inline bool rq_is_sync(struct request *rq)
@@ -645,9 +575,6 @@ static inline bool rq_is_sync(struct request *rq)
        return rw_is_sync(rq->cmd_flags);
 }
 
-#define rq_is_meta(rq)         ((rq)->cmd_flags & REQ_RW_META)
-#define rq_noidle(rq)          ((rq)->cmd_flags & REQ_NOIDLE)
-
 static inline int blk_queue_full(struct request_queue *q, int sync)
 {
        if (sync)
@@ -680,7 +607,8 @@ static inline void blk_clear_queue_full(struct request_queue *q, int sync)
        (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER)
 #define rq_mergeable(rq)       \
        (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
-        (blk_discard_rq(rq) || blk_fs_request((rq))))
+        (((rq)->cmd_flags & REQ_DISCARD) || \
+         (rq)->cmd_type == REQ_TYPE_FS))
 
 /*
  * q->prep_rq_fn return values
@@ -705,7 +633,7 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn;
 #define BLK_BOUNCE_HIGH                -1ULL
 #endif
 #define BLK_BOUNCE_ANY         (-1ULL)
-#define BLK_BOUNCE_ISA         (ISA_DMA_THRESHOLD)
+#define BLK_BOUNCE_ISA         (DMA_BIT_MASK(24))
 
 /*
  * default timeout for SG_IO if none specified
@@ -917,7 +845,12 @@ extern void blk_abort_queue(struct request_queue *);
  */
 extern struct request_queue *blk_init_queue_node(request_fn_proc *rfn,
                                        spinlock_t *lock, int node_id);
+extern struct request_queue *blk_init_allocated_queue_node(struct request_queue *,
+                                                          request_fn_proc *,
+                                                          spinlock_t *, int node_id);
 extern struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *);
+extern struct request_queue *blk_init_allocated_queue(struct request_queue *,
+                                                     request_fn_proc *, spinlock_t *);
 extern void blk_cleanup_queue(struct request_queue *);
 extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
 extern void blk_queue_bounce_limit(struct request_queue *, u64);
@@ -994,20 +927,25 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
                return NULL;
        return bqt->tag_index[tag];
 }
-
-extern int blkdev_issue_flush(struct block_device *, sector_t *);
-#define DISCARD_FL_WAIT                0x01    /* wait for completion */
-#define DISCARD_FL_BARRIER     0x02    /* issue DISCARD_BARRIER request */
-extern int blkdev_issue_discard(struct block_device *, sector_t sector,
-               sector_t nr_sects, gfp_t, int flags);
-
+enum{
+       BLKDEV_WAIT,    /* wait for completion */
+       BLKDEV_BARRIER, /*issue request with barrier */
+};
+#define BLKDEV_IFL_WAIT                (1 << BLKDEV_WAIT)
+#define BLKDEV_IFL_BARRIER     (1 << BLKDEV_BARRIER)
+extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *,
+                       unsigned long);
+extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
+               sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
+extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+                       sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
 static inline int sb_issue_discard(struct super_block *sb,
                                   sector_t block, sector_t nr_blocks)
 {
        block <<= (sb->s_blocksize_bits - 9);
        nr_blocks <<= (sb->s_blocksize_bits - 9);
        return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL,
-                                   DISCARD_FL_BARRIER);
+                                  BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER);
 }
 
 extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm);
@@ -1196,6 +1134,48 @@ static inline void put_dev_sector(Sector p)
 struct work_struct;
 int kblockd_schedule_work(struct request_queue *q, struct work_struct *work);
 
+#ifdef CONFIG_BLK_CGROUP
+/*
+ * This should not be using sched_clock(). A real patch is in progress
+ * to fix this up, until that is in place we need to disable preemption
+ * around sched_clock() in this function and set_io_start_time_ns().
+ */
+static inline void set_start_time_ns(struct request *req)
+{
+       preempt_disable();
+       req->start_time_ns = sched_clock();
+       preempt_enable();
+}
+
+static inline void set_io_start_time_ns(struct request *req)
+{
+       preempt_disable();
+       req->io_start_time_ns = sched_clock();
+       preempt_enable();
+}
+
+static inline uint64_t rq_start_time_ns(struct request *req)
+{
+        return req->start_time_ns;
+}
+
+static inline uint64_t rq_io_start_time_ns(struct request *req)
+{
+        return req->io_start_time_ns;
+}
+#else
+static inline void set_start_time_ns(struct request *req) {}
+static inline void set_io_start_time_ns(struct request *req) {}
+static inline uint64_t rq_start_time_ns(struct request *req)
+{
+       return 0;
+}
+static inline uint64_t rq_io_start_time_ns(struct request *req)
+{
+       return 0;
+}
+#endif
+
 #define MODULE_ALIAS_BLOCKDEV(major,minor) \
        MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
 #define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \
@@ -1283,10 +1263,11 @@ struct block_device_operations {
        int (*direct_access) (struct block_device *, sector_t,
                                                void **, unsigned long *);
        int (*media_changed) (struct gendisk *);
-       unsigned long long (*set_capacity) (struct gendisk *,
-                                               unsigned long long);
+       void (*unlock_native_capacity) (struct gendisk *);
        int (*revalidate_disk) (struct gendisk *);
        int (*getgeo)(struct block_device *, struct hd_geometry *);
+       /* this callback is with swap_lock and sometimes page table lock held */
+       void (*swap_slot_free_notify) (struct block_device *, unsigned long);
        struct module *owner;
 };