Linux RAID subsystem development
 help / color / mirror / Atom feed
* [PATCH 23/32] block/fs: pass in op and flags to ll_rw_block
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

This has ll_rw_block users pass in the request op and flags seperately
instead of as a bitmap.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 fs/buffer.c                 | 19 ++++++++++---------
 fs/ext4/inode.c             |  6 +++---
 fs/ext4/namei.c             |  3 ++-
 fs/ext4/super.c             |  2 +-
 fs/gfs2/bmap.c              |  2 +-
 fs/gfs2/meta_io.c           |  4 ++--
 fs/gfs2/quota.c             |  2 +-
 fs/isofs/compress.c         |  2 +-
 fs/jbd2/journal.c           |  2 +-
 fs/jbd2/recovery.c          |  4 ++--
 fs/ocfs2/aops.c             |  2 +-
 fs/ocfs2/super.c            |  2 +-
 fs/reiserfs/journal.c       |  8 ++++----
 fs/reiserfs/stree.c         |  4 ++--
 fs/reiserfs/super.c         |  2 +-
 fs/squashfs/block.c         |  4 ++--
 fs/udf/dir.c                |  2 +-
 fs/udf/directory.c          |  2 +-
 fs/udf/inode.c              |  2 +-
 fs/ufs/balloc.c             |  2 +-
 include/linux/buffer_head.h |  2 +-
 21 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index cd07d86..ba84126 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -595,7 +595,7 @@ void write_boundary_block(struct block_device *bdev,
 	struct buffer_head *bh = __find_get_block(bdev, bblock + 1, blocksize);
 	if (bh) {
 		if (buffer_dirty(bh))
-			ll_rw_block(WRITE, 1, &bh);
+			ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
 		put_bh(bh);
 	}
 }
@@ -1406,7 +1406,7 @@ void __breadahead(struct block_device *bdev, sector_t block, unsigned size)
 {
 	struct buffer_head *bh = __getblk(bdev, block, size);
 	if (likely(bh)) {
-		ll_rw_block(READA, 1, &bh);
+		ll_rw_block(REQ_OP_READ, REQ_RAHEAD, 1, &bh);
 		brelse(bh);
 	}
 }
@@ -1966,7 +1966,7 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
 		if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
 		    !buffer_unwritten(bh) &&
 		     (block_start < from || block_end > to)) {
-			ll_rw_block(READ, 1, &bh);
+			ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 			*wait_bh++=bh;
 		}
 	}
