aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-10-20 09:12:15 -0400
committerJens Axboe <axboe@fb.com>2016-10-28 10:48:54 -0400
commit87374179c535a98337569904727aa02f960fe79e (patch)
tree6c71566fb8bda79fbf683e60e207739cbae50bad
parentef295ecf090d3e86e5b742fc6ab34f1122a43773 (diff)
block: add a proper block layer data direction encoding
Currently the block layer op_is_write, bio_data_dir and rq_data_dir helper treat every operation that is not a READ as a data out operation. This worked surprisingly long, but the new REQ_OP_ZONE_REPORT operation actually adds a second operation that reads data from the device. Surprisingly nothing critical relied on this direction, but this might be a good opportunity to properly fix this issue up. We take a little inspiration and use the least significant bit of the operation number to encode the data direction, which just requires us to renumber the operations to fix this scheme. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Shaun Tancheff <shaun.tancheff@seagate.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--include/linux/blk_types.h38
-rw-r--r--include/linux/fs.h5
2 files changed, 30 insertions, 13 deletions
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index dca972d67548..3fa62cabe8d2 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -131,20 +131,37 @@ struct bio {
131/* 131/*
132 * Operations and flags common to the bio and request structures. 132 * Operations and flags common to the bio and request structures.
133 * We use 8 bits for encoding the operation, and the remaining 24 for flags. 133 * We use 8 bits for encoding the operation, and the remaining 24 for flags.
134 *
135 * The least significant bit of the operation number indicates the data
136 * transfer direction:
137 *
138 * - if the least significant bit is set transfers are TO the device
139 * - if the least significant bit is not set transfers are FROM the device
140 *
141 * If a operation does not transfer data the least significant bit has no
142 * meaning.
134 */ 143 */
135#define REQ_OP_BITS 8 144#define REQ_OP_BITS 8
136#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1) 145#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
137#define REQ_FLAG_BITS 24 146#define REQ_FLAG_BITS 24
138 147
139enum req_opf { 148enum req_opf {
140 REQ_OP_READ, 149 /* read sectors from the device */
141 REQ_OP_WRITE, 150 REQ_OP_READ = 0,
142 REQ_OP_DISCARD, /* request to discard sectors */ 151 /* write sectors to the device */
143 REQ_OP_SECURE_ERASE, /* request to securely erase sectors */ 152 REQ_OP_WRITE = 1,
144 REQ_OP_WRITE_SAME, /* write same block many times */ 153 /* flush the volatile write cache */
145 REQ_OP_FLUSH, /* request for cache flush */ 154 REQ_OP_FLUSH = 2,
146 REQ_OP_ZONE_REPORT, /* Get zone information */ 155 /* discard sectors */
147 REQ_OP_ZONE_RESET, /* Reset a zone write pointer */ 156 REQ_OP_DISCARD = 3,
157 /* get zone information */
158 REQ_OP_ZONE_REPORT = 4,
159 /* securely erase sectors */
160 REQ_OP_SECURE_ERASE = 5,
161 /* seset a zone write pointer */
162 REQ_OP_ZONE_RESET = 6,
163 /* write the same sector many times */
164 REQ_OP_WRITE_SAME = 7,
148 165
149 REQ_OP_LAST, 166 REQ_OP_LAST,
150}; 167};
@@ -194,6 +211,11 @@ enum req_flag_bits {
194#define bio_set_op_attrs(bio, op, op_flags) \ 211#define bio_set_op_attrs(bio, op, op_flags) \
195 ((bio)->bi_opf |= (op | op_flags)) 212 ((bio)->bi_opf |= (op | op_flags))
196 213
214static inline bool op_is_write(unsigned int op)
215{
216 return (op & 1);
217}
218
197static inline bool op_is_sync(unsigned int op) 219static inline bool op_is_sync(unsigned int op)
198{ 220{
199 return (op & REQ_OP_MASK) == REQ_OP_READ || (op & REQ_SYNC); 221 return (op & REQ_OP_MASK) == REQ_OP_READ || (op & REQ_SYNC);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 16d2b6e874d6..e3e878f12b25 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2499,11 +2499,6 @@ extern void make_bad_inode(struct inode *);
2499extern bool is_bad_inode(struct inode *); 2499extern bool is_bad_inode(struct inode *);
2500 2500
2501#ifdef CONFIG_BLOCK 2501#ifdef CONFIG_BLOCK
2502static inline bool op_is_write(unsigned int op)
2503{
2504 return op == REQ_OP_READ ? false : true;
2505}
2506
2507/* 2502/*
2508 * return data direction, READ or WRITE 2503 * return data direction, READ or WRITE
2509 */ 2504 */