Skip to content

Commit

Permalink
block: Introduce the REQ_FLUSH_IS_BARRIER flag
Browse files Browse the repository at this point in the history
A new feature in the UFS 4.0 specification is support for the BARRIER
command. This command can be used to enforce the command order without
enforcing durability. This is useful to implement transactions if it is
acceptable that some transactions are rolled back if a power failure
occurs. The intended use of this feature is as follows:
- The host waits for all pending write operations to complete.
- A barrier operation is submitted (REQ_OP_FLUSH | REQ_FLUSH_IS_BARRIER).
- After the barrier operation completes, more write operations are
  submitted.

The advantages of this approach compared to the previous block layer
barrier implementation are as follows:
- The new approach is compatible with reordering in the block layer.
- The new approach is compatible with blk-mq.

See also "block: replace barrier with sequenced flush", LWN.net, 2010
(https://lwn.net/Articles/399715/).

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
  • Loading branch information
bvanassche committed Oct 12, 2022
1 parent 6f1111b commit b2789e4
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
2 changes: 1 addition & 1 deletion block/blk-flush.c
Expand Up @@ -340,7 +340,7 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
flush_rq->internal_tag = first_rq->internal_tag;

flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
flush_rq->cmd_flags |= (flags & REQ_DRV) | (flags & REQ_FAILFAST_MASK);
flush_rq->cmd_flags |= flags & REQ_FLUSH_FLAGS;
flush_rq->rq_flags |= RQF_FLUSH_SEQ;
flush_rq->end_io = flush_end_io;
/*
Expand Down
7 changes: 7 additions & 0 deletions include/linux/blk_types.h
Expand Up @@ -399,6 +399,7 @@ enum req_flag_bits {
__REQ_NOMERGE, /* don't touch this for merging */
__REQ_IDLE, /* anticipate more IO after this one */
__REQ_INTEGRITY, /* I/O includes block integrity payload */
__REQ_FLUSH_IS_BARRIER, /* treat REQ_OP_FLUSH as a barrier */
__REQ_FUA, /* forced unit access */
__REQ_PREFLUSH, /* request for cache flush */
__REQ_RAHEAD, /* read ahead, can fail anytime */
Expand Down Expand Up @@ -438,6 +439,8 @@ enum req_flag_bits {
#define REQ_NOMERGE (__force blk_opf_t)(1ULL << __REQ_NOMERGE)
#define REQ_IDLE (__force blk_opf_t)(1ULL << __REQ_IDLE)
#define REQ_INTEGRITY (__force blk_opf_t)(1ULL << __REQ_INTEGRITY)
#define REQ_FLUSH_IS_BARRIER \
(__force blk_opf_t)(1ULL << __REQ_FLUSH_IS_BARRIER)
#define REQ_FUA (__force blk_opf_t)(1ULL << __REQ_FUA)
#define REQ_PREFLUSH (__force blk_opf_t)(1ULL << __REQ_PREFLUSH)
#define REQ_RAHEAD (__force blk_opf_t)(1ULL << __REQ_RAHEAD)
Expand All @@ -458,6 +461,10 @@ enum req_flag_bits {
#define REQ_NOMERGE_FLAGS \
(REQ_NOMERGE | REQ_PREFLUSH | REQ_FUA)

/* Request flags to preserve when submitting a REQ_OP_FLUSH request. */
#define REQ_FLUSH_FLAGS \
(REQ_DRV | REQ_FAILFAST_MASK | REQ_FLUSH_IS_BARRIER)

enum stat_group {
STAT_READ,
STAT_WRITE,
Expand Down

0 comments on commit b2789e4

Please sign in to comment.