@@ -2883,7 +2883,7 @@ int block_truncate_page(struct address_space *mapping,
 
 	if (!buffer_uptodate(bh) && !buffer_delay(bh) && !buffer_unwritten(bh)) {
 		err = -EIO;
-		ll_rw_block(READ, 1, &bh);
+		ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 		wait_on_buffer(bh);
 		/* Uhhuh. Read error. Complain and punt. */
 		if (!buffer_uptodate(bh))
@@ -3081,7 +3081,8 @@ EXPORT_SYMBOL(submit_bh);
 
 /**
  * ll_rw_block: low-level access to block devices (DEPRECATED)
- * @rw: whether to %READ or %WRITE or maybe %READA (readahead)
+ * @op: REQ_OP_READ or REQ_OP_WRITE
+ * op_flags: rq_flag_bits
  * @nr: number of &struct buffer_heads in the array
  * @bhs: array of pointers to &struct buffer_head
  *
@@ -3104,7 +3105,7 @@ EXPORT_SYMBOL(submit_bh);
  * All of the buffers must be for the same device, and must also be a
  * multiple of the current approved size for the device.
  */
-void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
+void ll_rw_block(int op, int op_flags, int nr, struct buffer_head *bhs[])
 {
 	int i;
 
@@ -3113,18 +3114,18 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
 
 		if (!trylock_buffer(bh))
 			continue;
-		if (rw == WRITE) {
+		if (op == REQ_OP_WRITE) {
 			if (test_clear_buffer_dirty(bh)) {
 				bh->b_end_io = end_buffer_write_sync;
 				get_bh(bh);
-				submit_bh(REQ_OP_WRITE, 0, bh);
+				submit_bh(REQ_OP_WRITE, op_flags, bh);
 				continue;
 			}
 		} else {
 			if (!buffer_uptodate(bh)) {
 				bh->b_end_io = end_buffer_read_sync;
 				get_bh(bh);
-				submit_bh(rw, 0, bh);
+				submit_bh(REQ_OP_READ, op_flags, bh);
 				continue;
 			}
 		}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index f34ef29..dd2e197 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -791,7 +791,7 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
 		return bh;
 	if (!bh || buffer_uptodate(bh))
 		return bh;
-	ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
+	ll_rw_block(REQ_OP_READ,  REQ_META | REQ_PRIO, 1, &bh);
 	wait_on_buffer(bh);
 	if (buffer_uptodate(bh))
 		return bh;
@@ -948,7 +948,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
 		if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
 		    !buffer_unwritten(bh) &&
 		    (block_start < from || block_end > to)) {
-			ll_rw_block(READ, 1, &bh);
+			ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 			*wait_bh++ = bh;
 			decrypt = ext4_encrypted_inode(inode) &&
 				S_ISREG(inode->i_mode);
@@ -3383,7 +3383,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
 
 	if (!buffer_uptodate(bh)) {
 		err = -EIO;
-		ll_rw_block(READ, 1, &bh);
+		ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 		wait_on_buffer(bh);
 		/* Uhhuh. Read error. Complain and punt. */
 		if (!buffer_uptodate(bh))
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 9f61e76..0336536 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1438,7 +1438,8 @@ restart:
 				}
 				bh_use[ra_max] = bh;
 				if (bh)
-					ll_rw_block(READ | REQ_META | REQ_PRIO,
+					ll_rw_block(REQ_OP_READ,
+						    REQ_META | REQ_PRIO,
 						    1, &bh);
 			}
 		}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d9e4329..037dd9e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4512,7 +4512,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
 		goto out_bdev;
 	}
 	journal->j_private = sb;
-	ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &journal->j_sb_buffer);
+	ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, &journal->j_sb_buffer);
 	wait_on_buffer(journal->j_sb_buffer);
 	if (!buffer_uptodate(journal->j_sb_buffer)) {
 		ext4_msg(sb, KERN_ERR, "I/O error on journal device");
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 967154c..1a22952 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -974,7 +974,7 @@ static int gfs2_block_truncate_page(struct address_space *mapping, loff_t from)
 
 	if (!buffer_uptodate(bh)) {
 		err = -EIO;
-		ll_rw_block(READ, 1, &bh);
+		ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 		wait_on_buffer(bh);
 		/* Uhhuh. Read error. Complain and punt. */
 		if (!buffer_uptodate(bh))
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index ff483bc..264c95c 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -379,7 +379,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
 	if (buffer_uptodate(first_bh))
 		goto out;
 	if (!buffer_locked(first_bh))
-		ll_rw_block(READ_SYNC | REQ_META, 1, &first_bh);
+		ll_rw_block(REQ_OP_READ, READ_SYNC | REQ_META, 1, &first_bh);
 
 	dblock++;
 	extlen--;
@@ -388,7 +388,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
 		bh = gfs2_getbuf(gl, dblock, CREATE);
 
 		if (!buffer_uptodate(bh) && !buffer_locked(bh))
-			ll_rw_block(READA | REQ_META, 1, &bh);
+			ll_rw_block(REQ_OP_READ, REQ_RAHEAD | REQ_META, 1, &bh);
 		brelse(bh);
 		dblock++;
 		extlen--;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 3a31226..841f15a 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -697,7 +697,7 @@ static int gfs2_write_buf_to_page(struct gfs2_inode *ip, unsigned long index,
 		if (PageUptodate(page))
 			set_buffer_uptodate(bh);
 		if (!buffer_uptodate(bh)) {
-			ll_rw_block(READ | REQ_META, 1, &bh);
+			ll_rw_block(REQ_OP_READ, REQ_META, 1, &bh);
 			wait_on_buffer(bh);
 			if (!buffer_uptodate(bh))
 				goto unlock_out;
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
index f311bf0..f9b5fc8 100644
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -81,7 +81,7 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
 	blocknum = block_start >> bufshift;
 	memset(bhs, 0, (needblocks + 1) * sizeof(struct buffer_head *));
 	haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);
-	ll_rw_block(READ, haveblocks, bhs);
+	ll_rw_block(REQ_OP_READ, 0, haveblocks, bhs);
 
 	curbh = 0;
 	curpage = 0;
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index e3855b0..4ba109f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1474,7 +1474,7 @@ static int journal_get_superblock(journal_t *journal)
 
 	J_ASSERT(bh != NULL);
 	if (!buffer_uptodate(bh)) {
-		ll_rw_block(READ, 1, &bh);
+		ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 		wait_on_buffer(bh);
 		if (!buffer_uptodate(bh)) {
 			printk(KERN_ERR
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index a9079d0..3147a89 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -104,7 +104,7 @@ static int do_readahead(journal_t *journal, unsigned int start)
 		if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
 			bufs[nbufs++] = bh;
 			if (nbufs == MAXBUF) {
-				ll_rw_block(READ, nbufs, bufs);
+				ll_rw_block(REQ_OP_READ, 0, nbufs, bufs);
 				journal_brelse_array(bufs, nbufs);
 				nbufs = 0;
 			}
@@ -113,7 +113,7 @@ static int do_readahead(journal_t *journal, unsigned int start)
 	}
 
 	if (nbufs)
-		ll_rw_block(READ, nbufs, bufs);
+		ll_rw_block(REQ_OP_READ, 0, nbufs, bufs);
 	err = 0;
 
 failed:
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 64b11d9..247ad9d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1141,7 +1141,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
 			   !buffer_new(bh) &&
 			   ocfs2_should_read_blk(inode, page, block_start) &&
 			   (block_start < from || block_end > to)) {
-			ll_rw_block(READ, 1, &bh);
+			ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 			*wait_bh++=bh;
 		}
 
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 2de4c8a..e860b60 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1837,7 +1837,7 @@ static int ocfs2_get_sector(struct super_block *sb,
 	if (!buffer_dirty(*bh))
 		clear_buffer_uptodate(*bh);
 	unlock_buffer(*bh);
-	ll_rw_block(READ, 1, bh);
+	ll_rw_block(REQ_OP_READ, 0, 1, bh);
 	wait_on_buffer(*bh);
 	if (!buffer_uptodate(*bh)) {
 		mlog_errno(-EIO);
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index df69581..feff389 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -872,7 +872,7 @@ loop_next:
 		 */
 		if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) {
 			spin_unlock(lock);
-			ll_rw_block(WRITE, 1, &bh);
+			ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
 			spin_lock(lock);
 		}
 		put_bh(bh);
@@ -1059,7 +1059,7 @@ static int flush_commit_list(struct super_block *s,
 		if (tbh) {
 			if (buffer_dirty(tbh)) {
 		            depth = reiserfs_write_unlock_nested(s);
-			    ll_rw_block(WRITE, 1, &tbh);
+			    ll_rw_block(REQ_OP_WRITE, 0, 1, &tbh);
 			    reiserfs_write_lock_nested(s, depth);
 			}
 			put_bh(tbh) ;
@@ -2248,7 +2248,7 @@ abort_replay:
 		}
 	}
 	/* read in the log blocks, memcpy to the corresponding real block */
-	ll_rw_block(READ, get_desc_trans_len(desc), log_blocks);
+	ll_rw_block(REQ_OP_READ, 0, get_desc_trans_len(desc), log_blocks);
 	for (i = 0; i < get_desc_trans_len(desc); i++) {
 
 		wait_on_buffer(log_blocks[i]);
@@ -2350,7 +2350,7 @@ static struct buffer_head *reiserfs_breada(struct block_device *dev,
 		} else
 			bhlist[j++] = bh;
 	}
-	ll_rw_block(READ, j, bhlist);
+	ll_rw_block(REQ_OP_READ, 0, j, bhlist);
 	for (i = 1; i < j; i++)
 		brelse(bhlist[i]);
 	bh = bhlist[0];
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 24cbe01..e887401 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -551,7 +551,7 @@ static int search_by_key_reada(struct super_block *s,
 		if (!buffer_uptodate(bh[j])) {
 			if (depth == -1)
 				depth = reiserfs_write_unlock_nested(s);
-			ll_rw_block(READA, 1, bh + j);
+			ll_rw_block(REQ_OP_READ, REQ_RAHEAD, 1, bh + j);
 		}
 		brelse(bh[j]);
 	}
@@ -660,7 +660,7 @@ int search_by_key(struct super_block *sb, const struct cpu_key *key,
 			if (!buffer_uptodate(bh) && depth == -1)
 				depth = reiserfs_write_unlock_nested(sb);
 
-			ll_rw_block(READ, 1, &bh);
+			ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 			wait_on_buffer(bh);
 
 			if (depth != -1)
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 4a62fe8..68f5f5c 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1659,7 +1659,7 @@ static int read_super_block(struct super_block *s, int offset)
 /* after journal replay, reread all bitmap and super blocks */
 static int reread_meta_blocks(struct super_block *s)
 {
-	ll_rw_block(READ, 1, &SB_BUFFER_WITH_SB(s));
+	ll_rw_block(REQ_OP_READ, 0, 1, &SB_BUFFER_WITH_SB(s));
 	wait_on_buffer(SB_BUFFER_WITH_SB(s));
 	if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
 		reiserfs_warning(s, "reiserfs-2504", "error reading the super");
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 0cea9b9..59375be 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -124,7 +124,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,
 				goto block_release;
 			bytes += msblk->devblksize;
 		}
-		ll_rw_block(READ, b, bh);
+		ll_rw_block(REQ_OP_READ, 0, b, bh);
 	} else {
 		/*
 		 * Metadata block.
@@ -156,7 +156,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,
 				goto block_release;
 			bytes += msblk->devblksize;
 		}
-		ll_rw_block(READ, b - 1, bh + 1);
+		ll_rw_block(REQ_OP_READ, 0, b - 1, bh + 1);
 	}
 
 	for (i = 0; i < b; i++) {
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 541d9c6..1792fa0 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -113,7 +113,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
 					brelse(tmp);
 			}
 			if (num) {
-				ll_rw_block(READA, num, bha);
+				ll_rw_block(REQ_OP_READ, REQ_RAHEAD, num, bha);
 				for (i = 0; i < num; i++)
 					brelse(bha[i]);
 			}
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index c763fda..988d535 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -87,7 +87,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
 					brelse(tmp);
 			}
 			if (num) {
-				ll_rw_block(READA, num, bha);
+				ll_rw_block(REQ_OP_READ, REQ_RAHEAD, num, bha);
 				for (i = 0; i < num; i++)
 					brelse(bha[i]);
 			}
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 8d0b3ad..240c0cc 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1191,7 +1191,7 @@ struct buffer_head *udf_bread(struct inode *inode, int block,
 	if (buffer_uptodate(bh))
 		return bh;
 
-	ll_rw_block(READ, 1, &bh);
+	ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 
 	wait_on_buffer(bh);
 	if (buffer_uptodate(bh))
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index dc5fae6..26a3bb1 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -292,7 +292,7 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg,
 			if (!buffer_mapped(bh))
 					map_bh(bh, inode->i_sb, oldb + pos);
 			if (!buffer_uptodate(bh)) {
-				ll_rw_block(READ, 1, &bh);
+				ll_rw_block(REQ_OP_READ, 0, 1, &bh);
 				wait_on_buffer(bh);
 				if (!buffer_uptodate(bh)) {
 					ufs_error(inode->i_sb, __func__,
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 6edc8dd..8505ee7 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -187,7 +187,7 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags);
 void free_buffer_head(struct buffer_head * bh);
 void unlock_buffer(struct buffer_head *bh);
 void __lock_buffer(struct buffer_head *bh);
-void ll_rw_block(int, int, struct buffer_head * bh[]);
+void ll_rw_block(int, int, int, struct buffer_head * bh[]);
 int sync_dirty_buffer(struct buffer_head *bh);
 int __sync_dirty_buffer(struct buffer_head *bh, int op, int op_flags);
 void write_dirty_buffer(struct buffer_head *bh, int op_flags);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 24/32] dm: pass dm stats data dir instead of bi_rw
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

It looks like dm stats primarily cares about the data direction
(READ vs WRITE) and does not need the bio/request flags
and in the future operation value. REQ_DISCARD is always set with
REQ_WRITE, so the check for either one in dm_stats_account_io
is not needed.

This patch has it use the bio and request data_dir helpers
instead of accessing the bi_rw/cmd_flags directly. This makes
the next patches that remove the operation from the cmd_flags
and bi_rw cleaner since we do not have to check for multiple
operations.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/md/dm-stats.c | 6 +++---
 drivers/md/dm.c       | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c
index 8289804..96b5c1b 100644
--- a/drivers/md/dm-stats.c
+++ b/drivers/md/dm-stats.c
@@ -518,7 +518,7 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry,
 			      struct dm_stats_aux *stats_aux, bool end,
 			      unsigned long duration_jiffies)
 {
-	unsigned long idx = bi_rw & REQ_WRITE;
+	unsigned long idx = bi_rw;
 	struct dm_stat_shared *shared = &s->stat_shared[entry];
 	struct dm_stat_percpu *p;
 
@@ -645,8 +645,8 @@ void dm_stats_account_io(struct dm_stats *stats, unsigned long bi_rw,
 		last = raw_cpu_ptr(stats->last);
 		stats_aux->merged =
 			(bi_sector == (ACCESS_ONCE(last->last_sector) &&
-				       ((bi_rw & (REQ_WRITE | REQ_DISCARD)) ==
-					(ACCESS_ONCE(last->last_rw) & (REQ_WRITE | REQ_DISCARD)))
+				       ((bi_rw == WRITE) ==
+					(ACCESS_ONCE(last->last_rw) == WRITE))
 				       ));
 		ACCESS_ONCE(last->last_sector) = end_sector;
 		ACCESS_ONCE(last->last_rw) = bi_rw;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index d2cf6d9..ea4bc70 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -655,7 +655,7 @@ static void start_io_acct(struct dm_io *io)
 		atomic_inc_return(&md->pending[rw]));
 
 	if (unlikely(dm_stats_used(&md->stats)))
-		dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_iter.bi_sector,
+		dm_stats_account_io(&md->stats, bio_data_dir(bio), bio->bi_iter.bi_sector,
 				    bio_sectors(bio), false, 0, &io->stats_aux);
 }
 
@@ -670,7 +670,7 @@ static void end_io_acct(struct dm_io *io)
 	generic_end_io_acct(rw, &dm_disk(md)->part0, io->start_time);
 
 	if (unlikely(dm_stats_used(&md->stats)))
-		dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_iter.bi_sector,
+		dm_stats_account_io(&md->stats, bio_data_dir(bio), bio->bi_iter.bi_sector,
 				    bio_sectors(bio), true, duration, &io->stats_aux);
 
 	/*
@@ -1053,7 +1053,7 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig)
 	if (unlikely(dm_stats_used(&md->stats))) {
 		struct dm_rq_target_io *tio = tio_from_request(orig);
 		tio->duration_jiffies = jiffies - tio->duration_jiffies;
-		dm_stats_account_io(&md->stats, orig->cmd_flags, blk_rq_pos(orig),
+		dm_stats_account_io(&md->stats, rq_data_dir(orig), blk_rq_pos(orig),
 				    tio->n_sectors, true, tio->duration_jiffies,
 				    &tio->stats_aux);
 	}
@@ -1988,7 +1988,7 @@ static void dm_start_request(struct mapped_device *md, struct request *orig)
 		struct dm_rq_target_io *tio = tio_from_request(orig);
 		tio->duration_jiffies = jiffies;
 		tio->n_sectors = blk_rq_sectors(orig);
-		dm_stats_account_io(&md->stats, orig->cmd_flags, blk_rq_pos(orig),
+		dm_stats_account_io(&md->stats, rq_data_dir(orig), blk_rq_pos(orig),
 				    tio->n_sectors, false, 0, &tio->stats_aux);
 	}
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 25/32] block: add operation field to request struct
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

This patch adds field to the request to store the REQ_OP, and
has the block layer code set it up.

The next patches will modify the other drivers to get/test the
request->op field. We are still ORing the op into the cmd_flags.
When I am done with the conversion, that will be dropped.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 block/blk-core.c       | 50 ++++++++++++++++++++++++++++----------------------
 block/blk-flush.c      |  1 +
 block/blk-mq.c         | 31 +++++++++++++++++--------------
 include/linux/blkdev.h |  1 +
 4 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index c8672f2..e625516 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -984,7 +984,8 @@ static struct io_context *rq_ioc(struct bio *bio)
 /**
  * __get_request - get a free request
  * @rl: request list to allocate from
- * @rw_flags: RW and SYNC flags
+ * @op: REQ_OP
+ * @op_flags: rq_flag_bits
  * @bio: bio to allocate request for (can be %NULL)
  * @gfp_mask: allocation mask
  *
@@ -995,21 +996,22 @@ static struct io_context *rq_ioc(struct bio *bio)
  * Returns ERR_PTR on failure, with @q->queue_lock held.
  * Returns request pointer on success, with @q->queue_lock *not held*.
  */
-static struct request *__get_request(struct request_list *rl, int rw_flags,
-				     struct bio *bio, gfp_t gfp_mask)
+static struct request *__get_request(struct request_list *rl, int op,
+				     int op_flags, struct bio *bio,
+				     gfp_t gfp_mask)
 {
 	struct request_queue *q = rl->q;
 	struct request *rq;
 	struct elevator_type *et = q->elevator->type;
 	struct io_context *ioc = rq_ioc(bio);
 	struct io_cq *icq = NULL;
-	const bool is_sync = rw_is_sync(rw_flags) != 0;
+	const bool is_sync = rw_is_sync(op | op_flags) != 0;
 	int may_queue;
 
 	if (unlikely(blk_queue_dying(q)))
 		return ERR_PTR(-ENODEV);
 
-	may_queue = elv_may_queue(q, rw_flags);
+	may_queue = elv_may_queue(q, op | op_flags);
 	if (may_queue == ELV_MQUEUE_NO)
 		goto rq_starved;
 
@@ -1053,7 +1055,7 @@ static struct request *__get_request(struct request_list *rl, int rw_flags,
 
 	/*
 	 * Decide whether the new request will be managed by elevator.  If
-	 * so, mark @rw_flags and increment elvpriv.  Non-zero elvpriv will
+	 * so, mark @op_flags and increment elvpriv.  Non-zero elvpriv will
 	 * prevent the current elevator from being destroyed until the new
 	 * request is freed.  This guarantees icq's won't be destroyed and
 	 * makes creating new ones safe.
@@ -1062,14 +1064,14 @@ static struct request *__get_request(struct request_list *rl, int rw_flags,
 	 * it will be created after releasing queue_lock.
 	 */
 	if (blk_rq_should_init_elevator(bio) && !blk_queue_bypass(q)) {
-		rw_flags |= REQ_ELVPRIV;
+		op_flags |= REQ_ELVPRIV;
 		q->nr_rqs_elvpriv++;
 		if (et->icq_cache && ioc)
 			icq = ioc_lookup_icq(ioc, q);
 	}
 
 	if (blk_queue_io_stat(q))
-		rw_flags |= REQ_IO_STAT;
+		op_flags |= REQ_IO_STAT;
 	spin_unlock_irq(q->queue_lock);
 
 	/* allocate and init request */
@@ -1079,10 +1081,11 @@ static struct request *__get_request(struct request_list *rl, int rw_flags,
 
 	blk_rq_init(q, rq);
 	blk_rq_set_rl(rq, rl);
-	rq->cmd_flags = rw_flags | REQ_ALLOCED;
+	rq->cmd_flags = op | op_flags | REQ_ALLOCED;
+	rq->op = op;
 
 	/* init elvpriv */
-	if (rw_flags & REQ_ELVPRIV) {
+	if (op_flags & REQ_ELVPRIV) {
 		if (unlikely(et->icq_cache && !icq)) {
 			if (ioc)
 				icq = ioc_create_icq(ioc, q, gfp_mask);
@@ -1108,7 +1111,7 @@ out:
 	if (ioc_batching(q, ioc))
 		ioc->nr_batch_requests--;
 
-	trace_block_getrq(q, bio, rw_flags & 1);
+	trace_block_getrq(q, bio, op);
 	return rq;
 
 fail_elvpriv:
@@ -1138,7 +1141,7 @@ fail_alloc:
 	 * queue, but this is pretty rare.
 	 */
 	spin_lock_irq(q->queue_lock);
-	freed_request(rl, rw_flags);
+	freed_request(rl, op | op_flags);
 
 	/*
 	 * in the very unlikely event that allocation failed and no
@@ -1156,7 +1159,8 @@ rq_starved:
 /**
  * get_request - get a free request
  * @q: request_queue to allocate request from
- * @rw_flags: RW and SYNC flags
+ * op: REQ_OP
+ * @op_flags: rq_flag_bits
  * @bio: bio to allocate request for (can be %NULL)
  * @gfp_mask: allocation mask
  *
@@ -1167,17 +1171,18 @@ rq_starved:
  * Returns ERR_PTR on failure, with @q->queue_lock held.
  * Returns request pointer on success, with @q->queue_lock *not held*.
  */
-static struct request *get_request(struct request_queue *q, int rw_flags,
-				   struct bio *bio, gfp_t gfp_mask)
+static struct request *get_request(struct request_queue *q, int op,
+				   int op_flags, struct bio *bio,
+				   gfp_t gfp_mask)
 {
-	const bool is_sync = rw_is_sync(rw_flags) != 0;
+	const bool is_sync = rw_is_sync(op | op_flags) != 0;
 	DEFINE_WAIT(wait);
 	struct request_list *rl;
 	struct request *rq;
 
 	rl = blk_get_rl(q, bio);	/* transferred to @rq on success */
 retry:
-	rq = __get_request(rl, rw_flags, bio, gfp_mask);
+	rq = __get_request(rl, op, op_flags, bio, gfp_mask);
 	if (!IS_ERR(rq))
 		return rq;
 
@@ -1190,7 +1195,7 @@ retry:
 	prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
 				  TASK_UNINTERRUPTIBLE);
 
-	trace_block_sleeprq(q, bio, rw_flags & 1);
+	trace_block_sleeprq(q, bio, op);
 
 	spin_unlock_irq(q->queue_lock);
 	io_schedule();
@@ -1219,7 +1224,7 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw,
 	create_io_context(gfp_mask, q->node);
 
 	spin_lock_irq(q->queue_lock);
-	rq = get_request(q, rw, NULL, gfp_mask);
+	rq = get_request(q, rw, 0, NULL, gfp_mask);
 	if (IS_ERR(rq))
 		spin_unlock_irq(q->queue_lock);
 	/* q->queue_lock is unlocked at this point */
@@ -1612,7 +1617,7 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
 {
 	const bool sync = !!(bio->bi_rw & REQ_SYNC);
 	struct blk_plug *plug;
-	int el_ret, rw_flags, where = ELEVATOR_INSERT_SORT;
+	int el_ret, rw_flags = 0, where = ELEVATOR_INSERT_SORT;
 	struct request *req;
 	unsigned int request_count = 0;
 
@@ -1670,7 +1675,6 @@ get_rq:
 	 * but we need to set it earlier to expose the sync flag to the
 	 * rq allocator and io schedulers.
 	 */
-	rw_flags = bio_data_dir(bio);
 	if (sync)
 		rw_flags |= REQ_SYNC;
 
@@ -1678,7 +1682,7 @@ get_rq:
 	 * Grab a free request. This is might sleep but can not fail.
 	 * Returns with the queue unlocked.
 	 */
-	req = get_request(q, rw_flags, bio, GFP_NOIO);
+	req = get_request(q, bio_data_dir(bio), rw_flags, bio, GFP_NOIO);
 	if (IS_ERR(req)) {
 		bio->bi_error = PTR_ERR(req);
 		bio_endio(bio);
@@ -2870,6 +2874,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 {
 	/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw */
 	rq->cmd_flags |= bio->bi_rw & REQ_WRITE;
+	rq->op = bio->bi_op;
 
 	if (bio_has_data(bio))
 		rq->nr_phys_segments = bio_phys_segments(q, bio);
@@ -2954,6 +2959,7 @@ EXPORT_SYMBOL_GPL(blk_rq_unprep_clone);
 static void __blk_rq_prep_clone(struct request *dst, struct request *src)
 {
 	dst->cpu = src->cpu;
+	dst->op = src->op;
 	dst->cmd_flags |= (src->cmd_flags & REQ_CLONE_MASK) | REQ_NOMERGE;
 	dst->cmd_type = src->cmd_type;
 	dst->__sector = blk_rq_pos(src);
diff --git a/block/blk-flush.c b/block/blk-flush.c
index f707ba1..fc9c343 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -330,6 +330,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
 
 	flush_rq->cmd_type = REQ_TYPE_FS;
 	flush_rq->cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ;
+	flush_rq->op = REQ_OP_WRITE;
 	flush_rq->rq_disk = first_rq->rq_disk;
 	flush_rq->end_io = flush_end_io;
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 85f0143..d57a581 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -176,16 +176,18 @@ bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
 EXPORT_SYMBOL(blk_mq_can_queue);
 
 static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
-			       struct request *rq, unsigned int rw_flags)
+			       struct request *rq, int op,
+			       unsigned int op_flags)
 {
 	if (blk_queue_io_stat(q))
-		rw_flags |= REQ_IO_STAT;
+		op_flags |= REQ_IO_STAT;
 
 	INIT_LIST_HEAD(&rq->queuelist);
 	/* csd/requeue_work/fifo_time is initialized before use */
 	rq->q = q;
 	rq->mq_ctx = ctx;
-	rq->cmd_flags |= rw_flags;
+	rq->op = op;
+	rq->cmd_flags |= op | op_flags;
 	/* do not touch atomic flags, it needs atomic ops against the timer */
 	rq->cpu = -1;
 	INIT_HLIST_NODE(&rq->hash);
@@ -220,11 +222,11 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
 	rq->end_io_data = NULL;
 	rq->next_rq = NULL;
 
-	ctx->rq_dispatched[rw_is_sync(rw_flags)]++;
+	ctx->rq_dispatched[rw_is_sync(op | op_flags)]++;
 }
 
 static struct request *
-__blk_mq_alloc_request(struct blk_mq_alloc_data *data, int rw)
+__blk_mq_alloc_request(struct blk_mq_alloc_data *data, int op, int op_flags)
 {
 	struct request *rq;
 	unsigned int tag;
@@ -239,7 +241,7 @@ __blk_mq_alloc_request(struct blk_mq_alloc_data *data, int rw)
 		}
 
 		rq->tag = tag;
-		blk_mq_rq_ctx_init(data->q, data->ctx, rq, rw);
+		blk_mq_rq_ctx_init(data->q, data->ctx, rq, op, op_flags);
 		return rq;
 	}
 
@@ -264,7 +266,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp,
 	blk_mq_set_alloc_data(&alloc_data, q, gfp & ~__GFP_WAIT,
 			reserved, ctx, hctx);
 
-	rq = __blk_mq_alloc_request(&alloc_data, rw);
+	rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
 	if (!rq && (gfp & __GFP_WAIT)) {
 		__blk_mq_run_hw_queue(hctx);
 		blk_mq_put_ctx(ctx);
@@ -273,7 +275,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp,
 		hctx = q->mq_ops->map_queue(q, ctx->cpu);
 		blk_mq_set_alloc_data(&alloc_data, q, gfp, reserved, ctx,
 				hctx);
-		rq =  __blk_mq_alloc_request(&alloc_data, rw);
+		rq =  __blk_mq_alloc_request(&alloc_data, rw, 0);
 		ctx = alloc_data.ctx;
 	}
 	blk_mq_put_ctx(ctx);
@@ -1173,7 +1175,8 @@ static struct request *blk_mq_map_request(struct request_queue *q,
 	struct blk_mq_hw_ctx *hctx;
 	struct blk_mq_ctx *ctx;
 	struct request *rq;
-	int rw = bio_data_dir(bio);
+	int op = bio_data_dir(bio);
+	int op_flags = 0;
 	struct blk_mq_alloc_data alloc_data;
 
 	if (unlikely(blk_mq_queue_enter(q, GFP_KERNEL))) {
@@ -1185,22 +1188,22 @@ static struct request *blk_mq_map_request(struct request_queue *q,
 	hctx = q->mq_ops->map_queue(q, ctx->cpu);
 
 	if (rw_is_sync(bio->bi_rw))
-		rw |= REQ_SYNC;
+		op_flags |= REQ_SYNC;
 
-	trace_block_getrq(q, bio, rw);
+	trace_block_getrq(q, bio, op);
 	blk_mq_set_alloc_data(&alloc_data, q, GFP_ATOMIC, false, ctx,
 			hctx);
-	rq = __blk_mq_alloc_request(&alloc_data, rw);
+	rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
 	if (unlikely(!rq)) {
 		__blk_mq_run_hw_queue(hctx);
 		blk_mq_put_ctx(ctx);
-		trace_block_sleeprq(q, bio, rw);
+		trace_block_sleeprq(q, bio, op);
 
 		ctx = blk_mq_get_ctx(q);
 		hctx = q->mq_ops->map_queue(q, ctx->cpu);
 		blk_mq_set_alloc_data(&alloc_data, q,
 				__GFP_WAIT|GFP_ATOMIC, false, ctx, hctx);
-		rq = __blk_mq_alloc_request(&alloc_data, rw);
+		rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
 		ctx = alloc_data.ctx;
 		hctx = alloc_data.hctx;
 	}
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index cf5f518..9c5bee9 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -94,6 +94,7 @@ struct request {
 	struct request_queue *q;
 	struct blk_mq_ctx *mq_ctx;
 
+	int op;
 	u64 cmd_flags;
 	unsigned cmd_type;
 	unsigned long atomic_flags;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 26/32] ide cd: do not set REQ_WRITE on requests.
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

The block layer will set the correct READ/WRITE operation flags/fields
when creating a request, so there is not need for drivers to set the
REQ_WRITE flag.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/ide/ide-cd_ioctl.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index 066e390..d2d0b38 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -459,9 +459,6 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi,
 	   layer. the packet must be complete, as we do not
 	   touch it at all. */
 
-	if (cgc->data_direction == CGC_DATA_WRITE)
-		flags |= REQ_WRITE;
-
 	if (cgc->sense)
 		memset(cgc->sense, 0, sizeof(struct request_sense));
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 27/32] cfq/cgroup: pass operation and flags seperately
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

The operation is about to be separated from the flags, so this
patch has users pass them in separately to the cgroup stats.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 block/cfq-iosched.c        | 49 +++++++++++++++++++++++++++-------------------
 include/linux/blk-cgroup.h | 13 ++++++------
 2 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 04de884..dbc3da4 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -660,9 +660,10 @@ static inline void cfqg_put(struct cfq_group *cfqg)
 } while (0)
 
 static inline void cfqg_stats_update_io_add(struct cfq_group *cfqg,
-					    struct cfq_group *curr_cfqg, int rw)
+					    struct cfq_group *curr_cfqg, int op,
+					    int op_flags)
 {
-	blkg_rwstat_add(&cfqg->stats.queued, rw, 1);
+	blkg_rwstat_add(&cfqg->stats.queued, op, op_flags, 1);
 	cfqg_stats_end_empty_time(&cfqg->stats);
 	cfqg_stats_set_start_group_wait_time(cfqg, curr_cfqg);
 }
@@ -676,26 +677,30 @@ static inline void cfqg_stats_update_timeslice_used(struct cfq_group *cfqg,
 #endif
 }
 
-static inline void cfqg_stats_update_io_remove(struct cfq_group *cfqg, int rw)
+static inline void cfqg_stats_update_io_remove(struct cfq_group *cfqg, int op,
+					       int op_flags)
 {
-	blkg_rwstat_add(&cfqg->stats.queued, rw, -1);
+	blkg_rwstat_add(&cfqg->stats.queued, op, op_flags, -1);
 }
 
-static inline void cfqg_stats_update_io_merged(struct cfq_group *cfqg, int rw)
+static inline void cfqg_stats_update_io_merged(struct cfq_group *cfqg, int op,
+					       int op_flags)
 {
-	blkg_rwstat_add(&cfqg->stats.merged, rw, 1);
+	blkg_rwstat_add(&cfqg->stats.merged, op, op_flags, 1);
 }
 
 static inline void cfqg_stats_update_completion(struct cfq_group *cfqg,
-			uint64_t start_time, uint64_t io_start_time, int rw)
+			uint64_t start_time, uint64_t io_start_time, int op,
+			int op_flags)
 {
 	struct cfqg_stats *stats = &cfqg->stats;
 	unsigned long long now = sched_clock();
 
 	if (time_after64(now, io_start_time))
-		blkg_rwstat_add(&stats->service_time, rw, now - io_start_time);
+		blkg_rwstat_add(&stats->service_time, op, op_flags,
+				now - io_start_time);
 	if (time_after64(io_start_time, start_time))
-		blkg_rwstat_add(&stats->wait_time, rw,
+		blkg_rwstat_add(&stats->wait_time, op, op_flags,
 				io_start_time - start_time);
 }
 
@@ -769,13 +774,16 @@ static inline void cfqg_put(struct cfq_group *cfqg) { }
 #define cfq_log_cfqg(cfqd, cfqg, fmt, args...)		do {} while (0)
 
 static inline void cfqg_stats_update_io_add(struct cfq_group *cfqg,
-			struct cfq_group *curr_cfqg, int rw) { }
+			struct cfq_group *curr_cfqg, int op, int op_flags) { }
 static inline void cfqg_stats_update_timeslice_used(struct cfq_group *cfqg,
 			unsigned long time, unsigned long unaccounted_time) { }
-static inline void cfqg_stats_update_io_remove(struct cfq_group *cfqg, int rw) { }
-static inline void cfqg_stats_update_io_merged(struct cfq_group *cfqg, int rw) { }
+static inline void cfqg_stats_update_io_remove(struct cfq_group *cfqg, int op,
+			int op_flags) { }
+static inline void cfqg_stats_update_io_merged(struct cfq_group *cfqg, int op,
+			int op_flags) { }
 static inline void cfqg_stats_update_completion(struct cfq_group *cfqg,
-			uint64_t start_time, uint64_t io_start_time, int rw) { }
+			uint64_t start_time, uint64_t io_start_time, int op,
+			int op_flags) { }
 
 #endif	/* CONFIG_CFQ_GROUP_IOSCHED */
 
@@ -2449,10 +2457,10 @@ static void cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq)
 {
 	elv_rb_del(&cfqq->sort_list, rq);
 	cfqq->queued[rq_is_sync(rq)]--;
-	cfqg_stats_update_io_remove(RQ_CFQG(rq), rq->cmd_flags);
+	cfqg_stats_update_io_remove(RQ_CFQG(rq), rq->op, rq->cmd_flags);
 	cfq_add_rq_rb(rq);
 	cfqg_stats_update_io_add(RQ_CFQG(rq), cfqq->cfqd->serving_group,
-				 rq->cmd_flags);
+				 rq->op, rq->cmd_flags);
 }
 
 static struct request *
@@ -2505,7 +2513,7 @@ static void cfq_remove_request(struct request *rq)
 	cfq_del_rq_rb(rq);
 
 	cfqq->cfqd->rq_queued--;
-	cfqg_stats_update_io_remove(RQ_CFQG(rq), rq->cmd_flags);
+	cfqg_stats_update_io_remove(RQ_CFQG(rq), rq->op, rq->cmd_flags);
 	if (rq->cmd_flags & REQ_PRIO) {
 		WARN_ON(!cfqq->prio_pending);
 		cfqq->prio_pending--;
@@ -2540,7 +2548,7 @@ static void cfq_merged_request(struct request_queue *q, struct request *req,
 static void cfq_bio_merged(struct request_queue *q, struct request *req,
 				struct bio *bio)
 {
-	cfqg_stats_update_io_merged(RQ_CFQG(req), bio->bi_rw);
+	cfqg_stats_update_io_merged(RQ_CFQG(req), bio->bi_op, bio->bi_rw);
 }
 
 static void
@@ -2563,7 +2571,7 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
 	if (cfqq->next_rq == next)
 		cfqq->next_rq = rq;
 	cfq_remove_request(next);
-	cfqg_stats_update_io_merged(RQ_CFQG(rq), next->cmd_flags);
+	cfqg_stats_update_io_merged(RQ_CFQG(rq), next->op, next->cmd_flags);
 
 	cfqq = RQ_CFQQ(next);
 	/*
@@ -4085,7 +4093,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
 	rq->fifo_time = jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)];
 	list_add_tail(&rq->queuelist, &cfqq->fifo);
 	cfq_add_rq_rb(rq);
-	cfqg_stats_update_io_add(RQ_CFQG(rq), cfqd->serving_group,
+	cfqg_stats_update_io_add(RQ_CFQG(rq), cfqd->serving_group, rq->op,
 				 rq->cmd_flags);
 	cfq_rq_enqueued(cfqd, cfqq, rq);
 }
@@ -4183,7 +4191,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
 	cfqq->dispatched--;
 	(RQ_CFQG(rq))->dispatched--;
 	cfqg_stats_update_completion(cfqq->cfqg, rq_start_time_ns(rq),
-				     rq_io_start_time_ns(rq), rq->cmd_flags);
+				     rq_io_start_time_ns(rq), rq->op,
+				     rq->cmd_flags);
 
 	cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--;
 
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index c02e669..0b230b9 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -590,25 +590,26 @@ static inline void blkg_rwstat_exit(struct blkg_rwstat *rwstat)
 /**
  * blkg_rwstat_add - add a value to a blkg_rwstat
  * @rwstat: target blkg_rwstat
- * @rw: mask of REQ_{WRITE|SYNC}
+ * @op: REQ_OP
+ * @op_flags: rq_flag_bits
  * @val: value to add
  *
  * Add @val to @rwstat.  The counters are chosen according to @rw.  The
  * caller is responsible for synchronizing calls to this function.
  */
 static inline void blkg_rwstat_add(struct blkg_rwstat *rwstat,
-				   int rw, uint64_t val)
+				   int op, int op_flags, uint64_t val)
 {
 	struct percpu_counter *cnt;
 
-	if (rw & REQ_WRITE)
+	if (op_to_data_dir(op))
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_WRITE];
 	else
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_READ];
 
 	__percpu_counter_add(cnt, val, BLKG_STAT_CPU_BATCH);
 
-	if (rw & REQ_SYNC)
+	if (op_flags & REQ_SYNC)
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_SYNC];
 	else
 		cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_ASYNC];
@@ -713,9 +714,9 @@ static inline bool blkcg_bio_issue_check(struct request_queue *q,
 
 	if (!throtl) {
 		blkg = blkg ?: q->root_blkg;
-		blkg_rwstat_add(&blkg->stat_bytes, bio->bi_rw,
+		blkg_rwstat_add(&blkg->stat_bytes, bio->bi_op, bio->bi_rw,
 				bio->bi_iter.bi_size);
-		blkg_rwstat_add(&blkg->stat_ios, bio->bi_rw, 1);
+		blkg_rwstat_add(&blkg->stat_ios, bio->bi_op, bio->bi_rw, 1);
 	}
 
 	rcu_read_unlock();
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 28/32] block/fs/drivers: use bio/rq_data_dir helpers
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

This has the the block layer, drivers and fs code use
the bio and rq data_dir helpers instead of accessing the
bi_rw/cmd_flags and checking for REQ_WRITE.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 block/blk-merge.c                | 2 +-
 drivers/ata/libata-scsi.c        | 2 +-
 drivers/block/loop.c             | 6 +++---
 drivers/block/rbd.c              | 2 +-
 drivers/block/umem.c             | 2 +-
 drivers/ide/ide-floppy.c         | 2 +-
 drivers/md/bcache/io.c           | 2 +-
 drivers/md/bcache/request.c      | 6 +++---
 drivers/scsi/osd/osd_initiator.c | 4 ++--
 fs/btrfs/disk-io.c               | 2 +-
 fs/btrfs/extent_io.c             | 2 +-
 fs/btrfs/inode.c                 | 2 +-
 include/linux/blkdev.h           | 2 +-
 include/linux/fs.h               | 2 +-
 14 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index c4e9c37..fe00d94 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -378,7 +378,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 	}
 
 	if (q->dma_drain_size && q->dma_drain_needed(rq)) {
-		if (rq->cmd_flags & REQ_WRITE)
+		if (rq_data_dir(rq) == WRITE)
 			memset(q->dma_drain_buffer, 0, q->dma_drain_size);
 
 		sg_unmark_end(sg);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 0d7f0da..68c2b34 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1125,7 +1125,7 @@ static int atapi_drain_needed(struct request *rq)
 	if (likely(rq->cmd_type != REQ_TYPE_BLOCK_PC))
 		return 0;
 
-	if (!blk_rq_bytes(rq) || (rq->cmd_flags & REQ_WRITE))
+	if (!blk_rq_bytes(rq) || rq_data_dir(rq) == WRITE)
 		return 0;
 
 	return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 674f800..e214936 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -396,7 +396,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
 
 	pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset;
 
-	if (rq->cmd_flags & REQ_WRITE) {
+	if (rq_data_dir(rq) == WRITE) {
 		if (rq->cmd_flags & REQ_FLUSH)
 			ret = lo_req_flush(lo, rq);
 		else if (rq->cmd_flags & REQ_DISCARD)
@@ -1461,7 +1461,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
 	if (lo->lo_state != Lo_bound)
 		return -EIO;
 
-	if (cmd->rq->cmd_flags & REQ_WRITE) {
+	if (rq_data_dir(cmd->rq) == WRITE) {
 		struct loop_device *lo = cmd->rq->q->queuedata;
 		bool need_sched = true;
 
@@ -1484,7 +1484,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
 
 static void loop_handle_cmd(struct loop_cmd *cmd)
 {
-	const bool write = cmd->rq->cmd_flags & REQ_WRITE;
+	const bool write = rq_data_dir(cmd->rq);
 	struct loop_device *lo = cmd->rq->q->queuedata;
 	int ret = 0;
 
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 6f26cf3..39104ca 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3377,7 +3377,7 @@ static void rbd_queue_workfn(struct work_struct *work)
 
 	if (rq->cmd_flags & REQ_DISCARD)
 		op_type = OBJ_OP_DISCARD;
-	else if (rq->cmd_flags & REQ_WRITE)
+	else if (rq_data_dir(rq) == WRITE)
 		op_type = OBJ_OP_WRITE;
 	else
 		op_type = OBJ_OP_READ;
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 04d6579..2355754 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -462,7 +462,7 @@ static void process_page(unsigned long data)
 				le32_to_cpu(desc->local_addr)>>9,
 				le32_to_cpu(desc->transfer_size));
 			dump_dmastat(card, control);
-		} else if ((bio->bi_rw & REQ_WRITE) &&
+		} else if (bio_data_dir(bio) == WRITE &&
 			   le32_to_cpu(desc->local_addr) >> 9 ==
 				card->init_size) {
 			card->init_size += le32_to_cpu(desc->transfer_size) >> 9;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 2fb5350..f079d8d 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -206,7 +206,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
 	memcpy(rq->cmd, pc->c, 12);
 
 	pc->rq = rq;
-	if (rq->cmd_flags & REQ_WRITE)
+	if (cmd == WRITE)
 		pc->flags |= PC_FLAG_WRITING;
 
 	pc->flags |= PC_FLAG_DMA_OK;
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index 86a0bb8..fbc8974 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -111,7 +111,7 @@ void bch_bbio_count_io_errors(struct cache_set *c, struct bio *bio,
 	struct bbio *b = container_of(bio, struct bbio, bio);
 	struct cache *ca = PTR_CACHE(c, &b->key, 0);
 
-	unsigned threshold = bio->bi_rw & REQ_WRITE
+	unsigned threshold = bio_data_dir(bio) == WRITE
 		? c->congested_write_threshold_us
 		: c->congested_read_threshold_us;
 
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 7a84f3b..11f6b5c 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -384,7 +384,7 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
 
 	if (mode == CACHE_MODE_NONE ||
 	    (mode == CACHE_MODE_WRITEAROUND &&
-	     (bio->bi_rw & REQ_WRITE)))
+	     bio_data_dir(bio) == WRITE))
 		goto skip;
 
 	if (bio->bi_iter.bi_sector & (c->sb.block_size - 1) ||
@@ -405,7 +405,7 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
 
 	if (!congested &&
 	    mode == CACHE_MODE_WRITEBACK &&
-	    (bio->bi_rw & REQ_WRITE) &&
+	    bio_data_dir(bio) == WRITE &&
 	    (bio->bi_rw & REQ_SYNC))
 		goto rescale;
 
@@ -658,7 +658,7 @@ static inline struct search *search_alloc(struct bio *bio,
 	s->cache_miss		= NULL;
 	s->d			= d;
 	s->recoverable		= 1;
-	s->write		= (bio->bi_rw & REQ_WRITE) != 0;
+	s->write		= bio_data_dir(bio) == WRITE;
 	s->read_dirty_data	= 0;
 	s->start_time		= jiffies;
 
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index ca7b4b6..650ba1c 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -828,7 +828,7 @@ void osd_req_write(struct osd_request *or,
 {
 	_osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, len);
 	WARN_ON(or->out.bio || or->out.total_bytes);
-	WARN_ON(0 == (bio->bi_rw & REQ_WRITE));
+	WARN_ON(bio_data_dir(bio) == READ);
 	or->out.bio = bio;
 	or->out.total_bytes = len;
 }
@@ -880,7 +880,7 @@ void osd_req_read(struct osd_request *or,
 {
 	_osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len);
 	WARN_ON(or->in.bio || or->in.total_bytes);
-	WARN_ON(bio->bi_rw & REQ_WRITE);
+	WARN_ON(bio_data_dir(bio) == WRITE);
 	or->in.bio = bio;
 	or->in.total_bytes = len;
 }
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f1262e6..8771f31 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -714,7 +714,7 @@ static void end_workqueue_bio(struct bio *bio)
 	fs_info = end_io_wq->info;
 	end_io_wq->error = bio->bi_error;
 
-	if (bio->bi_rw & REQ_WRITE) {
+	if (bio_data_dir(bio) == WRITE) {
 		if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) {
 			wq = fs_info->endio_meta_write_workers;
 			func = btrfs_endio_meta_write_helper;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 0dc9ec6..1075b05 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2410,7 +2410,7 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
 	int read_mode_flags = READ_SYNC;
 	int ret;
 
-	BUG_ON(failed_bio->bi_rw & REQ_WRITE);
+	BUG_ON(bio_data_dir(failed_bio) == WRITE);
 
 	ret = btrfs_get_io_failure_record(inode, start, end, &failrec);
 	if (ret)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index dd0b769..3ffb969 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7675,7 +7675,7 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
 	int read_mode;
 	int ret;
 
-	BUG_ON(failed_bio->bi_rw & REQ_WRITE);
+	BUG_ON(bio_data_dir(failed_bio) == WRITE);
 
 	ret = btrfs_get_io_failure_record(inode, start, end, &failrec);
 	if (ret)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 9c5bee9..4376ec6 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -599,7 +599,7 @@ static inline int op_to_data_dir(int op)
 		return WRITE;
 }
 
-#define rq_data_dir(rq)		((int)((rq)->cmd_flags & 1))
+#define rq_data_dir(rq)		(rq->op == REQ_OP_READ ? READ : WRITE)
 
 /*
  * Driver can handle struct request, if it either has an old style
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ac1fd9b..66dd4b91 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2397,7 +2397,7 @@ extern int is_bad_inode(struct inode *);
 /*
  * return data direction, READ or WRITE
  */
-#define bio_data_dir(bio)	((bio)->bi_rw & 1)
+#define bio_data_dir(bio)	((bio)->bi_op == REQ_OP_READ ? READ : WRITE)
 
 extern void check_disk_size_change(struct gendisk *disk,
 				   struct block_device *bdev);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 29/32] block/drivers: rm request cmd_flags REQ_OP use
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

With this patch the request struct code no longer uses the
cmd_flags field for REQ_OP operations.

---
 block/blk-core.c                  | 17 +++++++++--------
 block/blk-merge.c                 | 10 ++++++----
 block/blk-mq.c                    | 10 +++++-----
 block/cfq-iosched.c               |  4 ++--
 block/elevator.c                  |  8 ++++----
 drivers/block/loop.c              |  2 +-
 drivers/block/mtip32xx/mtip32xx.c |  2 +-
 drivers/block/nbd.c               |  2 +-
 drivers/block/nvme-core.c         |  6 +++---
 drivers/block/rbd.c               |  2 +-
 drivers/block/skd_main.c          | 11 ++++-------
 drivers/block/xen-blkfront.c      |  8 +++++---
 drivers/md/dm.c                   |  2 +-
 drivers/mmc/card/block.c          |  7 +++----
 drivers/mmc/card/queue.c          |  6 ++----
 drivers/mmc/card/queue.h          |  5 ++++-
 drivers/mtd/mtd_blkdevs.c         |  2 +-
 drivers/scsi/sd.c                 | 22 ++++++++++++++--------
 include/linux/blkdev.h            | 26 +++++++++++++-------------
 include/linux/elevator.h          |  4 ++--
 20 files changed, 82 insertions(+), 74 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index e625516..deb8bfd 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -889,10 +889,10 @@ static void __freed_request(struct request_list *rl, int sync)
  * A request has just been released.  Account for it, update the full and
  * congestion status, wake up any waiters.   Called under q->queue_lock.
  */
-static void freed_request(struct request_list *rl, unsigned int flags)
+static void freed_request(struct request_list *rl, int op, unsigned int flags)
 {
 	struct request_queue *q = rl->q;
-	int sync = rw_is_sync(flags);
+	int sync = rw_is_sync(op, flags);
 
 	q->nr_rqs[sync]--;
 	rl->count[sync]--;
@@ -1005,13 +1005,13 @@ static struct request *__get_request(struct request_list *rl, int op,
 	struct elevator_type *et = q->elevator->type;
 	struct io_context *ioc = rq_ioc(bio);
 	struct io_cq *icq = NULL;
-	const bool is_sync = rw_is_sync(op | op_flags) != 0;
+	const bool is_sync = rw_is_sync(op, op_flags) != 0;
 	int may_queue;
 
 	if (unlikely(blk_queue_dying(q)))
 		return ERR_PTR(-ENODEV);
 
-	may_queue = elv_may_queue(q, op | op_flags);
+	may_queue = elv_may_queue(q, op, op_flags);
 	if (may_queue == ELV_MQUEUE_NO)
 		goto rq_starved;
 
@@ -1141,7 +1141,7 @@ fail_alloc:
 	 * queue, but this is pretty rare.
 	 */
 	spin_lock_irq(q->queue_lock);
-	freed_request(rl, op | op_flags);
+	freed_request(rl, op, op_flags);
 
 	/*
 	 * in the very unlikely event that allocation failed and no
@@ -1175,7 +1175,7 @@ static struct request *get_request(struct request_queue *q, int op,
 				   int op_flags, struct bio *bio,
 				   gfp_t gfp_mask)
 {
-	const bool is_sync = rw_is_sync(op | op_flags) != 0;
+	const bool is_sync = rw_is_sync(op, op_flags) != 0;
 	DEFINE_WAIT(wait);
 	struct request_list *rl;
 	struct request *rq;
@@ -1424,13 +1424,14 @@ void __blk_put_request(struct request_queue *q, struct request *req)
 	 */
 	if (req->cmd_flags & REQ_ALLOCED) {
 		unsigned int flags = req->cmd_flags;
+		int op = req->op;
 		struct request_list *rl = blk_rq_rl(req);
 
 		BUG_ON(!list_empty(&req->queuelist));
 		BUG_ON(ELV_ON_HASH(req));
 
 		blk_free_request(rl, req);
-		freed_request(rl, flags);
+		freed_request(rl, op, flags);
 		blk_put_rl(rl);
 	}
 }
@@ -2054,7 +2055,7 @@ int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 	if (!rq_mergeable(rq))
 		return 0;
 
-	if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->cmd_flags)) {
+	if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->op)) {
 		printk(KERN_ERR "%s: over max size limit.\n", __func__);
 		return -EIO;
 	}
diff --git a/block/blk-merge.c b/block/blk-merge.c
index fe00d94..ec42c7e 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -582,7 +582,8 @@ static int attempt_merge(struct request_queue *q, struct request *req,
 	if (!rq_mergeable(req) || !rq_mergeable(next))
 		return 0;
 
-	if (!blk_check_merge_flags(req->cmd_flags, next->cmd_flags))
+	if (!blk_check_merge_flags(req->cmd_flags, req->op, next->cmd_flags,
+				   next->op))
 		return 0;
 
 	/*
@@ -596,7 +597,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
 	    || req_no_special_merge(next))
 		return 0;
 
-	if (req->cmd_flags & REQ_WRITE_SAME &&
+	if (req->op == REQ_OP_WRITE_SAME &&
 	    !blk_write_same_mergeable(req->bio, next->bio))
 		return 0;
 
@@ -684,7 +685,8 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 	if (!rq_mergeable(rq) || !bio_mergeable(bio))
 		return false;
 
-	if (!blk_check_merge_flags(rq->cmd_flags, bio->bi_rw))
+	if (!blk_check_merge_flags(rq->cmd_flags, rq->op, bio->bi_rw,
+				   bio->bi_op))
 		return false;
 
 	/* different data direction or already started, don't merge */
@@ -700,7 +702,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 		return false;
 
 	/* must be using the same buffer */
-	if (rq->cmd_flags & REQ_WRITE_SAME &&
+	if (rq->op == REQ_OP_WRITE_SAME &&
 	    !blk_write_same_mergeable(rq->bio, bio))
 		return false;
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index d57a581..b7352ad 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -187,7 +187,7 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
 	rq->q = q;
 	rq->mq_ctx = ctx;
 	rq->op = op;
-	rq->cmd_flags |= op | op_flags;
+	rq->cmd_flags |= op_flags;
 	/* do not touch atomic flags, it needs atomic ops against the timer */
 	rq->cpu = -1;
 	INIT_HLIST_NODE(&rq->hash);
@@ -222,7 +222,7 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
 	rq->end_io_data = NULL;
 	rq->next_rq = NULL;
 
-	ctx->rq_dispatched[rw_is_sync(op | op_flags)]++;
+	ctx->rq_dispatched[rw_is_sync(op, op_flags)]++;
 }
 
 static struct request *
@@ -1187,7 +1187,7 @@ static struct request *blk_mq_map_request(struct request_queue *q,
 	ctx = blk_mq_get_ctx(q);
 	hctx = q->mq_ops->map_queue(q, ctx->cpu);
 
-	if (rw_is_sync(bio->bi_rw))
+	if (rw_is_sync(bio->bi_op, bio->bi_rw))
 		op_flags |= REQ_SYNC;
 
 	trace_block_getrq(q, bio, op);
@@ -1253,7 +1253,7 @@ static int blk_mq_direct_issue_request(struct request *rq)
  */
 static void blk_mq_make_request(struct request_queue *q, struct bio *bio)
 {
-	const int is_sync = rw_is_sync(bio->bi_rw);
+	const int is_sync = rw_is_sync(bio->bi_op, bio->bi_rw);
 	const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA);
 	struct blk_map_ctx data;
 	struct request *rq;
@@ -1341,7 +1341,7 @@ run_queue:
  */
 static void blk_sq_make_request(struct request_queue *q, struct bio *bio)
 {
-	const int is_sync = rw_is_sync(bio->bi_rw);
+	const int is_sync = rw_is_sync(bio->bi_op, bio->bi_rw);
 	const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA);
 	struct blk_plug *plug;
 	unsigned int request_count = 0;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index dbc3da4..fc964e1 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -4271,7 +4271,7 @@ static inline int __cfq_may_queue(struct cfq_queue *cfqq)
 	return ELV_MQUEUE_MAY;
 }
 
-static int cfq_may_queue(struct request_queue *q, int rw)
+static int cfq_may_queue(struct request_queue *q, int op, int op_flags)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 	struct task_struct *tsk = current;
@@ -4288,7 +4288,7 @@ static int cfq_may_queue(struct request_queue *q, int rw)
 	if (!cic)
 		return ELV_MQUEUE_MAY;
 
-	cfqq = cic_to_cfqq(cic, rw_is_sync(rw));
+	cfqq = cic_to_cfqq(cic, rw_is_sync(op, op_flags));
 	if (cfqq) {
 		cfq_init_prio_data(cfqq, cic);
 
diff --git a/block/elevator.c b/block/elevator.c
index 84d6394..1624d48 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -366,8 +366,8 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
 	list_for_each_prev(entry, &q->queue_head) {
 		struct request *pos = list_entry_rq(entry);
 
-		if ((rq->cmd_flags & REQ_DISCARD) !=
-		    (pos->cmd_flags & REQ_DISCARD))
+		if ((rq->op == REQ_OP_DISCARD) !=
+		    (pos->op == REQ_OP_DISCARD))
 			break;
 		if (rq_data_dir(rq) != rq_data_dir(pos))
 			break;
@@ -717,12 +717,12 @@ void elv_put_request(struct request_queue *q, struct request *rq)
 		e->type->ops.elevator_put_req_fn(rq);
 }
 
-int elv_may_queue(struct request_queue *q, int rw)
+int elv_may_queue(struct request_queue *q, int op, int op_flags)
 {
 	struct elevator_queue *e = q->elevator;
 
 	if (e->type->ops.elevator_may_queue_fn)
-		return e->type->ops.elevator_may_queue_fn(q, rw);
+		return e->type->ops.elevator_may_queue_fn(q, op, op_flags);
 
 	return ELV_MQUEUE_MAY;
 }
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index e214936..bddffed 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -399,7 +399,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
 	if (rq_data_dir(rq) == WRITE) {
 		if (rq->cmd_flags & REQ_FLUSH)
 			ret = lo_req_flush(lo, rq);
-		else if (rq->cmd_flags & REQ_DISCARD)
+		else if (rq->op == REQ_OP_DISCARD)
 			ret = lo_discard(lo, rq, pos);
 		else if (lo->transfer)
 			ret = lo_write_transfer(lo, rq, pos);
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index f504232..a3f1b7a 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3677,7 +3677,7 @@ static int mtip_submit_request(struct blk_mq_hw_ctx *hctx, struct request *rq)
 			return -ENXIO;
 	}
 
-	if (rq->cmd_flags & REQ_DISCARD) {
+	if (rq->op == REQ_OP_DISCARD) {
 		int err;
 
 		err = mtip_send_trim(dd, blk_rq_pos(rq), blk_rq_sectors(rq));
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 1b87623..2d24c1a 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -242,7 +242,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
 
 	if (req->cmd_type == REQ_TYPE_DRV_PRIV)
 		type = NBD_CMD_DISC;
-	else if (req->cmd_flags & REQ_DISCARD)
+	else if (req->op == REQ_OP_DISCARD)
 		type = NBD_CMD_TRIM;
 	else if (req->cmd_flags & REQ_FLUSH)
 		type = NBD_CMD_FLUSH;
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index ccc0c1f..aeba59e 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -440,7 +440,7 @@ __nvme_alloc_iod(unsigned nseg, unsigned bytes, struct nvme_dev *dev,
 static struct nvme_iod *nvme_alloc_iod(struct request *rq, struct nvme_dev *dev,
 			               gfp_t gfp)
 {
-	unsigned size = !(rq->cmd_flags & REQ_DISCARD) ? blk_rq_bytes(rq) :
+	unsigned size = !(rq->op == REQ_OP_DISCARD) ? blk_rq_bytes(rq) :
                                                 sizeof(struct nvme_dsm_range);
 	struct nvme_iod *iod;
 
@@ -877,7 +877,7 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
 	if (!iod)
 		return BLK_MQ_RQ_QUEUE_BUSY;
 
-	if (req->cmd_flags & REQ_DISCARD) {
+	if (req->op == REQ_OP_DISCARD) {
 		void *range;
 		/*
 		 * We reuse the small pool to allocate the 16-byte range here
@@ -927,7 +927,7 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
 	spin_lock_irq(&nvmeq->q_lock);
 	if (req->cmd_type == REQ_TYPE_DRV_PRIV)
 		nvme_submit_priv(nvmeq, req, iod);
-	else if (req->cmd_flags & REQ_DISCARD)
+	else if (req->op == REQ_OP_DISCARD)
 		nvme_submit_discard(nvmeq, ns, req, iod);
 	else if (req->cmd_flags & REQ_FLUSH)
 		nvme_submit_flush(nvmeq, ns, req->tag);
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 39104ca..5ee8abe 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3375,7 +3375,7 @@ static void rbd_queue_workfn(struct work_struct *work)
 		goto err;
 	}
 
-	if (rq->cmd_flags & REQ_DISCARD)
+	if (rq->op == REQ_OP_DISCARD)
 		op_type = OBJ_OP_DISCARD;
 	else if (rq_data_dir(rq) == WRITE)
 		op_type = OBJ_OP_WRITE;
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c
index 586f916..f89a0c8 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -576,7 +576,6 @@ static void skd_request_fn(struct request_queue *q)
 	struct request *req = NULL;
 	struct skd_scsi_request *scsi_req;
 	struct page *page;
-	unsigned long io_flags;
 	int error;
 	u32 lba;
 	u32 count;
@@ -624,12 +623,11 @@ static void skd_request_fn(struct request_queue *q)
 		lba = (u32)blk_rq_pos(req);
 		count = blk_rq_sectors(req);
 		data_dir = rq_data_dir(req);
-		io_flags = req->cmd_flags;
 
-		if (io_flags & REQ_FLUSH)
+		if (req->cmd_flags & REQ_FLUSH)
 			flush++;
 
-		if (io_flags & REQ_FUA)
+		if (req->cmd_flags & REQ_FUA)
 			fua++;
 
 		pr_debug("%s:%s:%d new req=%p lba=%u(0x%x) "
@@ -735,7 +733,7 @@ static void skd_request_fn(struct request_queue *q)
 		else
 			skreq->sg_data_dir = SKD_DATA_DIR_HOST_TO_CARD;
 
-		if (io_flags & REQ_DISCARD) {
+		if (req->op == REQ_OP_DISCARD) {
 			page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
 			if (!page) {
 				pr_err("request_fn:Page allocation failed.\n");
@@ -852,9 +850,8 @@ static void skd_end_request(struct skd_device *skdev,
 			    struct skd_request_context *skreq, int error)
 {
 	struct request *req = skreq->req;
-	unsigned int io_flags = req->cmd_flags;
 
-	if ((io_flags & REQ_DISCARD) &&
+	if ((req->op == REQ_OP_DISCARD) &&
 		(skreq->discard_page == 1)) {
 		pr_debug("%s:%s:%d, free the page!",
 			 skdev->name, __func__, __LINE__);
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index ec76178..91eccd1 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -452,7 +452,8 @@ static int blkif_queue_request(struct request *req)
 	id = get_id_from_freelist(info);
 	info->shadow[id].request = req;
 
-	if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE))) {
+	if (unlikely(req->op == REQ_OP_DISCARD ||
+		     req->cmd_flags & REQ_SECURE)) {
 		ring_req->operation = BLKIF_OP_DISCARD;
 		ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
 		ring_req->u.discard.id = id;
@@ -1533,8 +1534,9 @@ static int blkif_recover(struct blkfront_info *info)
 		/*
 		 * Get the bios in the request so we can re-queue them.
 		 */
-		if (copy[i].request->cmd_flags &
-		    (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
+		if (copy[i].request->cmd_flags & REQ_FLUSH ||
+		    copy[i].request->op == REQ_OP_DISCARD ||
+		    copy[i].request->cmd_flags & (REQ_FUA | REQ_SECURE)) {
 			/*
 			 * Flush operations don't contain bios, so
 			 * we need to requeue the whole request
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index ea4bc70..e03ca09 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1245,7 +1245,7 @@ static void dm_done(struct request *clone, int error, bool mapped)
 			r = rq_end_io(tio->ti, clone, error, &tio->info);
 	}
 
-	if (unlikely(r == -EREMOTEIO && (clone->cmd_flags & REQ_WRITE_SAME) &&
+	if (unlikely(r == -EREMOTEIO && (clone->op == REQ_OP_WRITE_SAME) &&
 		     !clone->q->limits.max_write_same_sectors))
 		disable_write_same(tio->md);
 
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c742cfd..e99361f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1613,8 +1613,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
 		    !IS_ALIGNED(blk_rq_sectors(next), 8))
 			break;
 
-		if (next->cmd_flags & REQ_DISCARD ||
-		    next->cmd_flags & REQ_FLUSH)
+		if (next->op == REQ_OP_DISCARD || next->cmd_flags & REQ_FLUSH)
 			break;
 
 		if (rq_data_dir(cur) != rq_data_dir(next))
@@ -2055,7 +2054,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 	}
 
 	mq->flags &= ~MMC_QUEUE_NEW_REQUEST;
-	if (cmd_flags & REQ_DISCARD) {
+	if (req && req->op == REQ_OP_DISCARD) {
 		/* complete ongoing async transfer before issuing discard */
 		if (card->host->areq)
 			mmc_blk_issue_rw_rq(mq, NULL);
@@ -2079,7 +2078,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
 out:
 	if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) ||
-	     (cmd_flags & MMC_REQ_SPECIAL_MASK))
+	    mmc_req_is_special(req))
 		/*
 		 * Release host when there are no more requests
 		 * and after special request(discard, flush) is done.
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 6f4323c..9fb8d21 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -33,7 +33,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
 	/*
 	 * We only like normal block requests and discards.
 	 */
-	if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) {
+	if (req->cmd_type != REQ_TYPE_FS && req->op != REQ_OP_DISCARD) {
 		blk_dump_rq_flags(req, "MMC bad request");
 		return BLKPREP_KILL;
 	}
@@ -56,7 +56,6 @@ static int mmc_queue_thread(void *d)
 	down(&mq->thread_sem);
 	do {
 		struct request *req = NULL;
-		unsigned int cmd_flags = 0;
 
 		spin_lock_irq(q->queue_lock);
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -66,7 +65,6 @@ static int mmc_queue_thread(void *d)
 
 		if (req || mq->mqrq_prev->req) {
 			set_current_state(TASK_RUNNING);
-			cmd_flags = req ? req->cmd_flags : 0;
 			mq->issue_fn(mq, req);
 			cond_resched();
 			if (mq->flags & MMC_QUEUE_NEW_REQUEST) {
@@ -81,7 +79,7 @@ static int mmc_queue_thread(void *d)
 			 * has been finished. Do not assign it to previous
 			 * request.
 			 */
-			if (cmd_flags & MMC_REQ_SPECIAL_MASK)
+			if (mmc_req_is_special(req))
 				mq->mqrq_cur->req = NULL;
 
 			mq->mqrq_prev->brq.mrq.data = NULL;
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 36cddab..f166e5b 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -1,7 +1,10 @@
 #ifndef MMC_QUEUE_H
 #define MMC_QUEUE_H
 
-#define MMC_REQ_SPECIAL_MASK	(REQ_DISCARD | REQ_FLUSH)
+static inline bool mmc_req_is_special(struct request *req)
+{
+	return req && (req->cmd_flags & REQ_FLUSH || req->op == REQ_OP_DISCARD);
+}
 
 struct request;
 struct task_struct;
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 44dc965..49017f0 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -94,7 +94,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 	    get_capacity(req->rq_disk))
 		return -EIO;
 
-	if (req->cmd_flags & REQ_DISCARD)
+	if (req->op == REQ_OP_DISCARD)
 		return tr->discard(dev, block, nsect);
 
 	if (rq_data_dir(req) == READ) {
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3f37022..353508c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1122,21 +1122,27 @@ static int sd_init_command(struct scsi_cmnd *cmd)
 {
 	struct request *rq = cmd->request;
 
-	if (rq->cmd_flags & REQ_DISCARD)
+	switch (rq->op) {
+	case REQ_OP_DISCARD:
 		return sd_setup_discard_cmnd(cmd);
-	else if (rq->cmd_flags & REQ_WRITE_SAME)
+	case REQ_OP_WRITE_SAME:
 		return sd_setup_write_same_cmnd(cmd);
-	else if (rq->cmd_flags & REQ_FLUSH)
-		return sd_setup_flush_cmnd(cmd);
-	else
-		return sd_setup_read_write_cmnd(cmd);
+	case REQ_OP_READ:
+	case REQ_OP_WRITE:
+		if (rq->cmd_flags & REQ_FLUSH)
+			return sd_setup_flush_cmnd(cmd);
+		else
+			return sd_setup_read_write_cmnd(cmd);
+	default:
+		BUG();
+	}
 }
 
 static void sd_uninit_command(struct scsi_cmnd *SCpnt)
 {
 	struct request *rq = SCpnt->request;
 
-	if (rq->cmd_flags & REQ_DISCARD)
+	if (rq->op == REQ_OP_DISCARD)
 		__free_page(rq->completion_data);
 
 	if (SCpnt->cmnd != rq->cmd) {
@@ -1658,7 +1664,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
 	unsigned char op = SCpnt->cmnd[0];
 	unsigned char unmap = SCpnt->cmnd[1] & 8;
 
-	if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) {
+	if (req->op == REQ_OP_DISCARD || req->op == REQ_OP_WRITE_SAME) {
 		if (!result) {
 			good_bytes = blk_rq_bytes(req);
 			scsi_set_resid(SCpnt, 0);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4376ec6..d930191 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -618,14 +618,14 @@ static inline unsigned int blk_queue_cluster(struct request_queue *q)
 /*
  * We regard a request as sync, if either a read or a sync write
  */
-static inline bool rw_is_sync(unsigned int rw_flags)
+static inline bool rw_is_sync(int op, unsigned int rw_flags)
 {
-	return !(rw_flags & REQ_WRITE) || (rw_flags & REQ_SYNC);
+	return (op_to_data_dir(op) == READ) || (rw_flags & REQ_SYNC);
 }
 
 static inline bool rq_is_sync(struct request *rq)
 {
-	return rw_is_sync(rq->cmd_flags);
+	return rw_is_sync(rq->op, rq->cmd_flags);
 }
 
 static inline bool blk_rl_full(struct request_list *rl, bool sync)
@@ -660,16 +660,16 @@ static inline bool rq_mergeable(struct request *rq)
 	return true;
 }
 
-static inline bool blk_check_merge_flags(unsigned int flags1,
-					 unsigned int flags2)
+static inline bool blk_check_merge_flags(unsigned int flags1, unsigned int op1,
+					 unsigned int flags2, unsigned int op2)
 {
-	if ((flags1 & REQ_DISCARD) != (flags2 & REQ_DISCARD))
+	if ((op1 == REQ_OP_DISCARD) != (op2 == REQ_OP_DISCARD))
 		return false;
 
 	if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE))
 		return false;
 
-	if ((flags1 & REQ_WRITE_SAME) != (flags2 & REQ_WRITE_SAME))
+	if ((op1 == REQ_OP_WRITE_SAME) != (op2 == REQ_OP_WRITE_SAME))
 		return false;
 
 	return true;
@@ -863,12 +863,12 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
 }
 
 static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
-						     unsigned int cmd_flags)
+						     int op)
 {
-	if (unlikely(cmd_flags & REQ_DISCARD))
+	if (unlikely(op == REQ_OP_DISCARD))
 		return min(q->limits.max_discard_sectors, UINT_MAX >> 9);
 
-	if (unlikely(cmd_flags & REQ_WRITE_SAME))
+	if (unlikely(op == REQ_OP_WRITE_SAME))
 		return q->limits.max_write_same_sectors;
 
 	return q->limits.max_sectors;
@@ -895,11 +895,11 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq)
 	if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC))
 		return q->limits.max_hw_sectors;
 
-	if (!q->limits.chunk_sectors || (rq->cmd_flags & REQ_DISCARD))
-		return blk_queue_get_max_sectors(q, rq->cmd_flags);
+	if (!q->limits.chunk_sectors || (rq->op == REQ_OP_DISCARD))
+		return blk_queue_get_max_sectors(q, rq->op);
 
 	return min(blk_max_size_offset(q, blk_rq_pos(rq)),
-			blk_queue_get_max_sectors(q, rq->cmd_flags));
+			blk_queue_get_max_sectors(q, rq->op));
 }
 
 static inline unsigned int blk_rq_count_bios(struct request *rq)
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 638b324..953d286 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -26,7 +26,7 @@ typedef int (elevator_dispatch_fn) (struct request_queue *, int);
 typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
 typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
 typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
-typedef int (elevator_may_queue_fn) (struct request_queue *, int);
+typedef int (elevator_may_queue_fn) (struct request_queue *, int, int);
 
 typedef void (elevator_init_icq_fn) (struct io_cq *);
 typedef void (elevator_exit_icq_fn) (struct io_cq *);
@@ -134,7 +134,7 @@ extern struct request *elv_former_request(struct request_queue *, struct request
 extern struct request *elv_latter_request(struct request_queue *, struct request *);
 extern int elv_register_queue(struct request_queue *q);
 extern void elv_unregister_queue(struct request_queue *q);
-extern int elv_may_queue(struct request_queue *, int);
+extern int elv_may_queue(struct request_queue *, int, int);
 extern void elv_completed_request(struct request_queue *, struct request *);
 extern int elv_set_request(struct request_queue *q, struct request *rq,
 			   struct bio *bio, gfp_t gfp_mask);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 30/32] drbd: don't use bi_rw for operations
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

This removes drbd's bi_rw use for operations read, write,
discard, write same, etc (REQ_OPs).

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/block/drbd/drbd_actlog.c   |  2 +-
 drivers/block/drbd/drbd_bitmap.c   |  1 -
 drivers/block/drbd/drbd_main.c     | 15 ++++++++-------
 drivers/block/drbd/drbd_receiver.c | 22 ++++++++--------------
 drivers/block/drbd/drbd_worker.c   |  4 ++--
 5 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index ed2eafe..fc96a3c 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -159,7 +159,7 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
 		goto out;
 	bio->bi_private = device;
 	bio->bi_end_io = drbd_md_endio;
-	bio->bi_rw = op | op_flags;
+	bio->bi_rw = op_flags;
 	bio->bi_op = op;
 
 	if (op != REQ_OP_WRITE && device->state.disk == D_DISKLESS && device->ldev == NULL)
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 2ff407a..173a3d6 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -1022,7 +1022,6 @@ static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_ho
 
 	if (drbd_insert_fault(device, (rw == REQ_OP_WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
 		bio->bi_op = rw;
-		bio->bi_rw |= rw;
 		bio_io_error(bio);
 	} else {
 		submit_bio(rw, 0, bio);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9eb8039..d74178c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1602,15 +1602,16 @@ static int _drbd_send_zc_ee(struct drbd_peer_device *peer_device,
 	return 0;
 }
 
-static u32 bio_flags_to_wire(struct drbd_connection *connection, unsigned long bi_rw)
+static u32 bio_flags_to_wire(struct drbd_connection *connection,
+			     struct bio *bio)
 {
 	if (connection->agreed_pro_version >= 95)
-		return  (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
-			(bi_rw & REQ_FUA ? DP_FUA : 0) |
-			(bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
-			(bi_rw & REQ_DISCARD ? DP_DISCARD : 0);
+		return  (bio->bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
+			(bio->bi_rw & REQ_FUA ? DP_FUA : 0) |
+			(bio->bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
+			(bio->bi_op == REQ_OP_DISCARD ? DP_DISCARD : 0);
 	else
-		return bi_rw & REQ_SYNC ? DP_RW_SYNC : 0;
+		return bio->bi_rw & REQ_SYNC ? DP_RW_SYNC : 0;
 }
 
 /* Used to send write or TRIM aka REQ_DISCARD requests
@@ -1635,7 +1636,7 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *
 	p->sector = cpu_to_be64(req->i.sector);
 	p->block_id = (unsigned long)req;
 	p->seq_num = cpu_to_be32(atomic_inc_return(&device->packet_seq));
-	dp_flags = bio_flags_to_wire(peer_device->connection, req->master_bio->bi_rw);
+	dp_flags = bio_flags_to_wire(peer_device->connection, req->master_bio);
 	if (device->state.conn >= C_SYNC_SOURCE &&
 	    device->state.conn <= C_PAUSED_SYNC_T)
 		dp_flags |= DP_MAY_SET_IN_SYNC;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 4e458bd..44193da 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1418,7 +1418,7 @@ next_bio:
 	/* > peer_req->i.sector, unless this is the first bio */
 	bio->bi_iter.bi_sector = sector;
 	bio->bi_bdev = device->ldev->backing_bdev;
-	bio->bi_rw = op | op_flags;
+	bio->bi_rw = op_flags;
 	bio->bi_op = op;
 	bio->bi_private = peer_req;
 	bio->bi_end_io = drbd_peer_request_endio;
@@ -1427,7 +1427,7 @@ next_bio:
 	bios = bio;
 	++n_bios;
 
-	if (op & REQ_OP_DISCARD) {
+	if (op == REQ_OP_DISCARD) {
 		bio->bi_iter.bi_size = data_size;
 		goto submit;
 	}
@@ -2132,8 +2132,7 @@ static unsigned long wire_flags_to_bio_flags(u32 dpf)
 {
 	return  (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
 		(dpf & DP_FUA ? REQ_FUA : 0) |
-		(dpf & DP_FLUSH ? REQ_FLUSH : 0) |
-		(dpf & DP_DISCARD ? REQ_DISCARD : 0);
+		(dpf & DP_FLUSH ? REQ_FLUSH : 0);
 }
 
 static unsigned long wire_flags_to_bio_op(u32 dpf)
@@ -2141,7 +2140,7 @@ static unsigned long wire_flags_to_bio_op(u32 dpf)
 	if (dpf & DP_DISCARD)
 		return REQ_OP_DISCARD;
 	else
-		return 0;
+		return REQ_OP_WRITE;;
 }
 
 static void fail_postponed_requests(struct drbd_device *device, sector_t sector,
@@ -2287,7 +2286,7 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
 	struct drbd_peer_request *peer_req;
 	struct p_data *p = pi->data;
 	u32 peer_seq = be32_to_cpu(p->seq_num);
-	int op = REQ_OP_WRITE, op_flags = 0;
+	int op, op_flags;
 	u32 dp_flags;
 	int err, tp;
 
@@ -2326,20 +2325,15 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
 	peer_req->flags |= EE_APPLICATION;
 
 	dp_flags = be32_to_cpu(p->dp_flags);
-	/*
-	 * Tmp compat. We OR it here because other code assumes both the
-	 * discard and write flags are set. In the next patches that
-	 * will be cleaned up.
-	 */
-	op |= wire_flags_to_bio_op(dp_flags);
-	op_flags |= wire_flags_to_bio_flags(dp_flags);
+	op = wire_flags_to_bio_op(dp_flags);
+	op_flags = wire_flags_to_bio_flags(dp_flags);
 	if (pi->cmd == P_TRIM) {
 		struct request_queue *q = bdev_get_queue(device->ldev->backing_bdev);
 		peer_req->flags |= EE_IS_TRIM;
 		if (!blk_queue_discard(q))
 			peer_req->flags |= EE_IS_TRIM_USE_ZEROOUT;
 		D_ASSERT(peer_device, peer_req->i.size > 0);
-		D_ASSERT(peer_device, op & REQ_OP_DISCARD);
+		D_ASSERT(peer_device, op == REQ_OP_DISCARD);
 		D_ASSERT(peer_device, peer_req->pages == NULL);
 	} else if (peer_req->pages == NULL) {
 		D_ASSERT(device, peer_req->i.size == 0);
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 23e5500..f1c63d2 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -175,7 +175,7 @@ void drbd_peer_request_endio(struct bio *bio)
 	struct drbd_peer_request *peer_req = bio->bi_private;
 	struct drbd_device *device = peer_req->peer_device->device;
 	int is_write = bio_data_dir(bio) == WRITE;
-	int is_discard = !!(bio->bi_rw & REQ_DISCARD);
+	int is_discard = (bio->bi_op == REQ_OP_DISCARD);
 
 	if (bio->bi_error && __ratelimit(&drbd_ratelimit_state))
 		drbd_warn(device, "%s: error=%d s=%llus\n",
@@ -243,7 +243,7 @@ void drbd_request_endio(struct bio *bio)
 
 	/* to avoid recursion in __req_mod */
 	if (unlikely(bio->bi_error)) {
-		if (bio->bi_rw & REQ_DISCARD)
+		if (bio->bi_op == REQ_OP_DISCARD)
 			what = (bio->bi_error == -EOPNOTSUPP)
 				? DISCARD_COMPLETED_NOTSUPP
 				: DISCARD_COMPLETED_WITH_ERROR;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 31/32] block/fs/driver: rm bio bi_rw REQ_OP use
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

With this patch we no longer use the bio->bi_rw field
for REQ_WRITE, REQ_DISCARD, REQ_WRITE_SAME, (REQ_OPs). bi_rw should
only set REQ_XYZ values and bi_op is for REQ_OPs.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 block/bio.c                                 | 15 +++------
 block/blk-core.c                            | 10 +++---
 block/blk-lib.c                             |  9 ++---
 block/blk-map.c                             |  4 +--
 block/blk-merge.c                           | 12 +++----
 drivers/block/brd.c                         |  2 +-
 drivers/block/pktcdvd.c                     |  2 --
 drivers/block/rsxx/dma.c                    |  2 +-
 drivers/block/xen-blkfront.c                |  5 +--
 drivers/block/zram/zram_drv.c               |  2 +-
 drivers/md/bcache/journal.c                 |  6 ++--
 drivers/md/bcache/movinggc.c                |  2 +-
 drivers/md/bcache/request.c                 | 11 +++---
 drivers/md/bcache/writeback.c               |  4 +--
 drivers/md/dm-cache-target.c                | 10 +++---
 drivers/md/dm-crypt.c                       |  2 +-
 drivers/md/dm-io.c                          | 12 +++----
 drivers/md/dm-kcopyd.c                      |  2 +-
 drivers/md/dm-log-writes.c                  |  2 +-
 drivers/md/dm-raid1.c                       | 10 +++---
 drivers/md/dm-region-hash.c                 |  4 +--
 drivers/md/dm-stripe.c                      |  4 +--
 drivers/md/dm-thin.c                        | 15 +++++----
 drivers/md/dm.c                             |  6 ++--
 drivers/md/linear.c                         |  2 +-
 drivers/md/raid0.c                          |  2 +-
 drivers/md/raid1.c                          | 25 ++++++--------
 drivers/md/raid10.c                         | 34 +++++++++----------
 drivers/md/raid5.c                          | 20 ++++-------
 drivers/scsi/osd/osd_initiator.c            |  4 ---
 drivers/staging/lustre/lustre/llite/lloop.c |  8 ++---
 drivers/target/target_core_pscsi.c          |  4 +--
 fs/btrfs/volumes.c                          |  6 ++--
 fs/exofs/ore.c                              |  1 -
 include/linux/bio.h                         | 15 ++++++---
 include/linux/blk_types.h                   | 13 +++-----
 include/linux/blktrace_api.h                |  2 +-
 include/linux/fs.h                          | 29 ++++++++++------
 include/trace/events/bcache.h               | 12 ++++---
 include/trace/events/block.h                | 31 +++++++++++------
 kernel/trace/blktrace.c                     | 52 ++++++++++++++++-------------
 41 files changed, 204 insertions(+), 209 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 1cf8428..064a858 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -669,10 +669,10 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
 	bio->bi_iter.bi_sector	= bio_src->bi_iter.bi_sector;
 	bio->bi_iter.bi_size	= bio_src->bi_iter.bi_size;
 
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		goto integrity_clone;
 
-	if (bio->bi_rw & REQ_WRITE_SAME) {
+	if (bio->bi_op == REQ_OP_WRITE_SAME) {
 		bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
 		goto integrity_clone;
 	}
@@ -1170,10 +1170,8 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
 	if (!bio)
 		goto out_bmd;
 
-	if (iter->type & WRITE) {
-		bio->bi_rw |= REQ_WRITE;
+	if (iter->type & WRITE)
 		bio->bi_op = REQ_OP_WRITE;
-	}
 
 	ret = 0;
 
@@ -1342,10 +1340,8 @@ struct bio *bio_map_user_iov(struct request_queue *q,
 	/*
 	 * set data direction, and check if mapped pages need bouncing
 	 */
-	if (iter->type & WRITE) {
-		bio->bi_rw |= REQ_WRITE;
+	if (iter->type & WRITE)
 		bio->bi_op = REQ_OP_WRITE;
-	}
 
 	bio_set_flag(bio, BIO_USER_MAPPED);
 
@@ -1538,7 +1534,6 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
 		bio->bi_private = data;
 	} else {
 		bio->bi_end_io = bio_copy_kern_endio;
-		bio->bi_rw |= REQ_WRITE;
 		bio->bi_op = REQ_OP_WRITE;
 	}
 
@@ -1798,7 +1793,7 @@ struct bio *bio_split(struct bio *bio, int sectors,
 	 * Discards need a mutable bio_vec to accommodate the payload
 	 * required by the DSM TRIM and UNMAP commands.
 	 */
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		split = bio_clone_bioset(bio, gfp, bs);
 	else
 		split = bio_clone_fast(bio, gfp, bs);
diff --git a/block/blk-core.c b/block/blk-core.c
index deb8bfd..c270a4a 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1873,14 +1873,14 @@ generic_make_request_checks(struct bio *bio)
 		}
 	}
 
-	if ((bio->bi_rw & REQ_DISCARD) &&
+	if ((bio->bi_op == REQ_OP_DISCARD) &&
 	    (!blk_queue_discard(q) ||
 	     ((bio->bi_rw & REQ_SECURE) && !blk_queue_secdiscard(q)))) {
 		err = -EOPNOTSUPP;
 		goto end_io;
 	}
 
-	if (bio->bi_rw & REQ_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
+	if (bio->bi_op == REQ_OP_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
 		err = -EOPNOTSUPP;
 		goto end_io;
 	}
@@ -1992,7 +1992,7 @@ EXPORT_SYMBOL(generic_make_request);
  */
 void submit_bio(int op, int flags, struct bio *bio)
 {
-	bio->bi_rw |= op | flags;
+	bio->bi_rw |= flags;
 	bio->bi_op = op;
 
 	/*
@@ -2002,7 +2002,7 @@ void submit_bio(int op, int flags, struct bio *bio)
 	if (bio_has_data(bio)) {
 		unsigned int count;
 
-		if (unlikely(op == REQ_WRITE_SAME))
+		if (unlikely(op == REQ_OP_WRITE_SAME))
 			count = bdev_logical_block_size(bio->bi_bdev) >> 9;
 		else
 			count = bio_sectors(bio);
@@ -2873,8 +2873,6 @@ EXPORT_SYMBOL_GPL(__blk_end_request_err);
 void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 		     struct bio *bio)
 {
-	/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw */
-	rq->cmd_flags |= bio->bi_rw & REQ_WRITE;
 	rq->op = bio->bi_op;
 
 	if (bio_has_data(bio))
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 49786b0..77bba0a 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -43,7 +43,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 	DECLARE_COMPLETION_ONSTACK(wait);
 	struct request_queue *q = bdev_get_queue(bdev);
 	int op = REQ_OP_DISCARD;
-	int op_flags = REQ_WRITE;
+	int op_flags = 0;
 	unsigned int granularity;
 	int alignment;
 	struct bio_batch bb;
@@ -189,12 +189,7 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
 		}
 
 		atomic_inc(&bb.done);
-		/*
-		 * REQ_WRITE being passed as a flag is temp until
-		 * code that assumes REQ_WRITE is set for WRITE_SAME
-		 * is converted.
-		 */
-		submit_bio(REQ_OP_WRITE_SAME, REQ_WRITE, bio);
+		submit_bio(REQ_OP_WRITE_SAME, 0, bio);
 	}
 
 	/* Wait for bios in-flight */
diff --git a/block/blk-map.c b/block/blk-map.c
index 4a91dc4..9021a8f 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -223,10 +223,8 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
 	if (IS_ERR(bio))
 		return PTR_ERR(bio);
 
-	if (!reading) {
-		bio->bi_rw |= REQ_WRITE;
+	if (!reading)
 		bio->bi_op = REQ_OP_WRITE;
-	}
 
 	if (do_copy)
 		rq->cmd_flags |= REQ_COPY_USER;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index ec42c7e..7550411 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -116,9 +116,9 @@ void blk_queue_split(struct request_queue *q, struct bio **bio,
 {
 	struct bio *split;
 
-	if ((*bio)->bi_rw & REQ_DISCARD)
+	if ((*bio)->bi_op == REQ_OP_DISCARD)
 		split = blk_bio_discard_split(q, *bio, bs);
-	else if ((*bio)->bi_rw & REQ_WRITE_SAME)
+	else if ((*bio)->bi_op == REQ_OP_WRITE_SAME)
 		split = blk_bio_write_same_split(q, *bio, bs);
 	else
 		split = blk_bio_segment_split(q, *bio, q->bio_split);
@@ -148,10 +148,10 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
 	 * This should probably be returning 0, but blk_add_request_payload()
 	 * (Christoph!!!!)
 	 */
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		return 1;
 
-	if (bio->bi_rw & REQ_WRITE_SAME)
+	if (bio->bi_op == REQ_OP_WRITE_SAME)
 		return 1;
 
 	fbio = bio;
@@ -324,7 +324,7 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
 	nsegs = 0;
 	cluster = blk_queue_cluster(q);
 
-	if (bio->bi_rw & REQ_DISCARD) {
+	if (bio->bi_op == REQ_OP_DISCARD) {
 		/*
 		 * This is a hack - drivers should be neither modifying the
 		 * biovec, nor relying on bi_vcnt - but because of
@@ -339,7 +339,7 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
 		return 0;
 	}
 
-	if (bio->bi_rw & REQ_WRITE_SAME) {
+	if (bio->bi_op == REQ_OP_WRITE_SAME) {
 single_segment:
 		*sg = sglist;
 		bvec = bio_iovec(bio);
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index b9794ae..657e4c5 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -336,7 +336,7 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
 	if (bio_end_sector(bio) > get_capacity(bdev->bd_disk))
 		goto io_error;
 
-	if (unlikely(bio->bi_rw & REQ_DISCARD)) {
+	if (unlikely(bio->bi_op == REQ_OP_DISCARD)) {
 		discard_from_brd(brd, sector, bio->bi_iter.bi_size);
 		goto out;
 	}
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index bbb7a45..aeb296f 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1074,7 +1074,6 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
 			BUG();
 
 		atomic_inc(&pkt->io_wait);
-		bio->bi_rw = READ;
 		bio->bi_op = REQ_OP_READ;
 		pkt_queue_bio(pd, bio);
 		frames_read++;
@@ -1337,7 +1336,6 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
 
 	/* Start the write request */
 	atomic_set(&pkt->io_wait, 1);
-	pkt->w_bio->bi_rw = WRITE;
 	pkt->w_bio->bi_op = REQ_OP_WRITE;
 	pkt_queue_bio(pd, pkt->w_bio);
 }
diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c
index cf8cd29..dfc189e 100644
--- a/drivers/block/rsxx/dma.c
+++ b/drivers/block/rsxx/dma.c
@@ -705,7 +705,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
 		dma_cnt[i] = 0;
 	}
 
-	if (bio->bi_rw & REQ_DISCARD) {
+	if (bio->bi_op == REQ_OP_DISCARD) {
 		bv_len = bio->bi_iter.bi_size;
 
 		while (bv_len > 0) {
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 91eccd1..09ea7cd 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1593,7 +1593,8 @@ static int blkif_recover(struct blkfront_info *info)
 				bio_trim(cloned_bio, offset, size);
 				cloned_bio->bi_private = split_bio;
 				cloned_bio->bi_end_io = split_bio_end;
-				submit_bio(cloned_bio->bi_rw, 0, cloned_bio);
+				submit_bio(cloned_bio->bi_op,
+					   cloned_bio->bi_rw, cloned_bio);
 			}
 			/*
 			 * Now we have to wait for all those smaller bios to
@@ -1602,7 +1603,7 @@ static int blkif_recover(struct blkfront_info *info)
 			continue;
 		}
 		/* We don't need to split this bio */
-		submit_bio(bio->bi_rw, 0, bio);
+		submit_bio(bio->bi_op, bio->bi_rw, bio);
 	}
 
 	return 0;
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 9fa15bb..3b6b9e6 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -849,7 +849,7 @@ static void __zram_make_request(struct zram *zram, struct bio *bio)
 	offset = (bio->bi_iter.bi_sector &
 		  (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
 
-	if (unlikely(bio->bi_rw & REQ_DISCARD)) {
+	if (unlikely(bio->bi_op == REQ_OP_DISCARD)) {
 		zram_bio_discard(zram, index, offset, bio);
 		bio_endio(bio);
 		return;
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index d152e78..5dc383b8 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -55,7 +55,7 @@ reread:		left = ca->sb.bucket_size - offset;
 		bio->bi_iter.bi_sector	= bucket + offset;
 		bio->bi_bdev	= ca->bdev;
 		bio->bi_op	= REQ_OP_READ;
-		bio->bi_rw	= READ;
+		bio->bi_rw	= 0;
 		bio->bi_iter.bi_size	= len << 9;
 
 		bio->bi_end_io	= journal_read_endio;
@@ -454,7 +454,7 @@ static void do_journal_discard(struct cache *ca)
 						ca->sb.d[ja->discard_idx]);
 		bio->bi_bdev		= ca->bdev;
 		bio->bi_op		= REQ_OP_DISCARD;
-		bio->bi_rw		= REQ_WRITE|REQ_DISCARD;
+		bio->bi_rw		= 0;
 		bio->bi_max_vecs	= 1;
 		bio->bi_io_vec		= bio->bi_inline_vecs;
 		bio->bi_iter.bi_size	= bucket_bytes(ca);
@@ -629,7 +629,7 @@ static void journal_write_unlocked(struct closure *cl)
 		bio->bi_iter.bi_sector	= PTR_OFFSET(k, i);
 		bio->bi_bdev	= ca->bdev;
 		bio->bi_op	= REQ_OP_WRITE;
-		bio->bi_rw	= REQ_WRITE|REQ_SYNC|REQ_META|REQ_FLUSH|REQ_FUA;
+		bio->bi_rw	= REQ_SYNC|REQ_META|REQ_FLUSH|REQ_FUA;
 		bio->bi_iter.bi_size = sectors << 9;
 
 		bio->bi_end_io	= journal_write_endio;
diff --git a/drivers/md/bcache/movinggc.c b/drivers/md/bcache/movinggc.c
index 1318f32..78745ff 100644
--- a/drivers/md/bcache/movinggc.c
+++ b/drivers/md/bcache/movinggc.c
@@ -164,7 +164,7 @@ static void read_moving(struct cache_set *c)
 		bio = &io->bio.bio;
 
 		bio->bi_op	= REQ_OP_READ;
-		bio->bi_rw	= READ;
+		bio->bi_rw	= 0;
 		bio->bi_end_io	= read_moving_endio;
 
 		if (bio_alloc_pages(bio, GFP_KERNEL))
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 11f6b5c..0a35d7e 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -254,7 +254,6 @@ static void bch_data_insert_start(struct closure *cl)
 		bch_keylist_push(&op->insert_keys);
 
 		n->bi_op = REQ_OP_WRITE;
-		n->bi_rw |= REQ_WRITE;
 		bch_submit_bbio(n, op->c, k, 0);
 	} while (n != bio);
 
@@ -379,7 +378,7 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
 
 	if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
 	    c->gc_stats.in_use > CUTOFF_CACHE_ADD ||
-	    (bio->bi_rw & REQ_DISCARD))
+	    (bio->bi_op == REQ_OP_DISCARD))
 		goto skip;
 
 	if (mode == CACHE_MODE_NONE ||
@@ -900,7 +899,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
 	 * But check_overlapping drops dirty keys for which io hasn't started,
 	 * so we still want to call it.
 	 */
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		s->iop.bypass = true;
 
 	if (should_writeback(dc, s->orig_bio,
@@ -914,7 +913,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
 		s->iop.bio = s->orig_bio;
 		bio_get(s->iop.bio);
 
-		if (!(bio->bi_rw & REQ_DISCARD) ||
+		if (!(bio->bi_op == REQ_OP_DISCARD) ||
 		    blk_queue_discard(bdev_get_queue(dc->bdev)))
 			closure_bio_submit(bio, cl);
 	} else if (s->iop.writeback) {
@@ -993,7 +992,7 @@ static void cached_dev_make_request(struct request_queue *q, struct bio *bio)
 				cached_dev_read(dc, s);
 		}
 	} else {
-		if ((bio->bi_rw & REQ_DISCARD) &&
+		if ((bio->bi_op == REQ_OP_DISCARD) &&
 		    !blk_queue_discard(bdev_get_queue(dc->bdev)))
 			bio_endio(bio);
 		else
@@ -1101,7 +1100,7 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio)
 					&KEY(d->id, bio->bi_iter.bi_sector, 0),
 					&KEY(d->id, bio_end_sector(bio), 0));
 
-		s->iop.bypass		= (bio->bi_rw & REQ_DISCARD) != 0;
+		s->iop.bypass		= (bio->bi_op == REQ_OP_DISCARD) != 0;
 		s->iop.writeback	= true;
 		s->iop.bio		= bio;
 
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 28b1bae..f23d609 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -184,7 +184,7 @@ static void write_dirty(struct closure *cl)
 
 	dirty_init(w);
 	io->bio.bi_op		= REQ_OP_WRITE;
-	io->bio.bi_rw		= WRITE;
+	io->bio.bi_rw		= 0;
 	io->bio.bi_iter.bi_sector = KEY_START(&w->key);
 	io->bio.bi_bdev		= io->dc->bdev;
 	io->bio.bi_end_io	= dirty_endio;
@@ -258,7 +258,7 @@ static void read_dirty(struct cached_dev *dc)
 		io->bio.bi_bdev		= PTR_CACHE(dc->disk.c,
 						    &w->key, 0)->bdev;
 		io->bio.bi_op		= REQ_OP_READ;
-		io->bio.bi_rw		= READ;
+		io->bio.bi_rw		= 0;
 		io->bio.bi_end_io	= read_dirty_endio;
 
 		if (bio_alloc_pages(&io->bio, GFP_KERNEL))
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index dd90d12..1a13434 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -791,7 +791,8 @@ static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio)
 
 	spin_lock_irqsave(&cache->lock, flags);
 	if (cache->need_tick_bio &&
-	    !(bio->bi_rw & (REQ_FUA | REQ_FLUSH | REQ_DISCARD))) {
+	    !(bio->bi_rw & (REQ_FUA | REQ_FLUSH) &&
+	    bio->bi_op != REQ_OP_DISCARD)) {
 		pb->tick = true;
 		cache->need_tick_bio = false;
 	}
@@ -854,7 +855,7 @@ static void inc_ds(struct cache *cache, struct bio *bio,
 static bool accountable_bio(struct cache *cache, struct bio *bio)
 {
 	return ((bio->bi_bdev == cache->origin_dev->bdev) &&
-		!(bio->bi_rw & REQ_DISCARD));
+		(bio->bi_op != REQ_OP_DISCARD));
 }
 
 static void accounted_begin(struct cache *cache, struct bio *bio)
@@ -1065,7 +1066,8 @@ static void dec_io_migrations(struct cache *cache)
 
 static bool discard_or_flush(struct bio *bio)
 {
-	return bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD);
+	return bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+	       bio->bi_op == REQ_OP_DISCARD;
 }
 
 static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell)
@@ -1978,7 +1980,7 @@ static void process_deferred_bios(struct cache *cache)
 
 		if (bio->bi_rw & REQ_FLUSH)
 			process_flush_bio(cache, bio);
-		else if (bio->bi_rw & REQ_DISCARD)
+		else if (bio->bi_op == REQ_OP_DISCARD)
 			process_discard_bio(cache, &structs, bio);
 		else
 			process_bio(cache, &structs, bio);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 92689e5..404c7005 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1911,7 +1911,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
 	 * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight
 	 * - for REQ_DISCARD caller must use flush if IO ordering matters
 	 */
-	if (unlikely(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) {
+	if (unlikely(bio->bi_rw & REQ_FLUSH || bio->bi_op == REQ_OP_DISCARD)) {
 		bio->bi_bdev = cc->dev->bdev;
 		if (bio_sectors(bio))
 			bio->bi_iter.bi_sector = cc->start +
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index f389380..6b514cd 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -297,11 +297,11 @@ static void do_region(int op, int op_flags, unsigned region,
 	/*
 	 * Reject unsupported discard and write same requests.
 	 */
-	if (op == REQ_DISCARD)
+	if (op == REQ_OP_DISCARD)
 		special_cmd_max_sectors = q->limits.max_discard_sectors;
-	else if (op == REQ_WRITE_SAME)
+	else if (op == REQ_OP_WRITE_SAME)
 		special_cmd_max_sectors = q->limits.max_write_same_sectors;
-	if ((op == REQ_DISCARD || op == REQ_WRITE_SAME) &&
+	if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_SAME) &&
 	    special_cmd_max_sectors == 0) {
 		dec_count(io, region, -EOPNOTSUPP);
 		return;
@@ -315,7 +315,7 @@ static void do_region(int op, int op_flags, unsigned region,
 		/*
 		 * Allocate a suitably sized-bio.
 		 */
-		if ((op == REQ_DISCARD) || (op == REQ_WRITE_SAME))
+		if ((op == REQ_OP_DISCARD) || (op == REQ_OP_WRITE_SAME))
 			num_bvecs = 1;
 		else
 			num_bvecs = min_t(int, BIO_MAX_PAGES,
@@ -327,11 +327,11 @@ static void do_region(int op, int op_flags, unsigned region,
 		bio->bi_end_io = endio;
 		store_io_and_region_in_bio(bio, io, region);
 
-		if (op == REQ_DISCARD) {
+		if (op == REQ_OP_DISCARD) {
 			num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
 			bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
 			remaining -= num_sectors;
-		} else if (op == REQ_WRITE_SAME) {
+		} else if (op == REQ_OP_WRITE_SAME) {
 			/*
 			 * WRITE SAME only uses a single page.
 			 */
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 02dccbe..9612bff 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -735,7 +735,7 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
 		/*
 		 * Use WRITE SAME to optimize zeroing if all dests support it.
 		 */
-		job->rw = WRITE | REQ_WRITE_SAME;
+		job->rw = REQ_OP_WRITE_SAME;
 		for (i = 0; i < job->num_dests; i++)
 			if (!bdev_write_same(job->dests[i].bdev)) {
 				job->rw = WRITE;
diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
index 7bfaa91..6820654 100644
--- a/drivers/md/dm-log-writes.c
+++ b/drivers/md/dm-log-writes.c
@@ -554,7 +554,7 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio)
 	int i = 0;
 	bool flush_bio = (bio->bi_rw & REQ_FLUSH);
 	bool fua_bio = (bio->bi_rw & REQ_FUA);
-	bool discard_bio = (bio->bi_rw & REQ_DISCARD);
+	bool discard_bio = (bio->bi_op == REQ_OP_DISCARD);
 
 	pb->block = NULL;
 
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index ec48487..48da798 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -626,7 +626,7 @@ static void write_callback(unsigned long error, void *context)
 	 * If the bio is discard, return an error, but do not
 	 * degrade the array.
 	 */
-	if (bio->bi_rw & REQ_DISCARD) {
+	if (bio->bi_op == REQ_OP_DISCARD) {
 		bio->bi_error = -EOPNOTSUPP;
 		bio_endio(bio);
 		return;
@@ -665,8 +665,8 @@ static void do_write(struct mirror_set *ms, struct bio *bio)
 		.client = ms->io_client,
 	};
 
-	if (bio->bi_rw & REQ_DISCARD) {
-		io_req.bi_op_flags |= REQ_DISCARD;
+	if (bio->bi_op == REQ_OP_DISCARD) {
+		io_req.bi_op = REQ_OP_DISCARD;
 		io_req.mem.type = DM_IO_KMEM;
 		io_req.mem.ptr.addr = NULL;
 	}
@@ -705,7 +705,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
 
 	while ((bio = bio_list_pop(writes))) {
 		if ((bio->bi_rw & REQ_FLUSH) ||
-		    (bio->bi_rw & REQ_DISCARD)) {
+		    (bio->bi_op == REQ_OP_DISCARD)) {
 			bio_list_add(&sync, bio);
 			continue;
 		}
@@ -1253,7 +1253,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
 	 * We need to dec pending if this was a write.
 	 */
 	if (rw == WRITE) {
-		if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)))
+		if (!(bio->bi_rw & REQ_FLUSH || bio->bi_op == REQ_OP_DISCARD))
 			dm_rh_dec(ms->rh, bio_record->write_region);
 		return error;
 	}
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index b929fd5..adde887 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -405,7 +405,7 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
 		return;
 	}
 
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		return;
 
 	/* We must inform the log that the sync count has changed. */
@@ -528,7 +528,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
 	struct bio *bio;
 
 	for (bio = bios->head; bio; bio = bio->bi_next) {
-		if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))
+		if (bio->bi_rw & REQ_FLUSH || bio->bi_op == REQ_OP_DISCARD)
 			continue;
 		rh_inc(rh, dm_rh_bio_to_region(rh, bio));
 	}
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 797ddb9..12b1630 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -292,8 +292,8 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
 		bio->bi_bdev = sc->stripe[target_bio_nr].dev->bdev;
 		return DM_MAPIO_REMAPPED;
 	}
-	if (unlikely(bio->bi_rw & REQ_DISCARD) ||
-	    unlikely(bio->bi_rw & REQ_WRITE_SAME)) {
+	if (unlikely(bio->bi_op == REQ_OP_DISCARD) ||
+	    unlikely(bio->bi_op == REQ_OP_WRITE_SAME)) {
 		target_bio_nr = dm_bio_get_target_bio_nr(bio);
 		BUG_ON(target_bio_nr >= sc->stripes);
 		return stripe_map_range(sc, bio, target_bio_nr);
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 63a713d..caab74c 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -703,7 +703,7 @@ static void inc_all_io_entry(struct pool *pool, struct bio *bio)
 {
 	struct dm_thin_endio_hook *h;
 
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		return;
 
 	h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
@@ -866,7 +866,8 @@ static void __inc_remap_and_issue_cell(void *context,
 	struct bio *bio;
 
 	while ((bio = bio_list_pop(&cell->bios))) {
-		if (bio->bi_rw & (REQ_DISCARD | REQ_FLUSH | REQ_FUA))
+		if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+		    bio->bi_op == REQ_OP_DISCARD)
 			bio_list_add(&info->defer_bios, bio);
 		else {
 			inc_all_io_entry(info->tc->pool, bio);
@@ -1644,7 +1645,8 @@ static void __remap_and_issue_shared_cell(void *context,
 
 	while ((bio = bio_list_pop(&cell->bios))) {
 		if ((bio_data_dir(bio) == WRITE) ||
-		    (bio->bi_rw & (REQ_DISCARD | REQ_FLUSH | REQ_FUA)))
+		    (bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+		     bio->bi_op == REQ_OP_DISCARD))
 			bio_list_add(&info->defer_bios, bio);
 		else {
 			struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));;
@@ -2033,7 +2035,7 @@ static void process_thin_deferred_bios(struct thin_c *tc)
 			break;
 		}
 
-		if (bio->bi_rw & REQ_DISCARD)
+		if (bio->bi_op == REQ_OP_DISCARD)
 			pool->process_discard(tc, bio);
 		else
 			pool->process_bio(tc, bio);
@@ -2120,7 +2122,7 @@ static void process_thin_deferred_cells(struct thin_c *tc)
 				return;
 			}
 
-			if (cell->holder->bi_rw & REQ_DISCARD)
+			if (cell->holder->bi_op == REQ_OP_DISCARD)
 				pool->process_discard_cell(tc, cell);
 			else
 				pool->process_cell(tc, cell);
@@ -2555,7 +2557,8 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 		return DM_MAPIO_SUBMITTED;
 	}
 
-	if (bio->bi_rw & (REQ_DISCARD | REQ_FLUSH | REQ_FUA)) {
+	if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+	    bio->bi_op == REQ_OP_DISCARD) {
 		thin_defer_bio_with_throttle(tc, bio);
 		return DM_MAPIO_SUBMITTED;
 	}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index e03ca09..6b36aad 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -983,7 +983,7 @@ static void clone_endio(struct bio *bio)
 		}
 	}
 
-	if (unlikely(r == -EREMOTEIO && (bio->bi_rw & REQ_WRITE_SAME) &&
+	if (unlikely(r == -EREMOTEIO && (bio->bi_op == REQ_OP_WRITE_SAME) &&
 		     !bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors))
 		disable_write_same(md);
 
@@ -1657,9 +1657,9 @@ static int __split_and_process_non_flush(struct clone_info *ci)
 	struct dm_target *ti;
 	unsigned len;
 
-	if (unlikely(bio->bi_rw & REQ_DISCARD))
+	if (unlikely(bio->bi_op == REQ_OP_DISCARD))
 		return __send_discard(ci);
-	else if (unlikely(bio->bi_rw & REQ_WRITE_SAME))
+	else if (unlikely(bio->bi_op == REQ_OP_WRITE_SAME))
 		return __send_write_same(ci);
 
 	ti = dm_table_find_target(ci->map, ci->sector);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b7fe7e9..aad82c7 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -252,7 +252,7 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio)
 		split->bi_iter.bi_sector = split->bi_iter.bi_sector -
 			start_sector + data_offset;
 
-		if (unlikely((split->bi_rw & REQ_DISCARD) &&
+		if (unlikely((split->bi_op == REQ_OP_DISCARD) &&
 			 !blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
 			/* Just ignore it */
 			bio_endio(split);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index f8e5db0..f38be1f 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -488,7 +488,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
 		split->bi_iter.bi_sector = sector + zone->dev_start +
 			tmp_dev->data_offset;
 
-		if (unlikely((split->bi_rw & REQ_DISCARD) &&
+		if (unlikely((split->bi_op == REQ_OP_DISCARD) &&
 			 !blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
 			/* Just ignore it */
 			bio_endio(split);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 94e5a63..32e6bf5 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -757,7 +757,7 @@ static void flush_pending_writes(struct r1conf *conf)
 		while (bio) { /* submit pending writes */
 			struct bio *next = bio->bi_next;
 			bio->bi_next = NULL;
-			if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+			if (unlikely((bio->bi_op == REQ_OP_DISCARD) &&
 			    !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
 				/* Just ignore it */
 				bio_endio(bio);
@@ -1031,7 +1031,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
 	while (bio) { /* submit pending writes */
 		struct bio *next = bio->bi_next;
 		bio->bi_next = NULL;
-		if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+		if (unlikely((bio->bi_op == REQ_OP_DISCARD) &&
 		    !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
 			/* Just ignore it */
 			bio_endio(bio);
@@ -1055,9 +1055,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
 	const int rw = bio_data_dir(bio);
 	const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
 	const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
-	const unsigned long do_discard = (bio->bi_rw
-					  & (REQ_DISCARD | REQ_SECURE));
-	const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
+	const unsigned long do_secure = (bio->bi_rw & REQ_SECURE);
 	struct md_rdev *blocked_rdev;
 	struct blk_plug_cb *cb;
 	struct raid1_plug_cb *plug = NULL;
@@ -1166,7 +1164,7 @@ read_again:
 		read_bio->bi_bdev = mirror->rdev->bdev;
 		read_bio->bi_end_io = raid1_end_read_request;
 		read_bio->bi_op = REQ_OP_READ;
-		read_bio->bi_rw = READ | do_sync;
+		read_bio->bi_rw = do_sync;
 		read_bio->bi_private = r1_bio;
 
 		if (max_sectors < r1_bio->sectors) {
@@ -1377,8 +1375,7 @@ read_again:
 		mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
 		mbio->bi_end_io	= raid1_end_write_request;
 		mbio->bi_op = op;
-		mbio->bi_rw =
-			WRITE | do_flush_fua | do_sync | do_discard | do_same;
+		mbio->bi_rw = do_flush_fua | do_sync | do_secure;
 		mbio->bi_private = r1_bio;
 
 		atomic_inc(&r1_bio->remaining);
@@ -2021,7 +2018,7 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio)
 			continue;
 
 		wbio->bi_op = REQ_OP_WRITE;
-		wbio->bi_rw = WRITE;
+		wbio->bi_rw = 0;
 		wbio->bi_end_io = end_sync_write;
 		atomic_inc(&r1_bio->remaining);
 		md_sync_acct(conf->mirrors[i].rdev->bdev, bio_sectors(wbio));
@@ -2193,7 +2190,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
 		}
 
 		wbio->bi_op = REQ_OP_WRITE;
-		wbio->bi_rw = WRITE;
+		wbio->bi_rw = 0;
 		wbio->bi_iter.bi_sector = r1_bio->sector;
 		wbio->bi_iter.bi_size = r1_bio->sectors << 9;
 
@@ -2335,7 +2332,7 @@ read_more:
 		bio->bi_bdev = rdev->bdev;
 		bio->bi_end_io = raid1_end_read_request;
 		bio->bi_op  = REQ_OP_READ;
-		bio->bi_rw = READ | do_sync;
+		bio->bi_rw = do_sync;
 		bio->bi_private = r1_bio;
 		if (max_sectors < r1_bio->sectors) {
 			/* Drat - have to split this up more */
@@ -2551,7 +2548,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp
 				still_degraded = 1;
 		} else if (!test_bit(In_sync, &rdev->flags)) {
 			bio->bi_op = REQ_OP_WRITE;
-			bio->bi_rw = WRITE;
+			bio->bi_rw = 0;
 			bio->bi_end_io = end_sync_write;
 			write_targets ++;
 		} else {
@@ -2579,7 +2576,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp
 						disk = i;
 				}
 				bio->bi_op = REQ_OP_READ;
-				bio->bi_rw = READ;
+				bio->bi_rw = 0;
 				bio->bi_end_io = end_sync_read;
 				read_targets++;
 			} else if (!test_bit(WriteErrorSeen, &rdev->flags) &&
@@ -2592,7 +2589,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp
 				 * this device alone for this sync request.
 				 */
 				bio->bi_op = REQ_OP_WRITE;
-				bio->bi_rw = WRITE;
+				bio->bi_rw = 0;
 				bio->bi_end_io = end_sync_write;
 				write_targets++;
 			}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c7430f9..5d5b9b6 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -865,7 +865,7 @@ static void flush_pending_writes(struct r10conf *conf)
 		while (bio) { /* submit pending writes */
 			struct bio *next = bio->bi_next;
 			bio->bi_next = NULL;
-			if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+			if (unlikely((bio->bi_op == REQ_OP_DISCARD) &&
 			    !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
 				/* Just ignore it */
 				bio_endio(bio);
@@ -1041,7 +1041,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
 	while (bio) { /* submit pending writes */
 		struct bio *next = bio->bi_next;
 		bio->bi_next = NULL;
-		if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+		if (unlikely((bio->bi_op == REQ_OP_DISCARD) &&
 		    !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
 			/* Just ignore it */
 			bio_endio(bio);
@@ -1062,9 +1062,7 @@ static void __make_request(struct mddev *mddev, struct bio *bio)
 	const int rw = bio_data_dir(bio);
 	const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
 	const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
-	const unsigned long do_discard = (bio->bi_rw
-					  & (REQ_DISCARD | REQ_SECURE));
-	const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
+	const unsigned long do_secure = (bio->bi_rw & REQ_SECURE);
 	unsigned long flags;
 	struct md_rdev *blocked_rdev;
 	struct blk_plug_cb *cb;
@@ -1158,7 +1156,7 @@ read_again:
 		read_bio->bi_bdev = rdev->bdev;
 		read_bio->bi_end_io = raid10_end_read_request;
 		read_bio->bi_op = REQ_OP_READ;
-		read_bio->bi_rw = READ | do_sync;
+		read_bio->bi_rw = do_sync;
 		read_bio->bi_private = r10_bio;
 
 		if (max_sectors < r10_bio->sectors) {
@@ -1366,8 +1364,7 @@ retry_write:
 			mbio->bi_bdev = rdev->bdev;
 			mbio->bi_end_io	= raid10_end_write_request;
 			mbio->bi_op = op;
-			mbio->bi_rw =
-				WRITE | do_sync | do_fua | do_discard | do_same;
+			mbio->bi_rw = do_sync | do_fua | do_secure;
 			mbio->bi_private = r10_bio;
 
 			atomic_inc(&r10_bio->remaining);
@@ -1410,8 +1407,7 @@ retry_write:
 			mbio->bi_bdev = rdev->bdev;
 			mbio->bi_end_io	= raid10_end_write_request;
 			mbio->bi_op = op;
-			mbio->bi_rw =
-				WRITE | do_sync | do_fua | do_discard | do_same;
+			mbio->bi_rw = do_sync | do_fua | do_secure;
 			mbio->bi_private = r10_bio;
 
 			atomic_inc(&r10_bio->remaining);
@@ -1993,7 +1989,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
 		tbio->bi_vcnt = vcnt;
 		tbio->bi_iter.bi_size = r10_bio->sectors << 9;
 		tbio->bi_op = REQ_OP_WRITE;
-		tbio->bi_rw = WRITE;
+		tbio->bi_rw = 0;
 		tbio->bi_private = r10_bio;
 		tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;
 		tbio->bi_end_io = end_sync_write;
@@ -2550,7 +2546,7 @@ read_more:
 		+ choose_data_offset(r10_bio, rdev);
 	bio->bi_bdev = rdev->bdev;
 	bio->bi_op = REQ_OP_READ;
-	bio->bi_rw = READ | do_sync;
+	bio->bi_rw = do_sync;
 	bio->bi_private = r10_bio;
 	bio->bi_end_io = raid10_end_read_request;
 	if (max_sectors < r10_bio->sectors) {
@@ -3038,7 +3034,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
 				bio->bi_private = r10_bio;
 				bio->bi_end_io = end_sync_read;
 				bio->bi_op = REQ_OP_READ;
-				bio->bi_rw = READ;
+				bio->bi_rw = 0;
 				from_addr = r10_bio->devs[j].addr;
 				bio->bi_iter.bi_sector = from_addr +
 					rdev->data_offset;
@@ -3065,7 +3061,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
 					bio->bi_private = r10_bio;
 					bio->bi_end_io = end_sync_write;
 					bio->bi_op = REQ_OP_WRITE;
-					bio->bi_rw = WRITE;
+					bio->bi_rw = 0;
 					bio->bi_iter.bi_sector = to_addr
 						+ rdev->data_offset;
 					bio->bi_bdev = rdev->bdev;
@@ -3095,7 +3091,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
 				bio->bi_private = r10_bio;
 				bio->bi_end_io = end_sync_write;
 				bio->bi_op = REQ_OP_WRITE;
-				bio->bi_rw = WRITE;
+				bio->bi_rw = 0;
 				bio->bi_iter.bi_sector = to_addr +
 					rdev->data_offset;
 				bio->bi_bdev = rdev->bdev;
@@ -3216,7 +3212,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
 			bio->bi_private = r10_bio;
 			bio->bi_end_io = end_sync_read;
 			bio->bi_op = REQ_OP_READ;
-			bio->bi_rw = READ;
+			bio->bi_rw = 0;
 			bio->bi_iter.bi_sector = sector +
 				conf->mirrors[d].rdev->data_offset;
 			bio->bi_bdev = conf->mirrors[d].rdev->bdev;
@@ -3239,7 +3235,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
 			bio->bi_private = r10_bio;
 			bio->bi_end_io = end_sync_write;
 			bio->bi_op = REQ_OP_WRITE;
-			bio->bi_rw = WRITE;
+			bio->bi_rw = 0;
 			bio->bi_iter.bi_sector = sector +
 				conf->mirrors[d].replacement->data_offset;
 			bio->bi_bdev = conf->mirrors[d].replacement->bdev;
@@ -4323,7 +4319,7 @@ read_more:
 	read_bio->bi_private = r10_bio;
 	read_bio->bi_end_io = end_sync_read;
 	read_bio->bi_op = REQ_OP_READ;
-	read_bio->bi_rw = READ;
+	read_bio->bi_rw = 0;
 	read_bio->bi_flags &= (~0UL << BIO_RESET_BITS);
 	read_bio->bi_error = 0;
 	read_bio->bi_vcnt = 0;
@@ -4358,7 +4354,7 @@ read_more:
 		b->bi_private = r10_bio;
 		b->bi_end_io = end_reshape_write;
 		b->bi_op = REQ_OP_WRITE;
-		b->bi_rw = WRITE;
+		b->bi_rw = 0;
 		b->bi_next = blist;
 		blist = b;
 	}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7480155..9b084b2 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -813,7 +813,8 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh
 	dd_idx = 0;
 	while (dd_idx == sh->pd_idx || dd_idx == sh->qd_idx)
 		dd_idx++;
-	if (head->dev[dd_idx].towrite->bi_rw != sh->dev[dd_idx].towrite->bi_rw)
+	if (head->dev[dd_idx].towrite->bi_rw != sh->dev[dd_idx].towrite->bi_rw &&
+	    head->dev[dd_idx].towrite->bi_op != sh->dev[dd_idx].towrite->bi_op)
 		goto unlock_out;
 
 	if (head->batch_head) {
@@ -910,15 +911,8 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
 			} else {
 				op = REQ_OP_WRITE;
 			}
-			if (test_bit(R5_Discard, &sh->dev[i].flags)) {
+			if (test_bit(R5_Discard, &sh->dev[i].flags))
 				op = REQ_OP_DISCARD;
-				/*
-				 * this temporary for compat because drivers
-				 * expected this to be set for discards. It
-				 * will be removed in the next patches.
-				 */
-				op_flags |= REQ_WRITE;
-			}
 		} else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
 			op = REQ_OP_READ;
 		else if (test_and_clear_bit(R5_WantReplace,
@@ -1011,7 +1005,7 @@ again:
 			bio_reset(bi);
 			bi->bi_bdev = rdev->bdev;
 			bi->bi_op = op;
-			bi->bi_rw = op | op_flags;
+			bi->bi_rw = op_flags;
 			bi->bi_end_io = (op_to_data_dir(op) == WRITE)
 				? raid5_end_write_request
 				: raid5_end_read_request;
@@ -1064,7 +1058,7 @@ again:
 			bio_reset(rbi);
 			rbi->bi_bdev = rrdev->bdev;
 			rbi->bi_op = op;
-			rbi->bi_rw = op | op_flags;
+			rbi->bi_rw = op_flags;
 			BUG_ON(!(op_to_data_dir(op)));
 			rbi->bi_end_io = raid5_end_write_request;
 			rbi->bi_private = sh;
@@ -1640,7 +1634,7 @@ again:
 					set_bit(R5_WantFUA, &dev->flags);
 				if (wbi->bi_rw & REQ_SYNC)
 					set_bit(R5_SyncIO, &dev->flags);
-				if (wbi->bi_rw & REQ_DISCARD)
+				if (wbi->bi_op == REQ_OP_DISCARD)
 					set_bit(R5_Discard, &dev->flags);
 				else {
 					tx = async_copy_data(1, wbi, &dev->page,
@@ -5164,7 +5158,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
 			return;
 	}
 
-	if (unlikely(bi->bi_rw & REQ_DISCARD)) {
+	if (unlikely(bi->bi_op == REQ_OP_DISCARD)) {
 		make_discard_request(mddev, bi);
 		return;
 	}
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 650ba1c..b55be71 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -730,7 +730,6 @@ static int _osd_req_list_objects(struct osd_request *or,
 	}
 
 	bio->bi_op = REQ_OP_READ;
-	bio->bi_rw &= ~REQ_WRITE;
 	or->in.bio = bio;
 	or->in.total_bytes = bio->bi_iter.bi_size;
 	return 0;
@@ -844,7 +843,6 @@ int osd_req_write_kern(struct osd_request *or,
 		return PTR_ERR(bio);
 
 	bio->bi_op = REQ_OP_WRITE;
-	bio->bi_rw |= REQ_WRITE; /* FIXME: bio_set_dir() */
 	osd_req_write(or, obj, offset, bio, len);
 	return 0;
 }
@@ -962,7 +960,6 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
 		return PTR_ERR(bio);
 
 	bio->bi_op = REQ_OP_WRITE;
-	bio->bi_rw |= REQ_WRITE;
 
 	/* integrity check the continuation before the bio is linked
 	 * with the other data segments since the continuation
@@ -1084,7 +1081,6 @@ int osd_req_write_sg_kern(struct osd_request *or,
 		return PTR_ERR(bio);
 
 	bio->bi_op = REQ_OP_WRITE;
-	bio->bi_rw |= REQ_WRITE;
 	osd_req_write_sg(or, obj, bio, sglist, numentries);
 
 	return 0;
diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c
index 5f0d80c..9531cd8 100644
--- a/drivers/staging/lustre/lustre/llite/lloop.c
+++ b/drivers/staging/lustre/lustre/llite/lloop.c
@@ -212,9 +212,9 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
 	io->ci_lockreq = CILR_NEVER;
 
 	LASSERT(head != NULL);
-	rw = head->bi_rw;
+	rw = bio_data_dir(head);
 	for (bio = head; bio != NULL; bio = bio->bi_next) {
-		LASSERT(rw == bio->bi_rw);
+		LASSERT(rw == bio_data_dir(bio));
 
 		offset = (pgoff_t)(bio->bi_iter.bi_sector << 9) + lo->lo_offset;
 		bio_for_each_segment(bvec, bio, iter) {
@@ -305,9 +305,9 @@ static unsigned int loop_get_bio(struct lloop_device *lo, struct bio **req)
 	/* TODO: need to split the bio, too bad. */
 	LASSERT(first->bi_vcnt <= LLOOP_MAX_SEGMENTS);
 
-	rw = first->bi_rw;
+	rw = bio_data_dir(first);
 	bio = &lo->lo_bio;
-	while (*bio && (*bio)->bi_rw == rw) {
+	while (*bio && bio_data_dir(*bio) == rw) {
 		CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u \n",
 		       (unsigned long long)(*bio)->bi_iter.bi_sector,
 		       (*bio)->bi_iter.bi_size,
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 00a7bda5..2cf915c 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -921,10 +921,8 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
 				if (!bio)
 					goto fail;
 
-				if (rw) {
+				if (rw)
 					bio->bi_op = REQ_OP_WRITE;
-					bio->bi_rw |= REQ_WRITE;
-				}
 
 				pr_debug("PSCSI: Allocated bio: %p,"
 					" dir: %s nr_vecs: %d\n", bio,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ef67c2f..06c7c1d 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -367,7 +367,7 @@ loop_lock:
 			sync_pending = 0;
 		}
 
-		btrfsic_submit_bio(cur->bi_rw, 0, cur);
+		btrfsic_submit_bio(cur->bi_op, cur->bi_rw, cur);
 		num_run++;
 		batch_run++;
 
@@ -5766,7 +5766,7 @@ static void btrfs_end_bio(struct bio *bio)
 			BUG_ON(stripe_index >= bbio->num_stripes);
 			dev = bbio->stripes[stripe_index].dev;
 			if (dev->bdev) {
-				if (bio->bi_rw & WRITE)
+				if (bio_data_dir(bio) == WRITE)
 					btrfs_dev_stat_inc(dev,
 						BTRFS_DEV_STAT_WRITE_ERRS);
 				else
@@ -5848,7 +5848,7 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
 	WARN_ON(bio->bi_next);
 	bio->bi_next = NULL;
 	bio->bi_op = op;
-	bio->bi_rw |= op | op_flags;
+	bio->bi_rw |= op_flags;
 
 	spin_lock(&device->io_lock);
 	if (bio->bi_rw & REQ_SYNC)
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 7339bef..c40ed74 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -879,7 +879,6 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
 				bio = master_dev->bio;
 				/* FIXME: bio_set_dir() */
 				bio->bi_op = REQ_OP_WRITE;
-				bio->bi_rw |= REQ_WRITE;
 			}
 
 			osd_req_write(or, _ios_obj(ios, cur_comp),
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7796e0b..7cbad7a 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -106,18 +106,23 @@ static inline bool bio_has_data(struct bio *bio)
 {
 	if (bio &&
 	    bio->bi_iter.bi_size &&
-	    !(bio->bi_rw & REQ_DISCARD))
+	    !(bio->bi_op == REQ_OP_DISCARD))
 		return true;
 
 	return false;
 }
 
+static inline bool bio_no_advance_iter(struct bio *bio)
+{
+	return bio->bi_op == REQ_OP_DISCARD || bio->bi_op == REQ_OP_WRITE_SAME;
+}
+
 static inline bool bio_is_rw(struct bio *bio)
 {
 	if (!bio_has_data(bio))
 		return false;
 
-	if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
+	if (bio_no_advance_iter(bio))
 		return false;
 
 	return true;
@@ -225,7 +230,7 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
 {
 	iter->bi_sector += bytes >> 9;
 
-	if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
+	if (bio_no_advance_iter(bio))
 		iter->bi_size -= bytes;
 	else
 		bvec_iter_advance(bio->bi_io_vec, iter, bytes);
@@ -253,10 +258,10 @@ static inline unsigned bio_segments(struct bio *bio)
 	 * differently:
 	 */
 
-	if (bio->bi_rw & REQ_DISCARD)
+	if (bio->bi_op == REQ_OP_DISCARD)
 		return 1;
 
-	if (bio->bi_rw & REQ_WRITE_SAME)
+	if (bio->bi_op == REQ_OP_WRITE_SAME)
 		return 1;
 
 	bio_for_each_segment(bv, bio, iter)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index b974aea..581d353 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -213,13 +213,10 @@ enum rq_flag_bits {
 #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_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | REQ_NOIDLE | \
+	 REQ_FLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY)
 #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)
@@ -252,9 +249,9 @@ enum rq_flag_bits {
 
 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,
+	REQ_OP_WRITE_SAME,
 };
 
 #endif /* __LINUX_BLK_TYPES_H */
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index afc1343..ee25ba4 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -109,7 +109,7 @@ static inline int blk_cmd_buf_len(struct request *rq)
 }
 
 extern void blk_dump_cmd(char *buf, struct request *rq);
-extern void blk_fill_rwbs(char *rwbs, u32 rw, int bytes);
+extern void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes);
 
 #endif /* CONFIG_EVENT_TRACING && CONFIG_BLOCK */
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 66dd4b91..91f645e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -191,19 +191,19 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate);
  *			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 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
@@ -2389,16 +2389,23 @@ extern void make_bad_inode(struct inode *);
 extern int is_bad_inode(struct inode *);
 
 #ifdef CONFIG_BLOCK
-/*
- * return READ, READA, or WRITE
- */
-#define bio_rw(bio)		((bio)->bi_rw & (RW_MASK | RWA_MASK))
 
 /*
  * return data direction, READ or WRITE
  */
 #define bio_data_dir(bio)	((bio)->bi_op == REQ_OP_READ ? READ : WRITE)
 
+/*
+ * return READ, READA, or WRITE
+ */
+static inline int bio_rw(struct bio *bio)
+{
+	if (bio->bi_rw & RWA_MASK)
+		return READA;
+
+	return bio_data_dir(bio);
+}
+
 extern void check_disk_size_change(struct gendisk *disk,
 				   struct block_device *bdev);
 extern int revalidate_disk(struct gendisk *);
diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h
index 981acf7..8abe564 100644
--- a/include/trace/events/bcache.h
+++ b/include/trace/events/bcache.h
@@ -27,7 +27,8 @@ DECLARE_EVENT_CLASS(bcache_request,
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->orig_sector	= bio->bi_iter.bi_sector - 16;
 		__entry->nr_sector	= bio->bi_iter.bi_size >> 9;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 	),
 
 	TP_printk("%d,%d %s %llu + %u (from %d,%d @ %llu)",
@@ -101,7 +102,8 @@ DECLARE_EVENT_CLASS(bcache_bio,
 		__entry->dev		= bio->bi_bdev->bd_dev;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio->bi_iter.bi_size >> 9;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 	),
 
 	TP_printk("%d,%d  %s %llu + %u",
@@ -136,7 +138,8 @@ TRACE_EVENT(bcache_read,
 		__entry->dev		= bio->bi_bdev->bd_dev;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio->bi_iter.bi_size >> 9;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 		__entry->cache_hit = hit;
 		__entry->bypass = bypass;
 	),
@@ -167,7 +170,8 @@ TRACE_EVENT(bcache_write,
 		__entry->inode		= inode;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio->bi_iter.bi_size >> 9;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 		__entry->writeback = writeback;
 		__entry->bypass = bypass;
 	),
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index e8a5eca..4416dcd 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -84,7 +84,8 @@ DECLARE_EVENT_CLASS(block_rq_with_error,
 					0 : blk_rq_sectors(rq);
 		__entry->errors    = rq->errors;
 
-		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+		blk_fill_rwbs(__entry->rwbs, rq->op, rq->cmd_flags,
+			      blk_rq_bytes(rq));
 		blk_dump_cmd(__get_str(cmd), rq);
 	),
 
@@ -162,7 +163,7 @@ TRACE_EVENT(block_rq_complete,
 		__entry->nr_sector = nr_bytes >> 9;
 		__entry->errors    = rq->errors;
 
-		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, nr_bytes);
+		blk_fill_rwbs(__entry->rwbs, rq->op, rq->cmd_flags, nr_bytes);
 		blk_dump_cmd(__get_str(cmd), rq);
 	),
 
@@ -198,7 +199,8 @@ DECLARE_EVENT_CLASS(block_rq,
 		__entry->bytes     = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
 					blk_rq_bytes(rq) : 0;
 
-		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+		blk_fill_rwbs(__entry->rwbs, rq->op, rq->cmd_flags,
+			      blk_rq_bytes(rq));
 		blk_dump_cmd(__get_str(cmd), rq);
 		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
 	),
@@ -272,7 +274,8 @@ TRACE_EVENT(block_bio_bounce,
 					  bio->bi_bdev->bd_dev : 0;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio_sectors(bio);
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
 	),
 
@@ -310,7 +313,8 @@ TRACE_EVENT(block_bio_complete,
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio_sectors(bio);
 		__entry->error		= error;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 	),
 
 	TP_printk("%d,%d %s %llu + %u [%d]",
@@ -337,7 +341,8 @@ DECLARE_EVENT_CLASS(block_bio_merge,
 		__entry->dev		= bio->bi_bdev->bd_dev;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio_sectors(bio);
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
 	),
 
@@ -404,7 +409,8 @@ TRACE_EVENT(block_bio_queue,
 		__entry->dev		= bio->bi_bdev->bd_dev;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->nr_sector	= bio_sectors(bio);
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
 	),
 
@@ -432,7 +438,7 @@ DECLARE_EVENT_CLASS(block_get_rq,
 		__entry->dev		= bio ? bio->bi_bdev->bd_dev : 0;
 		__entry->sector		= bio ? bio->bi_iter.bi_sector : 0;
 		__entry->nr_sector	= bio ? bio_sectors(bio) : 0;
-		blk_fill_rwbs(__entry->rwbs,
+		blk_fill_rwbs(__entry->rwbs, bio ? bio->bi_op : 0,
 			      bio ? bio->bi_rw : 0, __entry->nr_sector);
 		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
         ),
@@ -567,7 +573,8 @@ TRACE_EVENT(block_split,
 		__entry->dev		= bio->bi_bdev->bd_dev;
 		__entry->sector		= bio->bi_iter.bi_sector;
 		__entry->new_sector	= new_sector;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
 	),
 
@@ -610,7 +617,8 @@ TRACE_EVENT(block_bio_remap,
 		__entry->nr_sector	= bio_sectors(bio);
 		__entry->old_dev	= dev;
 		__entry->old_sector	= from;
-		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+		blk_fill_rwbs(__entry->rwbs, bio->bi_op, bio->bi_rw,
+			      bio->bi_iter.bi_size);
 	),
 
 	TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
@@ -656,7 +664,8 @@ TRACE_EVENT(block_rq_remap,
 		__entry->old_dev	= dev;
 		__entry->old_sector	= from;
 		__entry->nr_bios	= blk_rq_count_bios(rq);
-		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+		blk_fill_rwbs(__entry->rwbs, rq->op, rq->cmd_flags,
+			      blk_rq_bytes(rq));
 	),
 
 	TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu %u",
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 90e72a0..36e3862 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -199,7 +199,8 @@ static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ),
  * blk_io_trace structure and places it in a per-cpu subbuffer.
  */
 static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
-		     int rw, u32 what, int error, int pdu_len, void *pdu_data)
+		     int op, int op_flags, u32 what, int error, int pdu_len,
+		     void *pdu_data)
 {
 	struct task_struct *tsk = current;
 	struct ring_buffer_event *event = NULL;
@@ -214,13 +215,14 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
 	if (unlikely(bt->trace_state != Blktrace_running && !blk_tracer))
 		return;
 
-	what |= ddir_act[rw & WRITE];
-	what |= MASK_TC_BIT(rw, SYNC);
-	what |= MASK_TC_BIT(rw, RAHEAD);
-	what |= MASK_TC_BIT(rw, META);
-	what |= MASK_TC_BIT(rw, DISCARD);
-	what |= MASK_TC_BIT(rw, FLUSH);
-	what |= MASK_TC_BIT(rw, FUA);
+	what |= ddir_act[op_to_data_dir(op)];
+	what |= MASK_TC_BIT(op_flags, SYNC);
+	what |= MASK_TC_BIT(op_flags, RAHEAD);
+	what |= MASK_TC_BIT(op_flags, META);
+	what |= MASK_TC_BIT(op_flags, FLUSH);
+	what |= MASK_TC_BIT(op_flags, FUA);
+	if (op == REQ_OP_DISCARD)
+		what |= BLK_TC_ACT(BLK_TC_DISCARD);
 
 	pid = tsk->pid;
 	if (act_log_check(bt, what, sector, pid))
@@ -717,11 +719,11 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
 
 	if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
 		what |= BLK_TC_ACT(BLK_TC_PC);
-		__blk_add_trace(bt, 0, nr_bytes, rq->cmd_flags,
+		__blk_add_trace(bt, 0, nr_bytes, rq->op, rq->cmd_flags,
 				what, rq->errors, rq->cmd_len, rq->cmd);
 	} else  {
 		what |= BLK_TC_ACT(BLK_TC_FS);
-		__blk_add_trace(bt, blk_rq_pos(rq), nr_bytes,
+		__blk_add_trace(bt, blk_rq_pos(rq), nr_bytes, rq->op,
 				rq->cmd_flags, what, rq->errors, 0, NULL);
 	}
 }
@@ -779,7 +781,7 @@ static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
 		return;
 
 	__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
-			bio->bi_rw, what, error, 0, NULL);
+			bio->bi_op, bio->bi_rw, what, error, 0, NULL);
 }
 
 static void blk_add_trace_bio_bounce(void *ignore,
@@ -827,7 +829,8 @@ static void blk_add_trace_getrq(void *ignore,
 		struct blk_trace *bt = q->blk_trace;
 
 		if (bt)
-			__blk_add_trace(bt, 0, 0, rw, BLK_TA_GETRQ, 0, 0, NULL);
+			__blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_GETRQ, 0, 0,
+					NULL);
 	}
 }
 
@@ -842,7 +845,7 @@ static void blk_add_trace_sleeprq(void *ignore,
 		struct blk_trace *bt = q->blk_trace;
 
 		if (bt)
-			__blk_add_trace(bt, 0, 0, rw, BLK_TA_SLEEPRQ,
+			__blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_SLEEPRQ,
 					0, 0, NULL);
 	}
 }
@@ -852,7 +855,7 @@ static void blk_add_trace_plug(void *ignore, struct request_queue *q)
 	struct blk_trace *bt = q->blk_trace;
 
 	if (bt)
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL);
+		__blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL);
 }
 
 static void blk_add_trace_unplug(void *ignore, struct request_queue *q,
@@ -869,7 +872,7 @@ static void blk_add_trace_unplug(void *ignore, struct request_queue *q,
 		else
 			what = BLK_TA_UNPLUG_TIMER;
 
-		__blk_add_trace(bt, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu);
+		__blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu);
 	}
 }
 
@@ -883,8 +886,9 @@ static void blk_add_trace_split(void *ignore,
 		__be64 rpdu = cpu_to_be64(pdu);
 
 		__blk_add_trace(bt, bio->bi_iter.bi_sector,
-				bio->bi_iter.bi_size, bio->bi_rw, BLK_TA_SPLIT,
-				bio->bi_error, sizeof(rpdu), &rpdu);
+				bio->bi_iter.bi_size, bio->bi_op, bio->bi_rw,
+				BLK_TA_SPLIT, bio->bi_error, sizeof(rpdu),
+				&rpdu);
 	}
 }
 
@@ -916,7 +920,7 @@ static void blk_add_trace_bio_remap(void *ignore,
 	r.sector_from = cpu_to_be64(from);
 
 	__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
-			bio->bi_rw, BLK_TA_REMAP, bio->bi_error,
+			bio->bi_op, bio->bi_rw, BLK_TA_REMAP, bio->bi_error,
 			sizeof(r), &r);
 }
 
@@ -949,7 +953,7 @@ static void blk_add_trace_rq_remap(void *ignore,
 	r.sector_from = cpu_to_be64(from);
 
 	__blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
-			rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors,
+			rq_data_dir(rq), 0, BLK_TA_REMAP, !!rq->errors,
 			sizeof(r), &r);
 }
 
@@ -974,10 +978,10 @@ void blk_add_driver_data(struct request_queue *q,
 		return;
 
 	if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
-		__blk_add_trace(bt, 0, blk_rq_bytes(rq), 0,
+		__blk_add_trace(bt, 0, blk_rq_bytes(rq), 0, 0,
 				BLK_TA_DRV_DATA, rq->errors, len, data);
 	else
-		__blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), 0,
+		__blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), 0, 0,
 				BLK_TA_DRV_DATA, rq->errors, len, data);
 }
 EXPORT_SYMBOL_GPL(blk_add_driver_data);
@@ -1778,16 +1782,16 @@ void blk_dump_cmd(char *buf, struct request *rq)
 	}
 }
 
-void blk_fill_rwbs(char *rwbs, u32 rw, int bytes)
+void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes)
 {
 	int i = 0;
 
 	if (rw & REQ_FLUSH)
 		rwbs[i++] = 'F';
 
-	if (rw & WRITE)
+	if (op == WRITE)
 		rwbs[i++] = 'W';
-	else if (rw & REQ_DISCARD)
+	else if (op == REQ_OP_DISCARD)
 		rwbs[i++] = 'D';
 	else if (bytes)
 		rwbs[i++] = 'R';
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 32/32] block: remove __REQ op defs and reduce bi_op/bi_rw sizes
From: mchristi @ 2015-11-04 22:08 UTC (permalink / raw)
  To: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

From: Mike Christie <mchristi@redhat.com>

This patches removes the __REQ/REQ definitions for operations
now defined by REQ_OPs.

There is now no need for bi_rw to be a long, so this makes it a
int. I also moved the priority to its own field, but I guess I could
have just kept this in the bi_rw since there is only 16 bio related
REQ_XYZ flags.

bi_op is also no longer a bitmap, so it only needs to be a u8/char,
so that is changed too.

This is more of a RFC patch, because I still need to update the rest
of the block layer code that was treating bi_rw as a long and I can
also shrink the request->cmd_flags.

I was not sure if or how much or where people wanted to stick things.
There also appears to be room in the bi_flags field. If bi_flags is
only using 13 bits and there are only 16 REQ_XYZs bits related bios,
I could put them all in one variable if we wanted to go wild with trying
to shrink the bio while I am at it..

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 include/linux/bio.h         | 13 ++-----------
 include/linux/blk_types.h   | 23 ++++++-----------------
 include/trace/events/f2fs.h |  1 -
 3 files changed, 8 insertions(+), 29 deletions(-)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7cbad7a..34a20cf 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -44,18 +44,9 @@
 #define BIO_MAX_SIZE		(BIO_MAX_PAGES << PAGE_CACHE_SHIFT)
 #define BIO_MAX_SECTORS		(BIO_MAX_SIZE >> 9)
 
-/*
- * upper 16 bits of bi_rw define the io priority of this bio
- */
-#define BIO_PRIO_SHIFT	(8 * sizeof(unsigned long) - IOPRIO_BITS)
-#define bio_prio(bio)	((bio)->bi_rw >> BIO_PRIO_SHIFT)
+#define bio_prio(bio)		(bio)->bi_ioprio
 #define bio_prio_valid(bio)	ioprio_valid(bio_prio(bio))
-
-#define bio_set_prio(bio, prio)		do {			\
-	WARN_ON(prio >= (1 << IOPRIO_BITS));			\
-	(bio)->bi_rw &= ((1UL << BIO_PRIO_SHIFT) - 1);		\
-	(bio)->bi_rw |= ((unsigned long) (prio) << BIO_PRIO_SHIFT);	\
-} while (0)
+#define bio_set_prio(bio, prio)	((bio)->bi_ioprio = prio)
 
 /*
  * various member access, note that bio_data should of course not be used
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 581d353..c32ae3c 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -48,14 +48,9 @@ struct bio {
 	struct block_device	*bi_bdev;
 	unsigned int		bi_flags;	/* status, command, etc */
 	int			bi_error;
-	unsigned long		bi_rw;		/* bottom bits rq_flags_bits
-						 * top bits priority
-						 */
-	/*
-	 * this will be a u8 in the next patches and bi_rw can be shrunk to
-	 * a u32. For compat in these transistional patches op is a int here.
-	 */
-	int			bi_op;		/* REQ_OP */
+	unsigned int		bi_rw;		/* rq_flags_bits */
+	unsigned short		bi_ioprio;
+	u8			bi_op;		/* REQ_OP */
 
 
 	struct bvec_iter	bi_iter;
@@ -151,7 +146,6 @@ struct bio {
  */
 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 */
@@ -159,9 +153,7 @@ enum rq_flag_bits {
 	__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 */
@@ -198,15 +190,12 @@ enum rq_flag_bits {
 	__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)
 
@@ -250,8 +239,8 @@ enum rq_flag_bits {
 enum req_op {
 	REQ_OP_READ,
 	REQ_OP_WRITE,
-	REQ_OP_DISCARD,
-	REQ_OP_WRITE_SAME,
+	REQ_OP_DISCARD,		/* request to discard sectors */
+	REQ_OP_WRITE_SAME,	/* write same block many times */
 };
 
 #endif /* __LINUX_BLK_TYPES_H */
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index 0c7301b..2446a2f 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -31,7 +31,6 @@ TRACE_DEFINE_ENUM(BG_GC);
 TRACE_DEFINE_ENUM(LFS);
 TRACE_DEFINE_ENUM(SSR);
 TRACE_DEFINE_ENUM(__REQ_RAHEAD);
-TRACE_DEFINE_ENUM(__REQ_WRITE);
 TRACE_DEFINE_ENUM(__REQ_SYNC);
 TRACE_DEFINE_ENUM(__REQ_NOIDLE);
 TRACE_DEFINE_ENUM(__REQ_FLUSH);
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH] md/raid10: fix data corruption and crash during resync
From: Shaohua Li @ 2015-11-04 22:33 UTC (permalink / raw)
  To: Artur Paszkiewicz; +Cc: neilb, linux-raid, pawel.baldysiak
In-Reply-To: <1446654630-24067-1-git-send-email-artur.paszkiewicz@intel.com>

On Wed, Nov 04, 2015 at 05:30:30PM +0100, Artur Paszkiewicz wrote:
> The commit c31df25f20e3 ("md/raid10: make sync_request_write() call
> bio_copy_data()") replaced manual data copying with bio_copy_data() but
> it doesn't work as intended. The source bio (fbio) is already processed,
> so its bvec_iter has bi_size == 0 and bi_idx == bi_vcnt.  Because of
> this, bio_copy_data() either does not copy anything, or worse, copies
> data from the ->bi_next bio if it is set.  This causes wrong data to be
> written to drives during resync and sometimes lockups/crashes in
> bio_copy_data():
> 
> [  517.338478] NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [md126_raid10:3319]
> [  517.347324] Modules linked in: raid10 xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 tun ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter ip_tables x86_pkg_temp_thermal coretemp kvm_intel kvm crct10dif_pclmul crc32_pclmul cryptd shpchp pcspkr ipmi_si ipmi_msghandler tpm_crb acpi_power_meter acpi_cpufreq ext4 mbcache jbd2 sr_mod cdrom sd_mod e1000e ax88179_178a usbnet mii ahci ata_generic crc32c_intel libahci ptp pata_acpi l
 ibata pps_core wmi sunrpc dm_mirror dm_region_hash dm_log dm_mod
> [  517.440555] CPU: 0 PID: 3319 Comm: md126_raid10 Not tainted 4.3.0-rc6+ #1
> [  517.448384] Hardware name: Intel Corporation PURLEY/PURLEY, BIOS PLYDCRB1.86B.0055.D14.1509221924 09/22/2015
> [  517.459768] task: ffff880153773980 ti: ffff880150df8000 task.ti: ffff880150df8000
> [  517.468529] RIP: 0010:[<ffffffff812e1888>]  [<ffffffff812e1888>] bio_copy_data+0xc8/0x3c0
> [  517.478164] RSP: 0018:ffff880150dfbc98  EFLAGS: 00000246
> [  517.484341] RAX: ffff880169356688 RBX: 0000000000001000 RCX: 0000000000000000
> [  517.492558] RDX: 0000000000000000 RSI: ffffea0001ac2980 RDI: ffffea0000d835c0
> [  517.500773] RBP: ffff880150dfbd08 R08: 0000000000000001 R09: ffff880153773980
> [  517.508987] R10: ffff880169356600 R11: 0000000000001000 R12: 0000000000010000
> [  517.517199] R13: 000000000000e000 R14: 0000000000000000 R15: 0000000000001000
> [  517.525412] FS:  0000000000000000(0000) GS:ffff880174a00000(0000) knlGS:0000000000000000
> [  517.534844] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [  517.541507] CR2: 00007f8a044d5fed CR3: 0000000169504000 CR4: 00000000001406f0
> [  517.549722] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [  517.557929] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> [  517.566144] Stack:
> [  517.568626]  ffff880174a16bc0 ffff880153773980 ffff880169356600 0000000000000000
> [  517.577659]  0000000000000001 0000000000000001 ffff880153773980 ffff88016a61a800
> [  517.586715]  ffff880150dfbcf8 0000000000000001 ffff88016dd209e0 0000000000001000
> [  517.595773] Call Trace:
> [  517.598747]  [<ffffffffa043ef95>] raid10d+0xfc5/0x1690 [raid10]
> [  517.605610]  [<ffffffff816697ae>] ? __schedule+0x29e/0x8e2
> [  517.611987]  [<ffffffff814ff206>] md_thread+0x106/0x140
> [  517.618072]  [<ffffffff810c1d80>] ? wait_woken+0x80/0x80
> [  517.624252]  [<ffffffff814ff100>] ? super_1_load+0x520/0x520
> [  517.630817]  [<ffffffff8109ef89>] kthread+0xc9/0xe0
> [  517.636506]  [<ffffffff8109eec0>] ? flush_kthread_worker+0x70/0x70
> [  517.643653]  [<ffffffff8166d99f>] ret_from_fork+0x3f/0x70
> [  517.649929]  [<ffffffff8109eec0>] ? flush_kthread_worker+0x70/0x70
> 
> Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
> ---
>  drivers/md/raid10.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
> index 96f3659..23bbe61 100644
> --- a/drivers/md/raid10.c
> +++ b/drivers/md/raid10.c
> @@ -1944,6 +1944,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
>  
>  	first = i;
>  	fbio = r10_bio->devs[i].bio;
> +	fbio->bi_iter.bi_size = r10_bio->sectors << 9;
> +	fbio->bi_iter.bi_idx = 0;
>  
>  	vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
>  	/* now find blocks with errors */
> @@ -1987,7 +1989,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
>  		bio_reset(tbio);
>  
>  		tbio->bi_vcnt = vcnt;
> -		tbio->bi_iter.bi_size = r10_bio->sectors << 9;
> +		tbio->bi_iter.bi_size = fbio->bi_iter.bi_size;
>  		tbio->bi_rw = WRITE;
>  		tbio->bi_private = r10_bio;
>  		tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;

Looks good. Reviewed-by: Shaohua Li <shli@kernel.org>

A nitpick, I'm wondering if we should do a full reset like raid1 does to make this more clear.

^ permalink raw reply

* Re: [dm-devel] [PATCH 19/32] block: add helper to get data dir from op
From: Bart Van Assche @ 2015-11-04 22:44 UTC (permalink / raw)
  To: device-mapper development, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	drbd-dev-cunTk1MwBs8qoQakbn7OcQ
  Cc: Mike Christie
In-Reply-To: <1446674909-5371-20-git-send-email-mchristi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On 11/04/2015 02:08 PM, mchristi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org wrote:
> From: Mike Christie <mchristi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>
> In later patches the op will no longer be a bitmap, so we will
> not have REQ_WRITE set for all non reads like discard, flush,
> and write same. Drivers will still want to treat them as writes
> for accounting reasons, so this patch adds a helper to translate
> a op to a data direction.
>
> Signed-off-by: Mike Christie <mchristi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>   include/linux/blkdev.h | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index 19c2e94..cf5f518 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -586,6 +586,18 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
>
>   #define list_entry_rq(ptr)	list_entry((ptr), struct request, queuelist)
>
> +/*
> + * Non REQ_OP_WRITE requests like discard, write same, etc, are
> + * considered WRITEs.
> + */
> +static inline int op_to_data_dir(int op)
> +{
> +	if (op == REQ_OP_READ)
> +		return READ;
> +	else
> +		return WRITE;
> +}
> +
>   #define rq_data_dir(rq)		((int)((rq)->cmd_flags & 1))
>
>   /*
>

How about introducing two functions - op_is_write() and op_is_read() ? I 
think that approach will result in shorter and easier to read code in 
the contexts where these functions are used.

Bart.

^ permalink raw reply

* RAID6 reshape stalls immediately
From: Peter Chubb @ 2015-11-04 23:39 UTC (permalink / raw)
  To: linux-raid

Hi Folks,
   I added two disks to my RAID5 array then attempted to reshape it to
   RAID 6.  And it has been sitting on 0% complete, with no disk I/O
   for 24 hours now.

   Is there any way to kick the reshape process?

/proc/mdstat is:

  Personalities : [raid6] [raid5] [raid4] 
  md0 : active raid6 sdi1[6] sdh1[5] sdd1[4] sde1[2] sdb1[1] sda1[0]
      5860122624 blocks super 1.2 level 6, 512k chunk, algorithm 18 [6/5] [UUUU_U]
      [>....................]  reshape =  0.0% (0/1953374208) finish=1308.7min speed=24099K/sec
      bitmap: 0/15 pages [0KB], 65536KB chunk

  unused devices: <none>


What I did:
  mdadm --add /dev/md0 /dev/sdh1
  mdadm --add /dev/md0 /dev/sdi1
  mdadm --grow /dev/md0 --level=6 --raid-devices=6 --backup-file=/root/raid5-backup

dmesg reported:
[691739.298345] md: bind<sdh1>
[691739.364534] RAID conf printout:
[691739.364537]  --- level:5 rd:4 wd:4
[691739.364539]  disk 0, o:1, dev:sda1
[691739.364540]  disk 1, o:1, dev:sdb1
[691739.364541]  disk 2, o:1, dev:sde1
[691739.364542]  disk 3, o:1, dev:sdd1
[691741.832242] md: bind<sdi1>
[691741.898470] RAID conf printout:
[691741.898474]  --- level:5 rd:4 wd:4
[691741.898476]  disk 0, o:1, dev:sda1
[691741.898478]  disk 1, o:1, dev:sdb1
[691741.898480]  disk 2, o:1, dev:sde1
[691741.898481]  disk 3, o:1, dev:sdd1
[691741.898482] RAID conf printout:
[691741.898482]  --- level:5 rd:4 wd:4
[691741.898484]  disk 0, o:1, dev:sda1
[691741.898485]  disk 1, o:1, dev:sdb1
[691741.898486]  disk 2, o:1, dev:sde1
[691741.898487]  disk 3, o:1, dev:sdd1
[691805.469105] md/raid:md0: device sdd1 operational as raid disk 3
[691805.469110] md/raid:md0: device sde1 operational as raid disk 2
[691805.469111] md/raid:md0: device sdb1 operational as raid disk 1
[691805.469112] md/raid:md0: device sda1 operational as raid disk 0
[691805.469551] md/raid:md0: allocated 5424kB
[691805.506035] md/raid:md0: raid level 6 active with 4 out of 5 devices, algori
thm 18
[691805.506050] RAID conf printout:
[691805.506051]  --- level:6 rd:5 wd:4
[691805.506053]  disk 0, o:1, dev:sda1
[691805.506054]  disk 1, o:1, dev:sdb1
[691805.506055]  disk 2, o:1, dev:sde1
[691805.506056]  disk 3, o:1, dev:sdd1
[691805.847329] RAID conf printout:
[691805.847333]  --- level:6 rd:6 wd:5
[691805.847335]  disk 0, o:1, dev:sda1
[691805.847336]  disk 1, o:1, dev:sdb1
[691805.847337]  disk 2, o:1, dev:sde1
[691805.847338]  disk 3, o:1, dev:sdd1
[691805.847340]  disk 4, o:1, dev:sdi1
[691805.847350] RAID conf printout:
[691805.847350]  --- level:6 rd:6 wd:5
[691805.847351]  disk 0, o:1, dev:sda1
[691805.847352]  disk 1, o:1, dev:sdb1
[691805.847353]  disk 2, o:1, dev:sde1
[691805.847354]  disk 3, o:1, dev:sdd1
[691805.847354]  disk 4, o:1, dev:sdi1
[691805.847355]  disk 5, o:1, dev:sdh1
[691805.847424] md: reshape of RAID array md0
[691805.847426] md: minimum _guaranteed_  speed: 1000 KB/sec/disk.
[691805.847428] md: using maximum available idle IO bandwidth (but not more than 200000 KB/sec) for reshape.
[691805.847439] md: using 128k window, over a total of 1953374208k.

And nothing since.
-- 
Dr Peter Chubb				         http://www.data61.csiro.au
http://www.ssrg.nicta.com.au   Software Systems Research Group/NICTA/Data61

^ permalink raw reply

* Re:linux-raid下午好“(AD)
From: zhcbs @ 2015-11-05  2:10 UTC (permalink / raw)
  To: linux-raid

linux-raid
【天猫】尊敬的淘宝会员,您获得了进群资格,邀请您进QQ群号24662898进群验证码60群内每天抢免单秒杀活动,天天免费红包 退订回T 










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































铅汞?当归獐肉。钻天打洞?刘宁宇”三焦俞穴!世界大地测量系统?风成波痕“灵潮若可通!梦断青灯问几更”颅底骨折伴颅内损伤?熊红斌;旋转分流阀:神经介入导丝。基金委员yuan会hui“足五里穴!鸠魔利齿”道乐东方!愿诚:土豪?马鞍西路”圆芽箭竹;马钢股份!而盲者不能自见”闇武刀炎龙”眼不识丁马前卒?江苏江阴市申港镇!公元前九五六四年。神力之药。哈根达斯店务经理”卡到阴:甘泰可欣;

^ permalink raw reply

* Re: Advice requested re: hard drive setup for RAID arrays
From: Brad Campbell @ 2015-11-05  6:02 UTC (permalink / raw)
  To: o1bigtenor, Phil Turmel; +Cc: Linux-RAID
In-Reply-To: <CAPpdf59BqCABOw=gHw=y8zO-xVzFDn30FLbgqFDjmiBzrgAaHA@mail.gmail.com>

On 04/11/15 22:30, o1bigtenor wrote:
>
> Those 2 drives are in a separate USB connected tray.
> When I ran the smartctl* command that you had me run to check the status
> and configuration of the drives it borked on that drive telling me that it was
> connected using USB and I needed to add some other command.

Right. USB is a bit of a strange animal for storage. Different USB-SATA 
interfaces pass or block different commands and it's very vendor 
specific. I'd not have expected that script to work on USB drives 
because it was written to solve *my* particular issue and I don't use 
USB connected drives for anything vaguely critical.

You might be able to get it to work on USB drives, but I'd be very 
surprised if their error recovery behaviour was suitable or deterministic.

This is what it looks like on my system.
root@srv:~# bin/set_sct
/dev/sda  is good Device Model:     SAMSUNG SSD 830 Series
/dev/sdb  is good Device Model:     SAMSUNG SSD 830 Series
/dev/sdc  is good Device Model:     WDC WD20EFRX-68AX9N0
/dev/sdd  is good Device Model:     SAMSUNG SSD 830 Series
/dev/sde  is good Device Model:     WDC WD20EFRX-68EUZN0
/dev/sdf  is good Product:              ST3300655SS
/dev/sdg  is good Product:              ST3300655SS
/dev/sdh  is good Product:              ST3300655SS
/dev/sdi  is good Product:              ST3300655SS
/dev/sdj  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdk  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdl  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdm  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdn  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdo  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdp  is good Device Model:     WDC WD20EFRX-68AX9N0
/dev/sdq  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdr  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sds  is good Device Model:     WDC WD20EFRX-68AX9N0
/dev/sdt  is good Device Model:     WDC WD20EARS-60MVWB0
/dev/sdu  is  bad Device Model:     INTEL SSDSC2CT240A3
/dev/sdv  is  bad Device Model:     INTEL SSDSC2CT240A3
/dev/sdw  is  bad Device Model:     INTEL SSDSC2CT240A3
/dev/sdx  is good Device Model:     WDC WD20EFRX-68AX9N0

Notice all my WD Green drives support ERC. I must have got the very last 
of the drives before they knobbled the firmware.

I iterate *every* drive in the system because every drive in the system 
is part of an array. Again, it was written to scratch my itch and 
possibly serve as an (perhaps bad) example to others.

There are 3 arrays on that system. 6xSSD in a RAID10, 4x15k SAS in a 
RAID10 and 14x2TB SATA in a RAID6. I've experienced catastrophic data 
loss with RAID twice in 10 years. The first time due to a bad IDE 
controller dropping multiple drives and md not being as robust about 
recovery as it is these days (and it was a RADI5), and the second due to 
a SIL PCIe controller silently corrupting writes which gently sprinkled 
corruption across 16TB over a long period. Both times by backups were 
inadequate because I believed RAID==Backup. I know better now.

You need to pay close attention to the whole storage stack to get a 
reliable system. I'd be doing something to replace those USB connections 
with something more suitable, but that's just me.



^ permalink raw reply

* Re: Reconstruct a RAID 6 that has failed in a non typical manner
From: Clement Parisot @ 2015-11-05 10:35 UTC (permalink / raw)
  To: Phil Turmel; +Cc: linux-raid
In-Reply-To: <5633B79D.4000009@turmel.org>

Hello,

First of all, thanks for your answer. Here is an update of what we did:

We got surprised to see two drives that were announced in 'failed' state back in 'working order' after a reboot. At least they were not considered in failed state anymore. So we tried something a bit tricky.
We removed the drive we changed and re-introduced the old one (supposed to be broken)
Thanks to this, we were able to re-create the array with "mdadm --assemble --force /dev/md2", restart the volume group and mount read-only the logical volume.
Sadly, trying to rsync data into a safer place, most of it failed with I/O error, often ending killing the array.
We still have two drives that were not physicaly removed, so that theorically contains datas, but that appears as spare in mdadm --examine, probably because of the 're-add' attempt we made.

> Your subject is inaccurate.  You've described a situation that is
> extraordinarily common when using green drives.  Or any modern desktop
> drive -- they aren't rated for use in raid arrays.  Please read the
> references in the post-script.
After reading your links, it seems that indeed, the situation we experiment is what is described in link [3] or link [6].

> Did you run "mdadm --stop /dev/md2" first?  That would explain the
> "busy" reports.
Yes we did. This is why the 'busy' is surprising. It seems to come from drives:
# mdadm --verbose --assemble /dev/md2
[...]
mdadm: /dev/sdp is identified as a member of /dev/md2, slot 15.
mdadm: /dev/sdo is identified as a member of /dev/md2, slot 14.
mdadm: /dev/sdn is identified as a member of /dev/md2, slot 13.
mdadm: /dev/sdm is identified as a member of /dev/md2, slot 12.
mdadm: /dev/sdl is identified as a member of /dev/md2, slot 11.
mdadm: /dev/sdk is identified as a member of /dev/md2, slot 10.
mdadm: /dev/sdj is identified as a member of /dev/md2, slot 9.
mdadm: /dev/sdi is identified as a member of /dev/md2, slot 8.
mdadm: /dev/sdh is identified as a member of /dev/md2, slot 7.
mdadm: /dev/sdg is identified as a member of /dev/md2, slot -1.
mdadm: /dev/sdf is identified as a member of /dev/md2, slot 5.
mdadm: /dev/sde is identified as a member of /dev/md2, slot 4.
mdadm: /dev/sdc is identified as a member of /dev/md2, slot 2.
mdadm: /dev/sdd is identified as a member of /dev/md2, slot 3.
mdadm: /dev/sdb is identified as a member of /dev/md2, slot -1.
mdadm: /dev/sda is identified as a member of /dev/md2, slot -1.
mdadm: no uptodate device for slot 0 of /dev/md2
mdadm: no uptodate device for slot 1 of /dev/md2
mdadm: added /dev/sdd to /dev/md2 as 3
mdadm: added /dev/sde to /dev/md2 as 4
mdadm: added /dev/sdf to /dev/md2 as 5
mdadm: no uptodate device for slot 6 of /dev/md2
mdadm: added /dev/sdh to /dev/md2 as 7
mdadm: added /dev/sdi to /dev/md2 as 8
mdadm: added /dev/sdj to /dev/md2 as 9
mdadm: added /dev/sdk to /dev/md2 as 10
mdadm: added /dev/sdl to /dev/md2 as 11
mdadm: added /dev/sdm to /dev/md2 as 12
mdadm: added /dev/sdn to /dev/md2 as 13
mdadm: added /dev/sdo to /dev/md2 as 14
mdadm: added /dev/sdp to /dev/md2 as 15
mdadm: added /dev/sdg to /dev/md2 as -1
mdadm: failed to add /dev/sdb to /dev/md2: Device or resource busy
mdadm: failed to add /dev/sda to /dev/md2: Device or resource busy


> Before proceeding, please supply more information:
> 
> for x in /dev/sd[a-p] ; mdadm -E $x ; smartctl -i -A -l scterc $x ; done
> 
> Paste the output inline in your response.


I couldn't get smartctl to work successfully. The version supported on debian squeeze doesn't support aacraid.
I tried from a chroot in a debootstrap with a more recent debian version, but only got:

# smartctl --all -d aacraid,0,0,0 /dev/sda
smartctl 6.4 2014-10-07 r4002 [x86_64-linux-2.6.32-5-amd64] (local build)
Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org

Smartctl open device: /dev/sda [aacraid_disk_00_00_0] [SCSI/SAT] failed: INQUIRY [SAT]: aacraid result: 0.0 = 22/0

Here is the output for mdadm -E:

$ for x in /dev/sd[a-p] ; do sudo mdadm -E $x ; done
/dev/sda:
          Magic : a92b4efc
        Version : 1.2
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 27a0fe11:278b30d3:3251ee70:66b015d0

    Update Time : Wed Oct 28 13:46:13 2015
       Checksum : 5b99bd5 - correct
         Events : 0

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : spare
   Array State : ..AAAA.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdb:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : b58fb9e7:72e48374:44a9862c:5b8de755

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : be982cb8 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 2
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdc:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
:mdadm: No md superblock detected on /dev/sdd.
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 1aff07a9:0ac3fa0c:6bb5e685:bac7893e

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : 5a5fc14a - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 3
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sde:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 30bfa9d2:2a483372:5a489324:c2f5f729

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : 7354c76b - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 5          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 93fd1f09:6ca19143:002a3e5c:17813675

    Update Time : Wed Oct 28 13:46:13 2015
       Checksum : fdacb903 - correct
         Events : 0

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : spare
   Array State : ..AAAA.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdg:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425472 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
    Data Offset : 512 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : d656d255:5ece759c:2deca760:3ae659c3

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : f636719b - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 7
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdh:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : d93661b8:40996a0b:b373cfd8:df0e2bd6

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : 52b2d4a4 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 8
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdi:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : cf9d8d29:42956b39:79841196:9d3281e4

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : bd786c40 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 9
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdj:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : d9ae5754:4b1fffcb:b76d34e4:fed2f192

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : 776990dc - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 10
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)

/dev/sdk:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : e44e950f:09456ec5:35463869:13663a98

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : b662c230 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 11
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdl:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 51b3c930:27332156:535ec2d3:a77cc127

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : 625b436e - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 12
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdm:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 83fa2210:26f430cf:6ef35e86:13be77c8

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : e172228 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 13
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdn:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 6700962b:ed334ee5:98e00751:79f25fb9

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : fb388963 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 14
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdo:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : 9b099832:da80cf49:d62f76d9:7681a6a5

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : db70bdc0 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 15
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)
/dev/sdp:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 2d0b91e8:a0b10f4c:3fa285f9:3198a918
           Name : ftalc2.nancy.grid5000.fr:2  (local to host ftalc2.nancy.grid5000.fr)
  Creation Time : Tue Oct  2 16:28:23 2012
     Raid Level : raid6
   Raid Devices : 16

 Avail Dev Size : 1952425984 (930.99 GiB 999.64 GB)
     Array Size : 27333956608 (13033.85 GiB 13994.99 GB)
  Used Dev Size : 1952425472 (930.99 GiB 999.64 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : df2bcc6a:5d7e060c:6ab4ac39:b11a631f

    Update Time : Wed Nov  4 10:31:19 2015
       Checksum : afcefb47 - correct
         Events : 5834314

         Layout : left-symmetric
     Chunk Size : 128K

   Device Role : Active device 1
   Array State : .AAA.A.AAAAAAAAA ('A' == active, '.' == missing)


Regards,

Clément and Marc
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Reconstruct a RAID 6 that has failed in a non typical manner
From: Phil Turmel @ 2015-11-05 13:34 UTC (permalink / raw)
  To: Clement Parisot; +Cc: linux-raid
In-Reply-To: <1861199271.16131793.1446719750662.JavaMail.zimbra@inria.fr>

Good morning Clément, Marc,

On 11/05/2015 05:35 AM, Clement Parisot wrote:

> We got surprised to see two drives that were announced in 'failed'
> state back in 'working order' after a reboot. At least they were not
> considered in failed state anymore. So we tried something a bit
> tricky.

> We removed the drive we changed and re-introduced the old one
> (supposed to be broken)

> Thanks to this, we were able to re-create the array with "mdadm
> --assemble --force /dev/md2", restart the volume group and mount
> read-only the logical volume.

Strictly speaking, you didn't re-create the array.  Simply re-assembled
it.  The terminology is important here.  Re-creating an array is much
more dangerous.

> Sadly, trying to rsync data into a safer place, most of it failed
> with I/O error, often ending killing the array.

Yes, with latent Unrecoverable Read Errors, you will need properly
working redundancy and no timeout mismatches.  I recommend you
repeatedly use --assemble --force to restore your array, skip the last
file that failed, and continue copying critical files as possible.

You should at least run this command every reboot until you replace your
drives or otherwise script the work-arounds:

for x in /sys/block/*/device/timeout ; do echo 180 > $x ; done

> We still have two drives that were not physicaly removed, so that
> theorically contains datas, but that appears as spare in mdadm
> --examine, probably because of the 're-add' attempt we made.

The only way to activate these, I think, is to re-create your array.
That is a last resort after you've copied everything possible with the
forced assembly state.

>> Your subject is inaccurate.  You've described a situation that is 
>> extraordinarily common when using green drives.  Or any modern
>> desktop drive -- they aren't rated for use in raid arrays.  Please
>> read the references in the post-script.

> After reading your links, it seems that indeed, the situation we
> experiment is what is described in link [3] or link [6].

>> Did you run "mdadm --stop /dev/md2" first?  That would explain the 
>> "busy" reports.

[trim /]

There's *something* holding access to sda and sdb -- please obtain and
run "lsdrv" [1] and post its output.

>> Before proceeding, please supply more information:
>> 
>> for x in /dev/sd[a-p] ; mdadm -E $x ; smartctl -i -A -l scterc $x ;
>> done
>> 
>> Paste the output inline in your response.
> 
> 
> I couldn't get smartctl to work successfully. The version supported
> on debian squeeze doesn't support aacraid.

> I tried from a chroot in a debootstrap with a more recent debian
> version, but only got:
> 
> # smartctl --all -d aacraid,0,0,0 /dev/sda

> smartctl 6.4 2014-10-07 r4002 [x86_64-linux-2.6.32-5-amd64] (local
> build)

> Copyright (C) 2002-14, Bruce Allen, Christian Franke,
> www.smartmontools.org
> 
> Smartctl open device: /dev/sda [aacraid_disk_00_00_0] [SCSI/SAT]
> failed: INQUIRY [SAT]: aacraid result: 0.0 = 22/0

It's possible the 0,0,0 isn't correct.  The output of lsdrv would help
with this.

Also, please use the smartctl options I requested.  '--all' omits the
scterc information I want to see, and shows a bunch of data I don't need
to see.  If you want all possible data for your own use, '-x' is the
correct option.

[trim /]

It's very important that we get a map of drive serial numbers to current
device names and the "Device Role" from "mdadm --examine".  As an
alternative, post the output of "ls -l /dev/disk/by-id/".  This is
critical information for any future re-create attempts.

The rest of the information from smartctl is important, and you should
upgrade your system to a level that supports it, but it can wait for later.

It might be best to boot into a newer environment strictly for this
recovery task.  Newer kernels and utilities have more bugfixes and are
much more robust in emergencies.  I normally use SystemRescueCD [2] for
emergencies like this.

Phil

[1] https://github.com/pturmel/lsdrv
[2] http://www.sysresccd.org/

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* You have new fax, document 00301442
From: Interfax @ 2015-11-05 14:18 UTC (permalink / raw)
  To: linux-raid

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

You have received a new fax.

To view it please open the attachment.

Pages number:        13
Author:              Fernando Shoemaker
Date:                Thu, 5 Nov 2015 14:28:10 +0300
Scan time:           54 seconds
Scan quality:        400 DPI
Filesize:            235 Kb
File name:           fax-00301442.doc

Thanks for using Interfax service!


[-- Attachment #2: fax-00301442.zip --]
[-- Type: application/zip, Size: 1663 bytes --]

^ permalink raw reply

* Re: [RESEND RFC PATCH 00/32] separate operations from flags in the bio/request structs
From: Bob Peterson @ 2015-11-05 16:44 UTC (permalink / raw)
  To: mchristi
  Cc: linux-fsdevel, dm-devel, linux-raid, linux-kernel, linux-scsi,
	drbd-dev
In-Reply-To: <1446674909-5371-1-git-send-email-mchristi@redhat.com>

----- Original Message -----
> This is just a resend of the patchset from earlier today. There was
> a error in the middle of sending the set, so it looks like 10 - 32 got
> dropped.
> 
> There are a couple new block layer commands we are trying to add support
> for in the near term:
> 
> compare and write
> http://www.spinics.net/lists/target-devel/msg07826.html
> 
> copy offload/extended copy/xcopy
> https://www.redhat.com/archives/dm-devel/2014-July/msg00070.html
> 
> The problem is if we contine to add more commands we will have to one day
> extend the cmd_flags/bi_rw fields again. To prevent that, this patchset
> separates the operation (REQ_WRITE, REQ_DISCARD, REQ_WRITE_SAME, etc) from
> the flags (REQ_SYNC, REQ_QUIET, etc) in the bio and request structs. In the
> end of this set, we will have two fields bio->bi_op/request->op and
> bio->bi_rw/request->cmd_flags.
> 
> The patches were made against Jens's linux-block tree's for-linus branch:
> https://git.kernel.org/cgit/linux/kernel/git/axboe/linux-block.git/log/?h=for-linus
> (last commit a22c4d7e34402ccdf3414f64c50365436eba7b93).
> 
> I have done some basic testing for a lot of the drivers and filesystems,
> but I wanted to get comments before trying to track down more hardware/
> systems for testing.
> 
> 
> Known issues:
> - REQ_FLUSH is still a flag, but should probably be a operation.
>  For lower level drivers like SCSI where we only get a flush, it makes
> more sense to be a operation. However, upper layers like filesystems
> can send down flushes with writes, so it is more of a flag for them.
> I am still working on this.
> 
> - There is a regression with the dm flakey target. It currently
> cannot corrupt the operation values.
> 
> - The patchset is a little awkward. It touches so much code,
> but I wanted to maintain git bisectibility, so there is lots of compat code
> left around until the last patches where everyting is cleaned up.

Hi Mike,

The GFS2 patches in patches 11, 14, 16 and 23 all look correct.
You can add my:
Reviewed-by: Bob Peterson <rpeterso@redhat.com>
to those, but I have not reviewed the non-GFS2 bits.

Regards,

Bob Peterson
Red Hat File Systems

^ permalink raw reply

* (unknown), 
From: o1bigtenor @ 2015-11-05 16:49 UTC (permalink / raw)
  To: Linux-RAID

help

^ permalink raw reply

* Re: [dm-devel] [PATCH 19/32] block: add helper to get data dir from op
From: Mike Christie @ 2015-11-05 17:34 UTC (permalink / raw)
  To: Bart Van Assche, device-mapper development, linux-fsdevel,
	linux-raid, linux-kernel, linux-scsi, drbd-dev
In-Reply-To: <563A8A33.3000002@sandisk.com>

On 11/04/2015 04:44 PM, Bart Van Assche wrote:
> On 11/04/2015 02:08 PM, mchristi@redhat.com wrote:
>> From: Mike Christie <mchristi@redhat.com>
>>
>> In later patches the op will no longer be a bitmap, so we will
>> not have REQ_WRITE set for all non reads like discard, flush,
>> and write same. Drivers will still want to treat them as writes
>> for accounting reasons, so this patch adds a helper to translate
>> a op to a data direction.
>>
>> Signed-off-by: Mike Christie <mchristi@redhat.com>
>> ---
>>   include/linux/blkdev.h | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
>> index 19c2e94..cf5f518 100644
>> --- a/include/linux/blkdev.h
>> +++ b/include/linux/blkdev.h
>> @@ -586,6 +586,18 @@ static inline void queue_flag_clear(unsigned int
>> flag, struct request_queue *q)
>>
>>   #define list_entry_rq(ptr)    list_entry((ptr), struct request,
>> queuelist)
>>
>> +/*
>> + * Non REQ_OP_WRITE requests like discard, write same, etc, are
>> + * considered WRITEs.
>> + */
>> +static inline int op_to_data_dir(int op)
>> +{
>> +    if (op == REQ_OP_READ)
>> +        return READ;
>> +    else
>> +        return WRITE;
>> +}
>> +
>>   #define rq_data_dir(rq)        ((int)((rq)->cmd_flags & 1))
>>
>>   /*
>>
> 
> How about introducing two functions - op_is_write() and op_is_read() ? I
> think that approach will result in shorter and easier to read code in
> the contexts where these functions are used.
> 

I can do that. You are right in how they are used. I just did the above,
to follow the other *_data_dir calls.


^ permalink raw reply

* Re: looking for good reference on storage configuration
From: Ladislav Mate @ 2015-11-05 17:44 UTC (permalink / raw)
  To: Miles Fidelman; +Cc: linux-raid@vger.kernel.org
In-Reply-To: <56277E47.9070003@meetinghouse.net>

On Wed, Oct 21, 2015 at 2:00 PM, Miles Fidelman
<mfidelman@meetinghouse.net> wrote:
> Hi Folks,
>
> Perhaps someone here might be able to point me at a reference or two on
> alternatives and best practices for configuring storage for a server - using
> a mix of SSDs and conventional drives.
>
> I'm in the process of upgrading a small cluster of 4 machines - each
> containing RAID arrays, with DRBD across clusters to support failover.  Easy
> enough with a uniform collection of HDDs.  But I can't get my head around
> how to add SSDs into the mix - what with the mismatch in access speeds and
> all, it would seem like one needs a more complex configuration with a level
> of caching between the faster and slower media.
>
> Seems like someone would have written a book, or tutorial, or case study, or
> conference presentation - but damned if I can find anything.  Any pointers,
> or guidance, would be much appreciated.
>
> Thanks,
>
> Miles Fidelman
>
> --
> In theory, there is no difference between theory and practice.
> In practice, there is.   .... Yogi Berra
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Hi Miles,
might me long shot, but can take a look on LVM caching..
Good description how to setup it is here :
http://blog-vpodzime.rhcloud.com/?p=45
Working for me for months now.... without DRBD.
HTH,

--
Ladislav Máte
--
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: looking for good reference on storage configuration
From: Miles Fidelman @ 2015-11-05 17:59 UTC (permalink / raw)
  To: Ladislav Mate; +Cc: linux-raid@vger.kernel.org
In-Reply-To: <CAG--WThaDTXk9udk=bfp8_mR+CzLgTdkNadWTfvh0nxUrpt+Pw@mail.gmail.com>

Thanks Ladislav - that gives me a starting point!

Best,

Miles

On 11/5/15 12:44 PM, Ladislav Mate wrote:
> On Wed, Oct 21, 2015 at 2:00 PM, Miles Fidelman
> <mfidelman@meetinghouse.net> wrote:
>> Hi Folks,
>>
>> Perhaps someone here might be able to point me at a reference or two on
>> alternatives and best practices for configuring storage for a server - using
>> a mix of SSDs and conventional drives.
>>
>> I'm in the process of upgrading a small cluster of 4 machines - each
>> containing RAID arrays, with DRBD across clusters to support failover.  Easy
>> enough with a uniform collection of HDDs.  But I can't get my head around
>> how to add SSDs into the mix - what with the mismatch in access speeds and
>> all, it would seem like one needs a more complex configuration with a level
>> of caching between the faster and slower media.
>>
>> Seems like someone would have written a book, or tutorial, or case study, or
>> conference presentation - but damned if I can find anything.  Any pointers,
>> or guidance, would be much appreciated.
>>
>> Thanks,
>>
>> Miles Fidelman
>>
>> --
>> In theory, there is no difference between theory and practice.
>> In practice, there is.   .... Yogi Berra
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Hi Miles,
> might me long shot, but can take a look on LVM caching..
> Good description how to setup it is here :
> http://blog-vpodzime.rhcloud.com/?p=45
> Working for me for months now.... without DRBD.
> HTH,
>
> --
> Ladislav Máte
> --
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
In theory, there is no difference between theory and practice.
In practice, there is.  .... Yogi Berra

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: raid6 stuck at reshape
From: Иван Исаев @ 2015-11-05 19:30 UTC (permalink / raw)
  To: Xiao Ni, linux-raid
In-Reply-To: <1721474289.3226622.1446622586738.JavaMail.zimbra@redhat.com>

Thanks Xiao Ni I found a reason.

I did debug the mdadm process: progress_reshape always returns 1.
Therefore done in child_monitor never becomes 1. And while (!done) { }
of child_monitor become infinity loop. In general, the reason is
backup. need_backup > info->reshape_progress in my case always true.
(gdb) p need_backup
$14 = 212992
(gdb) p info->reshape_progress
$15 = 81920

#mdadm --grow /dev/md3 --raid-devices=12 (without backup-file)
proccess of reshape is proceeding normally now:
[>....................]  reshape =  0.1% (3152844/2925383680)
finish=4832.4min speed=10078K/sec

Obviously, it's bug in user space of mdadm.

2015-11-04 14:36 GMT+07:00 Xiao Ni <xni@redhat.com>:
>
> When you run ps auxf | grep md, can you see a progress is stuck?
> If you find it you can check the reason with crash utility.
>
>
> ----- Original Message -----
>> From: "Иван Исаев" <1@crownet.ru>
>> To: linux-raid@vger.kernel.org
>> Sent: Wednesday, November 4, 2015 2:44:10 PM
>> Subject: Fwd: raid6 stuck at reshape
>>
>> 1.  cat /sys/block/md3/md/sync_max
>> 8192
>> 2. no selinux
>> 3.
>> after recreate of array:
>> # mdadm --grow --bitmap=none /dev/md3
>> # mdadm --grow /dev/md3 --raid-devices=12 --backup-file=/home/raid/md3.backup
>> mdadm: Need to backup 106496K of critical section..
>> mdadm: Recording backup file in /run/mdadm failed: File exists
>> ...
>> # cat /proc/mdstat
>> Personalities : [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] [linear]
>> md3 : active raid6 sdn[11] sdm[10] sdl[9] sdj[8] sdg[7] sdh[6] sdi[5]
>> sdk[4] sdf[3] sde[2] sdd[1] sdc[0]
>>       26328453120 blocks super 1.2 level 6, 4096k chunk, algorithm 2
>> [12/12] [UUUUUUUUUUUU]
>>       [>....................]  reshape =  0.0% (_4096_/2925383680)
>> finish=3758695.2min speed=12K/sec
>>
>> no changes.
>>
>> 2015-11-04 13:25 GMT+07:00 Xiao Ni <xni@redhat.com>:
>> > Hi
>> >
>> > You can check the sync_max whether it's 0.
>> >
>> > [root@storageqe-19 ~]# cd /sys/block/md1/md/
>> > [root@storageqe-19 md]# cat sync_max
>> > 0
>> >
>> > And check selinux:
>> > [root@storageqe-19 ~]# systemctl status mdadm-grow-continue@md1.service
>> > ● mdadm-grow-continue@md1.service - Manage MD Reshape on /dev/md1
>> >    Loaded: loaded (/usr/lib/systemd/system/mdadm-grow-continue@.service;
>> >    static; vendor preset: disabled)
>> >    Active: failed (Result: exit-code) since Tue 2015-11-03 03:39:11 EST;
>> >    21h ago
>> >   Process: 2353 ExecStart=/usr/sbin/mdadm --grow --continue /dev/%I
>> >   (code=exited, status=2)
>> >  Main PID: 2353 (code=exited, status=2)
>> >
>> > Nov 03 03:39:10 storageqe-19.rhts.eng.bos.redhat.com systemd[1]: Started
>> > Manage MD Reshape on /dev/md1.
>> > Nov 03 03:39:10 storageqe-19.rhts.eng.bos.redhat.com systemd[1]: Starting
>> > Manage MD Reshape on /dev/md1...
>> > Nov 03 03:39:11 storageqe-19.rhts.eng.bos.redhat.com systemd[1]:
>> > mdadm-grow-continue@md1.service: main process exite...ENT
>> > Nov 03 03:39:11 storageqe-19.rhts.eng.bos.redhat.com systemd[1]: Unit
>> > mdadm-grow-continue@md1.service entered failed...te.
>> > Nov 03 03:39:11 storageqe-19.rhts.eng.bos.redhat.com systemd[1]:
>> > mdadm-grow-continue@md1.service failed.
>> > Hint: Some lines were ellipsized, use -l to show in full.
>> >
>> > I think this is a selinux-policy problem. And you can try reshape a md
>> > without bitmap.
>> > It can success without bitmap.
>> >
>> > ----- Original Message -----
>> >> From: "Иван Исаев" <1@crownet.ru>
>> >> To: linux-raid@vger.kernel.org
>> >> Sent: Wednesday, November 4, 2015 1:53:17 PM
>> >> Subject: raid6 stuck at reshape
>> >>
>> >> 1. init state:
>> >> md3 : active raid6 sdm[10] sdl[9] sdj[8] sdg[7] sdh[6] sdi[5] sdk[4]
>> >> sdf[3] sde[2] sdd[1] sdc[0]
>> >>       26328453120 blocks super 1.2 level 6, 4096k chunk, algorithm 2
>> >> [11/11] [UUUUUUUUUUU]
>> >>       bitmap: 0/22 pages [0KB], 65536KB chunk
>> >>
>> >> 2. mdadm /dev/md3 -a /dev/sdn
>> >> mdadm --grow /dev/md3 --raid-devices=12
>> >> --backup-file=/home/raid/md3.backup
>> >>
>> >> md3 : active raid6 sdn[11] sdm[10] sdl[9] sdj[8] sdg[7] sdh[6] sdi[5]
>> >> sdk[4] sdf[3] sde[2] sdd[1] sdc[0]
>> >>       26328453120 blocks super 1.2 level 6, 4096k chunk, algorithm 2
>> >> [12/12] [UUUUUUUUUUUU]
>> >>       [>....................]  reshape =  0.0% (0/2925383680)
>> >> finish=3047274.6min speed=0K/sec
>> >>       bitmap: 0/22 pages [0KB], 65536KB chunk
>> >>
>> >> # ps aux|grep md3
>> >> root      5232 _54.8_  0.0      0     0 ?        R    10:55  56:43
>> >> [md3_raid6]
>> >> root      6956 _98.4_  0.4  53904 49896 ?        RL   11:01  96:29
>> >> mdadm --grow /dev/md3 --raid-devices=12
>> >> --backup-file=/home/raid/md3.backup
>> >>
>> >> # cat /sys/block/md3/md/reshape_position
>> >> 81920
>> >>
>> >> what can I do about it?
>> >>
>> >> P.S. If I stop the array, it can no longer be assembled:
>> >> # mdadm -S /dev/md3
>> >> # mdadm -A /dev/md3
>> >> mdadm: :/dev/md3 has an active reshape - checking if critical section
>> >> needs to be restored
>> >> mdadm: Failed to restore critical section for reshape, sorry.
>> >>
>> >> mdadm --assemble /dev/md3 -vv --backup-file /home/raid/md3.backup -f
>> >> mdadm: looking for devices for /dev/md3
>> >> ...
>> >> mdadm: /dev/sdn is identified as a member of /dev/md3, slot 11.
>> >> mdadm: /dev/sdl is identified as a member of /dev/md3, slot 9.
>> >> mdadm: /dev/sdg is identified as a member of /dev/md3, slot 7.
>> >> mdadm: /dev/sdm is identified as a member of /dev/md3, slot 10.
>> >> mdadm: /dev/sdj is identified as a member of /dev/md3, slot 8.
>> >> mdadm: /dev/sdk is identified as a member of /dev/md3, slot 4.
>> >> mdadm: /dev/sdf is identified as a member of /dev/md3, slot 3.
>> >> mdadm: /dev/sdd is identified as a member of /dev/md3, slot 1.
>> >> mdadm: /dev/sdi is identified as a member of /dev/md3, slot 5.
>> >> mdadm: /dev/sdh is identified as a member of /dev/md3, slot 6.
>> >> mdadm: /dev/sde is identified as a member of /dev/md3, slot 2.
>> >> mdadm: /dev/sdc is identified as a member of /dev/md3, slot 0.
>> >> mdadm: :/dev/md3 has an active reshape - checking if critical section
>> >> needs to be restored
>> >> mdadm: restoring critical section
>> >> mdadm: Error restoring backup from md3.backup
>> >> mdadm: Failed to restore critical section for reshape, sorry.
>> >>
>> >> # mdadm --assemble /dev/md3 -vv --invalid-backup -f
>> >> ...
>> >> mdadm: :/dev/md3 has an active reshape - checking if critical section
>> >> needs to be restored
>> >> mdadm: No backup metadata on device-11
>> >> mdadm: Failed to find backup of critical section
>> >> mdadm: continuing without restoring backup
>> >> mdadm: added /dev/sdd to /dev/md3 as 1
>> >> mdadm: added /dev/sde to /dev/md3 as 2
>> >> mdadm: added /dev/sdf to /dev/md3 as 3
>> >> mdadm: added /dev/sdk to /dev/md3 as 4
>> >> mdadm: added /dev/sdi to /dev/md3 as 5
>> >> mdadm: added /dev/sdh to /dev/md3 as 6
>> >> mdadm: added /dev/sdg to /dev/md3 as 7
>> >> mdadm: added /dev/sdj to /dev/md3 as 8
>> >> mdadm: added /dev/sdl to /dev/md3 as 9
>> >> mdadm: added /dev/sdm to /dev/md3 as 10
>> >> mdadm: added /dev/sdn to /dev/md3 as 11
>> >> mdadm: added /dev/sdc to /dev/md3 as 0
>> >> mdadm: failed to RUN_ARRAY /dev/md3: Invalid argument
>> >>
>> >> I had to create array again.
>> >> After that the array is operating normally, but I still can't grow it.
>> >>
>> >> P.S.S. kernel: 3.14.56
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
>> >> the body of a message to majordomo@vger.kernel.org
>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] md/raid5: remove redundant check in stripe_add_to_batch_list()
From: Neil Brown @ 2015-11-06  0:42 UTC (permalink / raw)
  To: linux-kernel; +Cc: Roman Gushchin, linux-raid
In-Reply-To: <1446458813-6502-1-git-send-email-klamm@yandex-team.ru>

[-- Attachment #1: Type: text/plain, Size: 1551 bytes --]

On Mon, Nov 02 2015, Roman Gushchin wrote:

> The stripe_add_to_batch_list() function is called only if
> stripe_can_batch() returned true, so there is no need for double check.
>
> Signed-off-by: Roman Gushchin <klamm@yandex-team.ru>
> Cc: Neil Brown <neilb@suse.com>
> Cc: linux-raid@vger.kernel.org
> ---
>  drivers/md/raid5.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 45933c1..f829ebc 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -768,8 +768,6 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh
>  	int hash;
>  	int dd_idx;
>  
> -	if (!stripe_can_batch(sh))
> -		return;
>  	/* Don't cross chunks, so stripe pd_idx/qd_idx is the same */
>  	tmp_sec = sh->sector;
>  	if (!sector_div(tmp_sec, conf->chunk_sectors))
> -- 
> 2.4.3

applied, thanks.

(for future reference, public mailing lists like linux-raid aren't
usually mentioned on a 'Cc:' line in a patch.
Documentation/SubmittingPatches suggests:

  If a person has had the opportunity to comment on a patch, but has not
  provided such comments, you may optionally add a "Cc:" tag to the patch.
  This is the only tag which might be added without an explicit action by the
  person it names - but it should indicate that this person was copied on the
  patch.  This tag documents that potentially interested parties
  have been included in the discussion.

so it is primarily for third-party individuals
)

Thanks,
NeilBrown

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox