diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:55:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:55:15 -0400 |
commit | 355bbd8cb82e60a592f6cd86ce6dbe5677615cf4 (patch) | |
tree | 23678e50ad4687f1656edc972388ee8014e7b89d /include | |
parent | 39695224bd84dc4be29abad93a0ec232a16fc519 (diff) | |
parent | 746cd1e7e4a555ddaee53b19a46e05c9c61eaf09 (diff) |
Merge branch 'for-2.6.32' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.32' of git://git.kernel.dk/linux-2.6-block: (29 commits)
block: use blkdev_issue_discard in blk_ioctl_discard
Make DISCARD_BARRIER and DISCARD_NOBARRIER writes instead of reads
block: don't assume device has a request list backing in nr_requests store
block: Optimal I/O limit wrapper
cfq: choose a new next_req when a request is dispatched
Seperate read and write statistics of in_flight requests
aoe: end barrier bios with EOPNOTSUPP
block: trace bio queueing trial only when it occurs
block: enable rq CPU completion affinity by default
cfq: fix the log message after dispatched a request
block: use printk_once
cciss: memory leak in cciss_init_one()
splice: update mtime and atime on files
block: make blk_iopoll_prep_sched() follow normal 0/1 return convention
cfq-iosched: get rid of must_alloc flag
block: use interrupts disabled version of raise_softirq_irqoff()
block: fix comment in blk-iopoll.c
block: adjust default budget for blk-iopoll
block: fix long lines in block/blk-iopoll.c
block: add blk-iopoll, a NAPI like approach for block devices
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/bio.h | 69 | ||||
-rw-r--r-- | include/linux/blk-iopoll.h | 48 | ||||
-rw-r--r-- | include/linux/blkdev.h | 44 | ||||
-rw-r--r-- | include/linux/fs.h | 4 | ||||
-rw-r--r-- | include/linux/genhd.h | 21 | ||||
-rw-r--r-- | include/linux/interrupt.h | 1 |
6 files changed, 131 insertions, 56 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index 2892b710771c..5be93f18d842 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -142,56 +142,51 @@ struct bio { | |||
142 | * | 142 | * |
143 | * bit 0 -- data direction | 143 | * bit 0 -- data direction |
144 | * If not set, bio is a read from device. If set, it's a write to device. | 144 | * If not set, bio is a read from device. If set, it's a write to device. |
145 | * bit 1 -- rw-ahead when set | 145 | * bit 1 -- fail fast device errors |
146 | * bit 2 -- barrier | 146 | * bit 2 -- fail fast transport errors |
147 | * bit 3 -- fail fast driver errors | ||
148 | * bit 4 -- rw-ahead when set | ||
149 | * bit 5 -- barrier | ||
147 | * Insert a serialization point in the IO queue, forcing previously | 150 | * Insert a serialization point in the IO queue, forcing previously |
148 | * submitted IO to be completed before this one is issued. | 151 | * submitted IO to be completed before this one is issued. |
149 | * bit 3 -- synchronous I/O hint. | 152 | * bit 6 -- synchronous I/O hint. |
150 | * bit 4 -- Unplug the device immediately after submitting this bio. | 153 | * bit 7 -- Unplug the device immediately after submitting this bio. |
151 | * bit 5 -- metadata request | 154 | * bit 8 -- metadata request |
152 | * Used for tracing to differentiate metadata and data IO. May also | 155 | * Used for tracing to differentiate metadata and data IO. May also |
153 | * get some preferential treatment in the IO scheduler | 156 | * get some preferential treatment in the IO scheduler |
154 | * bit 6 -- discard sectors | 157 | * bit 9 -- discard sectors |
155 | * Informs the lower level device that this range of sectors is no longer | 158 | * Informs the lower level device that this range of sectors is no longer |
156 | * used by the file system and may thus be freed by the device. Used | 159 | * used by the file system and may thus be freed by the device. Used |
157 | * for flash based storage. | 160 | * for flash based storage. |
158 | * bit 7 -- fail fast device errors | ||
159 | * bit 8 -- fail fast transport errors | ||
160 | * bit 9 -- fail fast driver errors | ||
161 | * Don't want driver retries for any fast fail whatever the reason. | 161 | * Don't want driver retries for any fast fail whatever the reason. |
162 | * bit 10 -- Tell the IO scheduler not to wait for more requests after this | 162 | * bit 10 -- Tell the IO scheduler not to wait for more requests after this |
163 | one has been submitted, even if it is a SYNC request. | 163 | one has been submitted, even if it is a SYNC request. |
164 | */ | 164 | */ |
165 | #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ | 165 | enum bio_rw_flags { |
166 | #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ | 166 | BIO_RW, |
167 | #define BIO_RW_BARRIER 2 | 167 | BIO_RW_FAILFAST_DEV, |
168 | #define BIO_RW_SYNCIO 3 | 168 | BIO_RW_FAILFAST_TRANSPORT, |
169 | #define BIO_RW_UNPLUG 4 | 169 | BIO_RW_FAILFAST_DRIVER, |
170 | #define BIO_RW_META 5 | 170 | /* above flags must match REQ_* */ |
171 | #define BIO_RW_DISCARD 6 | 171 | BIO_RW_AHEAD, |
172 | #define BIO_RW_FAILFAST_DEV 7 | 172 | BIO_RW_BARRIER, |
173 | #define BIO_RW_FAILFAST_TRANSPORT 8 | 173 | BIO_RW_SYNCIO, |
174 | #define BIO_RW_FAILFAST_DRIVER 9 | 174 | BIO_RW_UNPLUG, |
175 | #define BIO_RW_NOIDLE 10 | 175 | BIO_RW_META, |
176 | 176 | BIO_RW_DISCARD, | |
177 | #define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag))) | 177 | BIO_RW_NOIDLE, |
178 | }; | ||
178 | 179 | ||
179 | /* | 180 | /* |
180 | * Old defines, these should eventually be replaced by direct usage of | 181 | * First four bits must match between bio->bi_rw and rq->cmd_flags, make |
181 | * bio_rw_flagged() | 182 | * that explicit here. |
182 | */ | 183 | */ |
183 | #define bio_barrier(bio) bio_rw_flagged(bio, BIO_RW_BARRIER) | 184 | #define BIO_RW_RQ_MASK 0xf |
184 | #define bio_sync(bio) bio_rw_flagged(bio, BIO_RW_SYNCIO) | 185 | |
185 | #define bio_unplug(bio) bio_rw_flagged(bio, BIO_RW_UNPLUG) | 186 | static inline bool bio_rw_flagged(struct bio *bio, enum bio_rw_flags flag) |
186 | #define bio_failfast_dev(bio) bio_rw_flagged(bio, BIO_RW_FAILFAST_DEV) | 187 | { |
187 | #define bio_failfast_transport(bio) \ | 188 | return (bio->bi_rw & (1 << flag)) != 0; |
188 | bio_rw_flagged(bio, BIO_RW_FAILFAST_TRANSPORT) | 189 | } |
189 | #define bio_failfast_driver(bio) \ | ||
190 | bio_rw_flagged(bio, BIO_RW_FAILFAST_DRIVER) | ||
191 | #define bio_rw_ahead(bio) bio_rw_flagged(bio, BIO_RW_AHEAD) | ||
192 | #define bio_rw_meta(bio) bio_rw_flagged(bio, BIO_RW_META) | ||
193 | #define bio_discard(bio) bio_rw_flagged(bio, BIO_RW_DISCARD) | ||
194 | #define bio_noidle(bio) bio_rw_flagged(bio, BIO_RW_NOIDLE) | ||
195 | 190 | ||
196 | /* | 191 | /* |
197 | * upper 16 bits of bi_rw define the io priority of this bio | 192 | * upper 16 bits of bi_rw define the io priority of this bio |
@@ -216,7 +211,7 @@ struct bio { | |||
216 | #define bio_offset(bio) bio_iovec((bio))->bv_offset | 211 | #define bio_offset(bio) bio_iovec((bio))->bv_offset |
217 | #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) | 212 | #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) |
218 | #define bio_sectors(bio) ((bio)->bi_size >> 9) | 213 | #define bio_sectors(bio) ((bio)->bi_size >> 9) |
219 | #define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio)) | 214 | #define bio_empty_barrier(bio) (bio_rw_flagged(bio, BIO_RW_BARRIER) && !bio_has_data(bio) && !bio_rw_flagged(bio, BIO_RW_DISCARD)) |
220 | 215 | ||
221 | static inline unsigned int bio_cur_bytes(struct bio *bio) | 216 | static inline unsigned int bio_cur_bytes(struct bio *bio) |
222 | { | 217 | { |
diff --git a/include/linux/blk-iopoll.h b/include/linux/blk-iopoll.h new file mode 100644 index 000000000000..308734d3d4a2 --- /dev/null +++ b/include/linux/blk-iopoll.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef BLK_IOPOLL_H | ||
2 | #define BLK_IOPOLL_H | ||
3 | |||
4 | struct blk_iopoll; | ||
5 | typedef int (blk_iopoll_fn)(struct blk_iopoll *, int); | ||
6 | |||
7 | struct blk_iopoll { | ||
8 | struct list_head list; | ||
9 | unsigned long state; | ||
10 | unsigned long data; | ||
11 | int weight; | ||
12 | int max; | ||
13 | blk_iopoll_fn *poll; | ||
14 | }; | ||
15 | |||
16 | enum { | ||
17 | IOPOLL_F_SCHED = 0, | ||
18 | IOPOLL_F_DISABLE = 1, | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * Returns 0 if we successfully set the IOPOLL_F_SCHED bit, indicating | ||
23 | * that we were the first to acquire this iop for scheduling. If this iop | ||
24 | * is currently disabled, return "failure". | ||
25 | */ | ||
26 | static inline int blk_iopoll_sched_prep(struct blk_iopoll *iop) | ||
27 | { | ||
28 | if (!test_bit(IOPOLL_F_DISABLE, &iop->state)) | ||
29 | return test_and_set_bit(IOPOLL_F_SCHED, &iop->state); | ||
30 | |||
31 | return 1; | ||
32 | } | ||
33 | |||
34 | static inline int blk_iopoll_disable_pending(struct blk_iopoll *iop) | ||
35 | { | ||
36 | return test_bit(IOPOLL_F_DISABLE, &iop->state); | ||
37 | } | ||
38 | |||
39 | extern void blk_iopoll_sched(struct blk_iopoll *); | ||
40 | extern void blk_iopoll_init(struct blk_iopoll *, int, blk_iopoll_fn *); | ||
41 | extern void blk_iopoll_complete(struct blk_iopoll *); | ||
42 | extern void __blk_iopoll_complete(struct blk_iopoll *); | ||
43 | extern void blk_iopoll_enable(struct blk_iopoll *); | ||
44 | extern void blk_iopoll_disable(struct blk_iopoll *); | ||
45 | |||
46 | extern int blk_iopoll_enabled; | ||
47 | |||
48 | #endif | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 69103e053c92..e23a86cae5ac 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -86,13 +86,14 @@ enum { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * request type modified bits. first two bits match BIO_RW* bits, important | 89 | * request type modified bits. first four bits match BIO_RW* bits, important |
90 | */ | 90 | */ |
91 | enum rq_flag_bits { | 91 | enum rq_flag_bits { |
92 | __REQ_RW, /* not set, read. set, write */ | 92 | __REQ_RW, /* not set, read. set, write */ |
93 | __REQ_FAILFAST_DEV, /* no driver retries of device errors */ | 93 | __REQ_FAILFAST_DEV, /* no driver retries of device errors */ |
94 | __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ | 94 | __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ |
95 | __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ | 95 | __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ |
96 | /* above flags must match BIO_RW_* */ | ||
96 | __REQ_DISCARD, /* request to discard sectors */ | 97 | __REQ_DISCARD, /* request to discard sectors */ |
97 | __REQ_SORTED, /* elevator knows about this request */ | 98 | __REQ_SORTED, /* elevator knows about this request */ |
98 | __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ | 99 | __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ |
@@ -114,6 +115,7 @@ enum rq_flag_bits { | |||
114 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ | 115 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ |
115 | __REQ_NOIDLE, /* Don't anticipate more IO after this one */ | 116 | __REQ_NOIDLE, /* Don't anticipate more IO after this one */ |
116 | __REQ_IO_STAT, /* account I/O stat */ | 117 | __REQ_IO_STAT, /* account I/O stat */ |
118 | __REQ_MIXED_MERGE, /* merge of different types, fail separately */ | ||
117 | __REQ_NR_BITS, /* stops here */ | 119 | __REQ_NR_BITS, /* stops here */ |
118 | }; | 120 | }; |
119 | 121 | ||
@@ -142,6 +144,10 @@ enum rq_flag_bits { | |||
142 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) | 144 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) |
143 | #define REQ_NOIDLE (1 << __REQ_NOIDLE) | 145 | #define REQ_NOIDLE (1 << __REQ_NOIDLE) |
144 | #define REQ_IO_STAT (1 << __REQ_IO_STAT) | 146 | #define REQ_IO_STAT (1 << __REQ_IO_STAT) |
147 | #define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE) | ||
148 | |||
149 | #define REQ_FAILFAST_MASK (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | \ | ||
150 | REQ_FAILFAST_DRIVER) | ||
145 | 151 | ||
146 | #define BLK_MAX_CDB 16 | 152 | #define BLK_MAX_CDB 16 |
147 | 153 | ||
@@ -453,10 +459,12 @@ struct request_queue | |||
453 | #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ | 459 | #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ |
454 | #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ | 460 | #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ |
455 | #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ | 461 | #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ |
462 | #define QUEUE_FLAG_CQ 16 /* hardware does queuing */ | ||
456 | 463 | ||
457 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 464 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
458 | (1 << QUEUE_FLAG_CLUSTER) | \ | 465 | (1 << QUEUE_FLAG_CLUSTER) | \ |
459 | (1 << QUEUE_FLAG_STACKABLE)) | 466 | (1 << QUEUE_FLAG_STACKABLE) | \ |
467 | (1 << QUEUE_FLAG_SAME_COMP)) | ||
460 | 468 | ||
461 | static inline int queue_is_locked(struct request_queue *q) | 469 | static inline int queue_is_locked(struct request_queue *q) |
462 | { | 470 | { |
@@ -575,6 +583,7 @@ enum { | |||
575 | 583 | ||
576 | #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) | 584 | #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) |
577 | #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) | 585 | #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) |
586 | #define blk_queue_queuing(q) test_bit(QUEUE_FLAG_CQ, &(q)->queue_flags) | ||
578 | #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) | 587 | #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) |
579 | #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) | 588 | #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) |
580 | #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) | 589 | #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) |
@@ -828,11 +837,13 @@ static inline void blk_run_address_space(struct address_space *mapping) | |||
828 | } | 837 | } |
829 | 838 | ||
830 | /* | 839 | /* |
831 | * blk_rq_pos() : the current sector | 840 | * blk_rq_pos() : the current sector |
832 | * blk_rq_bytes() : bytes left in the entire request | 841 | * blk_rq_bytes() : bytes left in the entire request |
833 | * blk_rq_cur_bytes() : bytes left in the current segment | 842 | * blk_rq_cur_bytes() : bytes left in the current segment |
834 | * blk_rq_sectors() : sectors left in the entire request | 843 | * blk_rq_err_bytes() : bytes left till the next error boundary |
835 | * blk_rq_cur_sectors() : sectors left in the current segment | 844 | * blk_rq_sectors() : sectors left in the entire request |
845 | * blk_rq_cur_sectors() : sectors left in the current segment | ||
846 | * blk_rq_err_sectors() : sectors left till the next error boundary | ||
836 | */ | 847 | */ |
837 | static inline sector_t blk_rq_pos(const struct request *rq) | 848 | static inline sector_t blk_rq_pos(const struct request *rq) |
838 | { | 849 | { |
@@ -849,6 +860,8 @@ static inline int blk_rq_cur_bytes(const struct request *rq) | |||
849 | return rq->bio ? bio_cur_bytes(rq->bio) : 0; | 860 | return rq->bio ? bio_cur_bytes(rq->bio) : 0; |
850 | } | 861 | } |
851 | 862 | ||
863 | extern unsigned int blk_rq_err_bytes(const struct request *rq); | ||
864 | |||
852 | static inline unsigned int blk_rq_sectors(const struct request *rq) | 865 | static inline unsigned int blk_rq_sectors(const struct request *rq) |
853 | { | 866 | { |
854 | return blk_rq_bytes(rq) >> 9; | 867 | return blk_rq_bytes(rq) >> 9; |
@@ -859,6 +872,11 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq) | |||
859 | return blk_rq_cur_bytes(rq) >> 9; | 872 | return blk_rq_cur_bytes(rq) >> 9; |
860 | } | 873 | } |
861 | 874 | ||
875 | static inline unsigned int blk_rq_err_sectors(const struct request *rq) | ||
876 | { | ||
877 | return blk_rq_err_bytes(rq) >> 9; | ||
878 | } | ||
879 | |||
862 | /* | 880 | /* |
863 | * Request issue related functions. | 881 | * Request issue related functions. |
864 | */ | 882 | */ |
@@ -885,10 +903,12 @@ extern bool blk_end_request(struct request *rq, int error, | |||
885 | unsigned int nr_bytes); | 903 | unsigned int nr_bytes); |
886 | extern void blk_end_request_all(struct request *rq, int error); | 904 | extern void blk_end_request_all(struct request *rq, int error); |
887 | extern bool blk_end_request_cur(struct request *rq, int error); | 905 | extern bool blk_end_request_cur(struct request *rq, int error); |
906 | extern bool blk_end_request_err(struct request *rq, int error); | ||
888 | extern bool __blk_end_request(struct request *rq, int error, | 907 | extern bool __blk_end_request(struct request *rq, int error, |
889 | unsigned int nr_bytes); | 908 | unsigned int nr_bytes); |
890 | extern void __blk_end_request_all(struct request *rq, int error); | 909 | extern void __blk_end_request_all(struct request *rq, int error); |
891 | extern bool __blk_end_request_cur(struct request *rq, int error); | 910 | extern bool __blk_end_request_cur(struct request *rq, int error); |
911 | extern bool __blk_end_request_err(struct request *rq, int error); | ||
892 | 912 | ||
893 | extern void blk_complete_request(struct request *); | 913 | extern void blk_complete_request(struct request *); |
894 | extern void __blk_complete_request(struct request *); | 914 | extern void __blk_complete_request(struct request *); |
@@ -915,6 +935,7 @@ extern void blk_queue_alignment_offset(struct request_queue *q, | |||
915 | unsigned int alignment); | 935 | unsigned int alignment); |
916 | extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min); | 936 | extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min); |
917 | extern void blk_queue_io_min(struct request_queue *q, unsigned int min); | 937 | extern void blk_queue_io_min(struct request_queue *q, unsigned int min); |
938 | extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt); | ||
918 | extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); | 939 | extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); |
919 | extern void blk_set_default_limits(struct queue_limits *lim); | 940 | extern void blk_set_default_limits(struct queue_limits *lim); |
920 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | 941 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, |
@@ -977,15 +998,18 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, | |||
977 | } | 998 | } |
978 | 999 | ||
979 | extern int blkdev_issue_flush(struct block_device *, sector_t *); | 1000 | extern int blkdev_issue_flush(struct block_device *, sector_t *); |
980 | extern int blkdev_issue_discard(struct block_device *, | 1001 | #define DISCARD_FL_WAIT 0x01 /* wait for completion */ |
981 | sector_t sector, sector_t nr_sects, gfp_t); | 1002 | #define DISCARD_FL_BARRIER 0x02 /* issue DISCARD_BARRIER request */ |
1003 | extern int blkdev_issue_discard(struct block_device *, sector_t sector, | ||
1004 | sector_t nr_sects, gfp_t, int flags); | ||
982 | 1005 | ||
983 | static inline int sb_issue_discard(struct super_block *sb, | 1006 | static inline int sb_issue_discard(struct super_block *sb, |
984 | sector_t block, sector_t nr_blocks) | 1007 | sector_t block, sector_t nr_blocks) |
985 | { | 1008 | { |
986 | block <<= (sb->s_blocksize_bits - 9); | 1009 | block <<= (sb->s_blocksize_bits - 9); |
987 | nr_blocks <<= (sb->s_blocksize_bits - 9); | 1010 | nr_blocks <<= (sb->s_blocksize_bits - 9); |
988 | return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL); | 1011 | return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL, |
1012 | DISCARD_FL_BARRIER); | ||
989 | } | 1013 | } |
990 | 1014 | ||
991 | extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); | 1015 | extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 37f53216998a..b21cf6b9c80b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -161,8 +161,8 @@ struct inodes_stat_t { | |||
161 | * These aren't really reads or writes, they pass down information about | 161 | * These aren't really reads or writes, they pass down information about |
162 | * parts of device that are now unused by the file system. | 162 | * parts of device that are now unused by the file system. |
163 | */ | 163 | */ |
164 | #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) | 164 | #define DISCARD_NOBARRIER (WRITE | (1 << BIO_RW_DISCARD)) |
165 | #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) | 165 | #define DISCARD_BARRIER (DISCARD_NOBARRIER | (1 << BIO_RW_BARRIER)) |
166 | 166 | ||
167 | #define SEL_IN 1 | 167 | #define SEL_IN 1 |
168 | #define SEL_OUT 2 | 168 | #define SEL_OUT 2 |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 45fc320a53c6..44263cb27121 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -98,7 +98,7 @@ struct hd_struct { | |||
98 | int make_it_fail; | 98 | int make_it_fail; |
99 | #endif | 99 | #endif |
100 | unsigned long stamp; | 100 | unsigned long stamp; |
101 | int in_flight; | 101 | int in_flight[2]; |
102 | #ifdef CONFIG_SMP | 102 | #ifdef CONFIG_SMP |
103 | struct disk_stats *dkstats; | 103 | struct disk_stats *dkstats; |
104 | #else | 104 | #else |
@@ -322,18 +322,23 @@ static inline void free_part_stats(struct hd_struct *part) | |||
322 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | 322 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ |
323 | part_stat_add(cpu, gendiskp, field, -subnd) | 323 | part_stat_add(cpu, gendiskp, field, -subnd) |
324 | 324 | ||
325 | static inline void part_inc_in_flight(struct hd_struct *part) | 325 | static inline void part_inc_in_flight(struct hd_struct *part, int rw) |
326 | { | 326 | { |
327 | part->in_flight++; | 327 | part->in_flight[rw]++; |
328 | if (part->partno) | 328 | if (part->partno) |
329 | part_to_disk(part)->part0.in_flight++; | 329 | part_to_disk(part)->part0.in_flight[rw]++; |
330 | } | 330 | } |
331 | 331 | ||
332 | static inline void part_dec_in_flight(struct hd_struct *part) | 332 | static inline void part_dec_in_flight(struct hd_struct *part, int rw) |
333 | { | 333 | { |
334 | part->in_flight--; | 334 | part->in_flight[rw]--; |
335 | if (part->partno) | 335 | if (part->partno) |
336 | part_to_disk(part)->part0.in_flight--; | 336 | part_to_disk(part)->part0.in_flight[rw]--; |
337 | } | ||
338 | |||
339 | static inline int part_in_flight(struct hd_struct *part) | ||
340 | { | ||
341 | return part->in_flight[0] + part->in_flight[1]; | ||
337 | } | 342 | } |
338 | 343 | ||
339 | /* block/blk-core.c */ | 344 | /* block/blk-core.c */ |
@@ -546,6 +551,8 @@ extern ssize_t part_size_show(struct device *dev, | |||
546 | struct device_attribute *attr, char *buf); | 551 | struct device_attribute *attr, char *buf); |
547 | extern ssize_t part_stat_show(struct device *dev, | 552 | extern ssize_t part_stat_show(struct device *dev, |
548 | struct device_attribute *attr, char *buf); | 553 | struct device_attribute *attr, char *buf); |
554 | extern ssize_t part_inflight_show(struct device *dev, | ||
555 | struct device_attribute *attr, char *buf); | ||
549 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 556 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
550 | extern ssize_t part_fail_show(struct device *dev, | 557 | extern ssize_t part_fail_show(struct device *dev, |
551 | struct device_attribute *attr, char *buf); | 558 | struct device_attribute *attr, char *buf); |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 1ac57e522a1f..8e9e151f811e 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -348,6 +348,7 @@ enum | |||
348 | NET_TX_SOFTIRQ, | 348 | NET_TX_SOFTIRQ, |
349 | NET_RX_SOFTIRQ, | 349 | NET_RX_SOFTIRQ, |
350 | BLOCK_SOFTIRQ, | 350 | BLOCK_SOFTIRQ, |
351 | BLOCK_IOPOLL_SOFTIRQ, | ||
351 | TASKLET_SOFTIRQ, | 352 | TASKLET_SOFTIRQ, |
352 | SCHED_SOFTIRQ, | 353 | SCHED_SOFTIRQ, |
353 | HRTIMER_SOFTIRQ, | 354 | HRTIMER_SOFTIRQ, |