aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-05-07 09:24:41 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-05-11 03:50:54 -0400
commit2e46e8b27aa57c6bd34b3102b40ee4d0144b4fab (patch)
tree134f560f66c2af277f0f25e5b85f6c1acaddfc06 /include/linux
parent9780e2dd8254351f6cbe11304849126b51dbd561 (diff)
block: drop request->hard_* and *nr_sectors
struct request has had a few different ways to represent some properties of a request. ->hard_* represent block layer's view of the request progress (completion cursor) and the ones without the prefix are supposed to represent the issue cursor and allowed to be updated as necessary by the low level drivers. The thing is that as block layer supports partial completion, the two cursors really aren't necessary and only cause confusion. In addition, manual management of request detail from low level drivers is cumbersome and error-prone at the very least. Another interesting duplicate fields are rq->[hard_]nr_sectors and rq->{hard_cur|current}_nr_sectors against rq->data_len and rq->bio->bi_size. This is more convoluted than the hard_ case. rq->[hard_]nr_sectors are initialized for requests with bio but blk_rq_bytes() uses it only for !pc requests. rq->data_len is initialized for all request but blk_rq_bytes() uses it only for pc requests. This causes good amount of confusion throughout block layer and its drivers and determining the request length has been a bit of black magic which may or may not work depending on circumstances and what the specific LLD is actually doing. rq->{hard_cur|current}_nr_sectors represent the number of sectors in the contiguous data area at the front. This is mainly used by drivers which transfers data by walking request segment-by-segment. This value always equals rq->bio->bi_size >> 9. However, data length for pc requests may not be multiple of 512 bytes and using this field becomes a bit confusing. In general, having multiple fields to represent the same property leads only to confusion and subtle bugs. With recent block low level driver cleanups, no driver is accessing or manipulating these duplicate fields directly. Drop all the duplicates. Now rq->sector means the current sector, rq->data_len the current total length and rq->bio->bi_size the current segment length. Everything else is defined in terms of these three and available only through accessors. * blk_recalc_rq_sectors() is collapsed into blk_update_request() and now handles pc and fs requests equally other than rq->sector update. This means that now pc requests can use partial completion too (no in-kernel user yet tho). * bio_cur_sectors() is replaced with bio_cur_bytes() as block layer now uses byte count as the primary data length. * blk_rq_pos() is now guranteed to be always correct. In-block users converted. * blk_rq_bytes() is now guaranteed to be always valid as is blk_rq_sectors(). In-block users converted. * blk_rq_sectors() is now guaranteed to equal blk_rq_bytes() >> 9. More convenient one is used. * blk_rq_bytes() and blk_rq_cur_bytes() are now inlined and take const pointer to request. [ Impact: API cleanup, single way to represent one property of a request ] Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bio.h6
-rw-r--r--include/linux/blkdev.h37
-rw-r--r--include/linux/elevator.h2
3 files changed, 20 insertions, 25 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h
index f37ca8c726ba..d30ec6f30dd7 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -218,12 +218,12 @@ struct bio {
218#define bio_sectors(bio) ((bio)->bi_size >> 9) 218#define bio_sectors(bio) ((bio)->bi_size >> 9)
219#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio)) 219#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio))
220 220
221static inline unsigned int bio_cur_sectors(struct bio *bio) 221static inline unsigned int bio_cur_bytes(struct bio *bio)
222{ 222{
223 if (bio->bi_vcnt) 223 if (bio->bi_vcnt)
224 return bio_iovec(bio)->bv_len >> 9; 224 return bio_iovec(bio)->bv_len;
225 else /* dataless requests such as discard */ 225 else /* dataless requests such as discard */
226 return bio->bi_size >> 9; 226 return bio->bi_size;
227} 227}
228 228
229static inline void *bio_data(struct bio *bio) 229static inline void *bio_data(struct bio *bio)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4e5f85598728..ce2bf5efa9ba 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -166,19 +166,8 @@ struct request {
166 enum rq_cmd_type_bits cmd_type; 166 enum rq_cmd_type_bits cmd_type;
167 unsigned long atomic_flags; 167 unsigned long atomic_flags;
168 168
169 /* Maintain bio traversal state for part by part I/O submission. 169 sector_t sector; /* sector cursor */
170 * hard_* are block layer internals, no driver should touch them! 170 unsigned int data_len; /* total data len, don't access directly */
171 */
172
173 sector_t sector; /* next sector to submit */
174 sector_t hard_sector; /* next sector to complete */
175 unsigned long nr_sectors; /* no. of sectors left to submit */
176 unsigned long hard_nr_sectors; /* no. of sectors left to complete */
177 /* no. of sectors left to submit in the current segment */
178 unsigned int current_nr_sectors;
179
180 /* no. of sectors left to complete in the current segment */
181 unsigned int hard_cur_sectors;
182 171
183 struct bio *bio; 172 struct bio *bio;
184 struct bio *biotail; 173 struct bio *biotail;
@@ -226,7 +215,6 @@ struct request {
226 unsigned char __cmd[BLK_MAX_CDB]; 215 unsigned char __cmd[BLK_MAX_CDB];
227 unsigned char *cmd; 216 unsigned char *cmd;
228 217
229 unsigned int data_len;
230 unsigned int extra_len; /* length of alignment and padding */ 218 unsigned int extra_len; /* length of alignment and padding */
231 unsigned int sense_len; 219 unsigned int sense_len;
232 unsigned int resid_len; /* residual count */ 220 unsigned int resid_len; /* residual count */
@@ -840,20 +828,27 @@ extern void blkdev_dequeue_request(struct request *req);
840 */ 828 */
841static inline sector_t blk_rq_pos(const struct request *rq) 829static inline sector_t blk_rq_pos(const struct request *rq)
842{ 830{
843 return rq->hard_sector; 831 return rq->sector;
832}
833
834static inline unsigned int blk_rq_bytes(const struct request *rq)
835{
836 return rq->data_len;
844} 837}
845 838
846extern unsigned int blk_rq_bytes(struct request *rq); 839static inline int blk_rq_cur_bytes(const struct request *rq)
847extern unsigned int blk_rq_cur_bytes(struct request *rq); 840{
841 return rq->bio ? bio_cur_bytes(rq->bio) : 0;
842}
848 843
849static inline unsigned int blk_rq_sectors(const struct request *rq) 844static inline unsigned int blk_rq_sectors(const struct request *rq)
850{ 845{
851 return rq->hard_nr_sectors; 846 return blk_rq_bytes(rq) >> 9;
852} 847}
853 848
854static inline unsigned int blk_rq_cur_sectors(const struct request *rq) 849static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
855{ 850{
856 return rq->hard_cur_sectors; 851 return blk_rq_cur_bytes(rq) >> 9;
857} 852}
858 853
859/* 854/*
@@ -928,7 +923,7 @@ static inline void blk_end_request_all(struct request *rq, int error)
928 */ 923 */
929static inline bool blk_end_request_cur(struct request *rq, int error) 924static inline bool blk_end_request_cur(struct request *rq, int error)
930{ 925{
931 return blk_end_request(rq, error, rq->hard_cur_sectors << 9); 926 return blk_end_request(rq, error, blk_rq_cur_bytes(rq));
932} 927}
933 928
934/** 929/**
@@ -981,7 +976,7 @@ static inline void __blk_end_request_all(struct request *rq, int error)
981 */ 976 */
982static inline bool __blk_end_request_cur(struct request *rq, int error) 977static inline bool __blk_end_request_cur(struct request *rq, int error)
983{ 978{
984 return __blk_end_request(rq, error, rq->hard_cur_sectors << 9); 979 return __blk_end_request(rq, error, blk_rq_cur_bytes(rq));
985} 980}
986 981
987extern void blk_complete_request(struct request *); 982extern void blk_complete_request(struct request *);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index c59b769f62b0..4e462878c9ca 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -171,7 +171,7 @@ enum {
171 ELV_MQUEUE_MUST, 171 ELV_MQUEUE_MUST,
172}; 172};
173 173
174#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors) 174#define rq_end_sector(rq) (blk_rq_pos(rq) + blk_rq_sectors(rq))
175#define rb_entry_rq(node) rb_entry((node), struct request, rb_node) 175#define rb_entry_rq(node) rb_entry((node), struct request, rb_node)
176 176
177/* 177/*