Commit 87374179 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarShaun Tancheff <shaun.tancheff@seagate.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent ef295ecf
...@@ -131,20 +131,37 @@ struct bio { ...@@ -131,20 +131,37 @@ struct bio {
/* /*
* Operations and flags common to the bio and request structures. * Operations and flags common to the bio and request structures.
* We use 8 bits for encoding the operation, and the remaining 24 for flags. * We use 8 bits for encoding the operation, and the remaining 24 for flags.
*
* The least significant bit of the operation number indicates the data
* transfer direction:
*
* - if the least significant bit is set transfers are TO the device
* - if the least significant bit is not set transfers are FROM the device
*
* If a operation does not transfer data the least significant bit has no
* meaning.
*/ */
#define REQ_OP_BITS 8 #define REQ_OP_BITS 8
#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1) #define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
#define REQ_FLAG_BITS 24 #define REQ_FLAG_BITS 24
enum req_opf { enum req_opf {
REQ_OP_READ, /* read sectors from the device */
REQ_OP_WRITE, REQ_OP_READ = 0,
REQ_OP_DISCARD, /* request to discard sectors */ /* write sectors to the device */
REQ_OP_SECURE_ERASE, /* request to securely erase sectors */ REQ_OP_WRITE = 1,
REQ_OP_WRITE_SAME, /* write same block many times */ /* flush the volatile write cache */
REQ_OP_FLUSH, /* request for cache flush */ REQ_OP_FLUSH = 2,
REQ_OP_ZONE_REPORT, /* Get zone information */ /* discard sectors */
REQ_OP_ZONE_RESET, /* Reset a zone write pointer */ REQ_OP_DISCARD = 3,
/* get zone information */
REQ_OP_ZONE_REPORT = 4,
/* securely erase sectors */
REQ_OP_SECURE_ERASE = 5,
/* seset a zone write pointer */
REQ_OP_ZONE_RESET = 6,
/* write the same sector many times */
REQ_OP_WRITE_SAME = 7,
REQ_OP_LAST, REQ_OP_LAST,
}; };
...@@ -194,6 +211,11 @@ enum req_flag_bits { ...@@ -194,6 +211,11 @@ enum req_flag_bits {
#define bio_set_op_attrs(bio, op, op_flags) \ #define bio_set_op_attrs(bio, op, op_flags) \
((bio)->bi_opf |= (op | op_flags)) ((bio)->bi_opf |= (op | op_flags))
static inline bool op_is_write(unsigned int op)
{
return (op & 1);
}
static inline bool op_is_sync(unsigned int op) static inline bool op_is_sync(unsigned int op)
{ {
return (op & REQ_OP_MASK) == REQ_OP_READ || (op & REQ_SYNC); return (op & REQ_OP_MASK) == REQ_OP_READ || (op & REQ_SYNC);
......
...@@ -2499,11 +2499,6 @@ extern void make_bad_inode(struct inode *); ...@@ -2499,11 +2499,6 @@ extern void make_bad_inode(struct inode *);
extern bool is_bad_inode(struct inode *); extern bool is_bad_inode(struct inode *);
#ifdef CONFIG_BLOCK #ifdef CONFIG_BLOCK
static inline bool op_is_write(unsigned int op)
{
return op == REQ_OP_READ ? false : true;
}
/* /*
* return data direction, READ or WRITE * return data direction, READ or WRITE
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment