Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / include / linux / blkdev.h
index 32176cc..1a23722 100644 (file)
@@ -257,7 +257,7 @@ struct queue_limits {
        unsigned char           misaligned;
        unsigned char           discard_misaligned;
        unsigned char           cluster;
-       signed char             discard_zeroes_data;
+       unsigned char           discard_zeroes_data;
 };
 
 struct request_queue
@@ -364,6 +364,8 @@ struct request_queue
         * for flush operations
         */
        unsigned int            flush_flags;
+       unsigned int            flush_not_queueable:1;
+       unsigned int            flush_queue_delayed:1;
        unsigned int            flush_pending_idx:1;
        unsigned int            flush_running_idx:1;
        unsigned long           flush_pending_since;
@@ -388,20 +390,19 @@ struct request_queue
 #define        QUEUE_FLAG_SYNCFULL     3       /* read queue has been filled */
 #define QUEUE_FLAG_ASYNCFULL   4       /* write queue has been filled */
 #define QUEUE_FLAG_DEAD                5       /* queue being torn down */
-#define QUEUE_FLAG_REENTER     6       /* Re-entrancy avoidance */
-#define QUEUE_FLAG_ELVSWITCH   7       /* don't use elevator, just do FIFO */
-#define QUEUE_FLAG_BIDI                8       /* queue supports bidi requests */
-#define QUEUE_FLAG_NOMERGES     9      /* disable merge attempts */
-#define QUEUE_FLAG_SAME_COMP   10      /* force complete on same CPU */
-#define QUEUE_FLAG_FAIL_IO     11      /* fake timeout */
-#define QUEUE_FLAG_STACKABLE   12      /* supports request stacking */
-#define QUEUE_FLAG_NONROT      13      /* non-rotational device (SSD) */
+#define QUEUE_FLAG_ELVSWITCH   6       /* don't use elevator, just do FIFO */
+#define QUEUE_FLAG_BIDI                7       /* queue supports bidi requests */
+#define QUEUE_FLAG_NOMERGES     8      /* disable merge attempts */
+#define QUEUE_FLAG_SAME_COMP   9       /* force complete on same CPU */
+#define QUEUE_FLAG_FAIL_IO     10      /* fake timeout */
+#define QUEUE_FLAG_STACKABLE   11      /* supports request stacking */
+#define QUEUE_FLAG_NONROT      12      /* non-rotational device (SSD) */
 #define QUEUE_FLAG_VIRT        QUEUE_FLAG_NONROT /* paravirt device */
-#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_SECDISCARD  19      /* supports SECDISCARD */
+#define QUEUE_FLAG_IO_STAT     13      /* do IO stats */
+#define QUEUE_FLAG_DISCARD     14      /* supports DISCARD */
+#define QUEUE_FLAG_NOXMERGES   15      /* No extended merges */
+#define QUEUE_FLAG_ADD_RANDOM  16      /* Contributes to random pool */
+#define QUEUE_FLAG_SECDISCARD  17      /* supports SECDISCARD */
 
 #define QUEUE_FLAG_DEFAULT     ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_STACKABLE)    |       \
@@ -697,8 +698,9 @@ extern void blk_start_queue(struct request_queue *q);
 extern void blk_stop_queue(struct request_queue *q);
 extern void blk_sync_queue(struct request_queue *q);
 extern void __blk_stop_queue(struct request_queue *q);
-extern void __blk_run_queue(struct request_queue *q, bool force_kblockd);
+extern void __blk_run_queue(struct request_queue *q);
 extern void blk_run_queue(struct request_queue *);
+extern void blk_run_queue_async(struct request_queue *q);
 extern int blk_rq_map_user(struct request_queue *, struct request *,
                           struct rq_map_data *, void __user *, unsigned long,
                           gfp_t);
@@ -843,6 +845,7 @@ extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
 extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
 extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
 extern void blk_queue_flush(struct request_queue *q, unsigned int flush);
+extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
 
 extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
@@ -857,26 +860,39 @@ extern void blk_put_queue(struct request_queue *);
 struct blk_plug {
        unsigned long magic;
        struct list_head list;
+       struct list_head cb_list;
        unsigned int should_sort;
 };
+struct blk_plug_cb {
+       struct list_head list;
+       void (*callback)(struct blk_plug_cb *);
+};
 
 extern void blk_start_plug(struct blk_plug *);
 extern void blk_finish_plug(struct blk_plug *);
-extern void __blk_flush_plug(struct task_struct *, struct blk_plug *);
+extern void blk_flush_plug_list(struct blk_plug *, bool);
 
 static inline void blk_flush_plug(struct task_struct *tsk)
 {
        struct blk_plug *plug = tsk->plug;
 
-       if (unlikely(plug))
-               __blk_flush_plug(tsk, plug);
+       if (plug)
+               blk_flush_plug_list(plug, false);
+}
+
+static inline void blk_schedule_flush_plug(struct task_struct *tsk)
+{
+       struct blk_plug *plug = tsk->plug;
+
+       if (plug)
+               blk_flush_plug_list(plug, true);
 }
 
 static inline bool blk_needs_flush_plug(struct task_struct *tsk)
 {
        struct blk_plug *plug = tsk->plug;
 
-       return plug && !list_empty(&plug->list);
+       return plug && (!list_empty(&plug->list) || !list_empty(&plug->cb_list));
 }
 
 /*
@@ -1053,13 +1069,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector
 {
        unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
 
+       if (!lim->max_discard_sectors)
+               return 0;
+
        return (lim->discard_granularity + lim->discard_alignment - alignment)
                & (lim->discard_granularity - 1);
 }
 
 static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
 {
-       if (q->limits.discard_zeroes_data == 1)
+       if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
                return 1;
 
        return 0;
@@ -1098,6 +1117,11 @@ static inline unsigned int block_size(struct block_device *bdev)
        return bdev->bd_block_size;
 }
 
+static inline bool queue_flush_queueable(struct request_queue *q)
+{
+       return !q->flush_not_queueable;
+}
+
 typedef struct {struct page *v;} Sector;
 
 unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *);
@@ -1258,8 +1282,8 @@ queue_max_integrity_segments(struct request_queue *q)
 #define blk_get_integrity(a)                   (0)
 #define blk_integrity_compare(a, b)            (0)
 #define blk_integrity_register(a, b)           (0)
-#define blk_integrity_unregister(a)            do { } while (0);
-#define blk_queue_max_integrity_segments(a, b) do { } while (0);
+#define blk_integrity_unregister(a)            do { } while (0)
+#define blk_queue_max_integrity_segments(a, b) do { } while (0)
 #define queue_max_integrity_segments(a)                (0)
 #define blk_integrity_merge_rq(a, b, c)                (0)
 #define blk_integrity_merge_bio(a, b, c)       (0)
@@ -1314,6 +1338,11 @@ static inline void blk_flush_plug(struct task_struct *task)
 {
 }
 
+static inline void blk_schedule_flush_plug(struct task_struct *task)
+{
+}
+
+
 static inline bool blk_needs_flush_plug(struct task_struct *tsk)
 {
        return false;