struct block_device *bi_bdev;
unsigned int bi_flags; /* status, command, etc */
int bi_error;
- unsigned int bi_rw; /* READ/WRITE */
+ unsigned int bi_rw; /* bottom bits req flags,
+ * top bits REQ_OP
+ */
unsigned short bi_ioprio;
struct bvec_iter bi_iter;
struct bio_vec bi_inline_vecs[0];
};
+#define BIO_OP_SHIFT (8 * sizeof(unsigned int) - REQ_OP_BITS)
+#define bio_op(bio) ((bio)->bi_rw >> BIO_OP_SHIFT)
+
+#define bio_set_op_attrs(bio, op, op_flags) do { \
+ WARN_ON(op >= (1 << REQ_OP_BITS)); \
+ (bio)->bi_rw &= ((1 << BIO_OP_SHIFT) - 1); \
+ (bio)->bi_rw |= ((unsigned int) (op) << BIO_OP_SHIFT); \
+ (bio)->bi_rw |= op_flags; \
+} while (0)
+
#define BIO_RESET_BYTES offsetof(struct bio, bi_max_vecs)
/*
*/
enum rq_flag_bits {
/* common flags */
- __REQ_WRITE, /* not set, read. set, write */
__REQ_FAILFAST_DEV, /* no driver retries of device errors */
__REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
__REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */
__REQ_SYNC, /* request is sync (sync write or read) */
__REQ_META, /* metadata io request */
__REQ_PRIO, /* boost priority in cfq */
- __REQ_DISCARD, /* request to discard sectors */
- __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
- __REQ_WRITE_SAME, /* write same block many times */
+ __REQ_SECURE, /* secure discard (used with REQ_OP_DISCARD) */
__REQ_NOIDLE, /* don't anticipate more IO after this one */
__REQ_INTEGRITY, /* I/O includes block integrity payload */
__REQ_NR_BITS, /* stops here */
};
-#define REQ_WRITE (1ULL << __REQ_WRITE)
#define REQ_FAILFAST_DEV (1ULL << __REQ_FAILFAST_DEV)
#define REQ_FAILFAST_TRANSPORT (1ULL << __REQ_FAILFAST_TRANSPORT)
#define REQ_FAILFAST_DRIVER (1ULL << __REQ_FAILFAST_DRIVER)
#define REQ_SYNC (1ULL << __REQ_SYNC)
#define REQ_META (1ULL << __REQ_META)
#define REQ_PRIO (1ULL << __REQ_PRIO)
-#define REQ_DISCARD (1ULL << __REQ_DISCARD)
-#define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME)
#define REQ_NOIDLE (1ULL << __REQ_NOIDLE)
#define REQ_INTEGRITY (1ULL << __REQ_INTEGRITY)
#define REQ_FAILFAST_MASK \
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
#define REQ_COMMON_MASK \
- (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
- REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
- REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE)
+ (REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | REQ_NOIDLE | \
+ REQ_FLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE)
#define REQ_CLONE_MASK REQ_COMMON_MASK
-#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME)
-
/* This mask is used for both bio and request merge checking */
#define REQ_NOMERGE_FLAGS \
(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ)
enum req_op {
REQ_OP_READ,
- REQ_OP_WRITE = REQ_WRITE,
- REQ_OP_DISCARD = REQ_DISCARD,
- REQ_OP_WRITE_SAME = REQ_WRITE_SAME,
+ REQ_OP_WRITE,
+ REQ_OP_DISCARD, /* request to discard sectors */
+ REQ_OP_WRITE_SAME, /* write same block many times */
};
-/*
- * tmp cpmpat. Users used to set the write bit for all non reads, but
- * we will be dropping the bitmap use for ops. Support both until
- * the end of the patchset.
- */
-static inline int op_from_rq_bits(u64 flags)
-{
- if (flags & REQ_OP_DISCARD)
- return REQ_OP_DISCARD;
- else if (flags & REQ_OP_WRITE_SAME)
- return REQ_OP_WRITE_SAME;
- else if (flags & REQ_OP_WRITE)
- return REQ_OP_WRITE;
- else
- return REQ_OP_READ;
-}
+#define REQ_OP_BITS 2
typedef unsigned int blk_qc_t;
#define BLK_QC_T_NONE -1U
struct request *next_rq;
};
-#define req_op(req) (op_from_rq_bits((req)->cmd_flags))
-#define req_set_op(req, op) ((req)->cmd_flags |= op)
+#define REQ_OP_SHIFT (8 * sizeof(u64) - REQ_OP_BITS)
+#define req_op(req) ((req)->cmd_flags >> REQ_OP_SHIFT)
+
+#define req_set_op(req, op) do { \
+ WARN_ON(op >= (1 << REQ_OP_BITS)); \
+ (req)->cmd_flags &= ((1ULL << REQ_OP_SHIFT) - 1); \
+ (req)->cmd_flags |= ((u64) (op) << REQ_OP_SHIFT); \
+} while (0)
+
#define req_set_op_attrs(req, op, flags) do { \
req_set_op(req, op); \
(req)->cmd_flags |= flags; \
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
-#define rq_data_dir(rq) \
- (op_is_write(op_from_rq_bits(rq->cmd_flags)) ? WRITE : READ)
+#define rq_data_dir(rq) (op_is_write(req_op(rq)) ? WRITE : READ)
/*
* Driver can handle struct request, if it either has an old style
#define CHECK_IOVEC_ONLY -1
/*
- * The below are the various read and write types that we support. Some of
+ * The below are the various read and write flags that we support. Some of
* them include behavioral modifiers that send information down to the
- * block layer and IO scheduler. Terminology:
+ * block layer and IO scheduler. They should be used along with a req_op.
+ * Terminology:
*
* The block layer uses device plugging to defer IO a little bit, in
* the hope that we will see more IO very shortly. This increases
* non-volatile media on completion.
*
*/
-#define RW_MASK REQ_WRITE
+#define RW_MASK REQ_OP_WRITE
#define RWA_MASK REQ_RAHEAD
-#define READ 0
+#define READ REQ_OP_READ
#define WRITE RW_MASK
#define READA RWA_MASK
-#define READ_SYNC (READ | REQ_SYNC)
-#define WRITE_SYNC (WRITE | REQ_SYNC | REQ_NOIDLE)
-#define WRITE_ODIRECT (WRITE | REQ_SYNC)
-#define WRITE_FLUSH (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH)
-#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA)
-#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
+#define READ_SYNC REQ_SYNC
+#define WRITE_SYNC (REQ_SYNC | REQ_NOIDLE)
+#define WRITE_ODIRECT REQ_SYNC
+#define WRITE_FLUSH (REQ_SYNC | REQ_NOIDLE | REQ_FLUSH)
+#define WRITE_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FUA)
+#define WRITE_FLUSH_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
/*
* Attribute flags. These should be or-ed together to figure out what
extern bool is_bad_inode(struct inode *);
#ifdef CONFIG_BLOCK
-/*
- * tmp cpmpat. Users used to set the write bit for all non reads, but
- * we will be dropping the bitmap use for ops. Support both until
- * the end of the patchset.
- */
-static inline bool op_is_write(unsigned long flags)
+static inline bool op_is_write(unsigned int op)
{
- if (flags & (REQ_OP_WRITE | REQ_OP_WRITE_SAME | REQ_OP_DISCARD))
- return true;
- else
- return false;
+ return op == REQ_OP_READ ? false : true;
}
/*
*/
static inline int bio_rw(struct bio *bio)
{
- if (op_is_write(op_from_rq_bits(bio->bi_rw)))
+ if (op_is_write(bio_op(bio)))
return WRITE;
return bio->bi_rw & RWA_MASK;
*/
static inline int bio_data_dir(struct bio *bio)
{
- return op_is_write(op_from_rq_bits(bio->bi_rw)) ? WRITE : READ;
+ return op_is_write(bio_op(bio)) ? WRITE : READ;
}
extern void check_disk_size_change(struct gendisk *disk,