f2fs: resolve op and op_flags confilcts

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Jaegeuk Kim 2017-01-11 18:24:54 -08:00
parent 1dad3b6a0f
commit e27aa59132
9 changed files with 98 additions and 53 deletions

View File

@ -64,14 +64,15 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
struct f2fs_io_info fio = {
.sbi = sbi,
.type = META,
.rw = READ_SYNC | REQ_META | REQ_PRIO,
.op = REQ_OP_READ,
.op_flags = REQ_SYNC | REQ_META | REQ_PRIO,
.old_blkaddr = index,
.new_blkaddr = index,
.encrypted_page = NULL,
};
if (unlikely(!is_meta))
fio.rw &= ~REQ_META;
fio.op_flags &= ~REQ_META;
repeat:
page = f2fs_grab_cache_page(mapping, index, false);
if (!page) {
@ -159,13 +160,15 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
struct f2fs_io_info fio = {
.sbi = sbi,
.type = META,
.rw = sync ? (READ_SYNC | REQ_META | REQ_PRIO) : READA,
.op = REQ_OP_READ,
.op_flags = sync ? (REQ_SYNC | REQ_META | REQ_PRIO) :
REQ_RAHEAD,
.encrypted_page = NULL,
};
struct blk_plug plug;
if (unlikely(type == META_POR))
fio.rw &= ~REQ_META;
fio.op_flags &= ~REQ_META;
blk_start_plug(&plug);
for (; nrpages-- > 0; blkno++) {

View File

@ -168,15 +168,15 @@ static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr,
return bio;
}
static inline void __submit_bio(struct f2fs_sb_info *sbi, int rw,
struct bio *bio, enum page_type type)
static inline void __submit_bio(struct f2fs_sb_info *sbi,
struct bio *bio, enum page_type type)
{
if (!is_read_io(rw)) {
if (!is_read_io(bio_op(bio))) {
if (f2fs_sb_mounted_blkzoned(sbi->sb) &&
current->plug && (type == DATA || type == NODE))
blk_finish_plug(current->plug);
}
submit_bio(rw, bio);
submit_bio(0, bio);
}
static void __submit_merged_bio(struct f2fs_bio_info *io)
@ -186,12 +186,14 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
if (!io->bio)
return;
if (is_read_io(fio->rw))
if (is_read_io(fio->op))
trace_f2fs_submit_read_bio(io->sbi->sb, fio, io->bio);
else
trace_f2fs_submit_write_bio(io->sbi->sb, fio, io->bio);
__submit_bio(io->sbi, fio->rw, io->bio, fio->type);
bio_set_op_attrs(io->bio, fio->op, fio->op_flags);
__submit_bio(io->sbi, io->bio, fio->type);
io->bio = NULL;
}
@ -257,10 +259,10 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
/* change META to META_FLUSH in the checkpoint procedure */
if (type >= META_FLUSH) {
io->fio.type = META_FLUSH;
if (test_opt(sbi, NOBARRIER))
io->fio.rw = WRITE_FLUSH | REQ_META | REQ_PRIO;
else
io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO;
io->fio.op = REQ_OP_WRITE;
io->fio.op_flags = WRITE_FLUSH | REQ_META | REQ_PRIO;
if (!test_opt(sbi, NOBARRIER))
io->fio.op_flags |= REQ_FUA;
}
__submit_merged_bio(io);
out:
@ -302,14 +304,15 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
f2fs_trace_ios(fio, 0);
/* Allocate a new bio */
bio = __bio_alloc(fio->sbi, fio->new_blkaddr, 1, is_read_io(fio->rw));
bio = __bio_alloc(fio->sbi, fio->new_blkaddr, 1, is_read_io(fio->op));
if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
bio_put(bio);
return -EFAULT;
}
bio_set_op_attrs(bio, fio->op, fio->op_flags);
__submit_bio(fio->sbi, fio->rw, bio, fio->type);
__submit_bio(fio->sbi, bio, fio->type);
return 0;
}
@ -318,7 +321,7 @@ void f2fs_submit_page_mbio(struct f2fs_io_info *fio)
struct f2fs_sb_info *sbi = fio->sbi;
enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
struct f2fs_bio_info *io;
bool is_read = is_read_io(fio->rw);
bool is_read = is_read_io(fio->op);
struct page *bio_page;
io = is_read ? &sbi->read_io : &sbi->write_io[btype];
@ -335,7 +338,7 @@ void f2fs_submit_page_mbio(struct f2fs_io_info *fio)
down_write(&io->io_rwsem);
if (io->bio && (io->last_block_in_bio != fio->new_blkaddr - 1 ||
(io->fio.rw != fio->rw) ||
(io->fio.op != fio->op || io->fio.op_flags != fio->op_flags) ||
!__same_bdev(sbi, fio->new_blkaddr, io->bio)))
__submit_merged_bio(io);
alloc_new:
@ -463,7 +466,7 @@ int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index)
}
struct page *get_read_data_page(struct inode *inode, pgoff_t index,
int rw, bool for_write)
int op_flags, bool for_write)
{
struct address_space *mapping = inode->i_mapping;
struct dnode_of_data dn;
@ -473,7 +476,8 @@ struct page *get_read_data_page(struct inode *inode, pgoff_t index,
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(inode),
.type = DATA,
.rw = rw,
.op = REQ_OP_READ,
.op_flags = op_flags,
.encrypted_page = NULL,
};
@ -541,7 +545,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index)
return page;
f2fs_put_page(page, 0);
page = get_read_data_page(inode, index, READ_SYNC, false);
page = get_read_data_page(inode, index, REQ_SYNC, false);
if (IS_ERR(page))
return page;
@ -567,7 +571,7 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index,
struct address_space *mapping = inode->i_mapping;
struct page *page;
repeat:
page = get_read_data_page(inode, index, READ_SYNC, for_write);
page = get_read_data_page(inode, index, REQ_SYNC, for_write);
if (IS_ERR(page))
return page;
@ -1145,7 +1149,7 @@ got_it:
if (bio && (last_block_in_bio != block_nr - 1 ||
!__same_bdev(F2FS_I_SB(inode), block_nr, bio))) {
submit_and_realloc:
__submit_bio(F2FS_I_SB(inode), READ, bio, DATA);
__submit_bio(F2FS_I_SB(inode), bio, DATA);
bio = NULL;
}
if (bio == NULL) {
@ -1154,6 +1158,7 @@ submit_and_realloc:
bio = NULL;
goto set_error_page;
}
bio_set_op_attrs(bio, REQ_OP_READ, 0);
}
if (bio_add_page(bio, page, blocksize, 0) < blocksize)
@ -1168,7 +1173,7 @@ set_error_page:
goto next_page;
confused:
if (bio) {
__submit_bio(F2FS_I_SB(inode), READ, bio, DATA);
__submit_bio(F2FS_I_SB(inode), bio, DATA);
bio = NULL;
}
unlock_page(page);
@ -1178,7 +1183,7 @@ next_page:
}
BUG_ON(pages && !list_empty(pages));
if (bio)
__submit_bio(F2FS_I_SB(inode), READ, bio, DATA);
__submit_bio(F2FS_I_SB(inode), bio, DATA);
return 0;
}
@ -1296,7 +1301,8 @@ static int f2fs_write_data_page(struct page *page,
struct f2fs_io_info fio = {
.sbi = sbi,
.type = DATA,
.rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC : WRITE,
.op = REQ_OP_WRITE,
.op_flags = wbc_to_write_flags(wbc),
.page = page,
.encrypted_page = NULL,
};
@ -1718,14 +1724,14 @@ repeat:
err = PTR_ERR(bio);
goto fail;
}
bio->bi_rw = READ_SYNC;
if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
bio_put(bio);
err = -EFAULT;
goto fail;
}
__submit_bio(sbi, READ_SYNC, bio, DATA);
__submit_bio(sbi, bio, DATA);
lock_page(page);
if (unlikely(page->mapping != mapping)) {

View File

@ -24,6 +24,7 @@
#include <linux/blkdev.h>
#include <linux/fscrypto.h>
#include <crypto/hash.h>
#include <linux/writeback.h>
#ifdef CONFIG_F2FS_CHECK_FS
#define f2fs_bug_on(sbi, condition) BUG_ON(condition)
@ -113,6 +114,24 @@ struct f2fs_mount_info {
#define F2FS_CLEAR_FEATURE(sb, mask) \
F2FS_SB(sb)->raw_super->feature &= ~cpu_to_le32(mask)
/* bio stuffs */
#define REQ_OP_READ READ
#define REQ_OP_WRITE WRITE
#define bio_op(bio) ((bio)->bi_rw & 1)
static inline void bio_set_op_attrs(struct bio *bio, unsigned op,
unsigned op_flags)
{
bio->bi_rw = op | op_flags;
}
static inline int wbc_to_write_flags(struct writeback_control *wbc)
{
if (wbc->sync_mode == WB_SYNC_ALL)
return REQ_SYNC | REQ_NOIDLE;
return 0;
}
static inline void inode_lock(struct inode *inode)
{
mutex_lock(&inode->i_mutex);
@ -759,14 +778,15 @@ enum page_type {
struct f2fs_io_info {
struct f2fs_sb_info *sbi; /* f2fs_sb_info pointer */
enum page_type type; /* contains DATA/NODE/META/META_FLUSH */
int rw; /* contains R/RS/W/WS with REQ_META/REQ_PRIO */
int op; /* contains REQ_OP_ */
int op_flags; /* req_flag_bits */
block_t new_blkaddr; /* new block address to be written */
block_t old_blkaddr; /* old block address before Cow */
struct page *page; /* page to be written */
struct page *encrypted_page; /* encrypted page */
};
#define is_read_io(rw) (((rw) & 1) == READ)
#define is_read_io(rw) (rw == READ)
struct f2fs_bio_info {
struct f2fs_sb_info *sbi; /* f2fs superblock */
struct bio *bio; /* bios to merge */

View File

@ -550,7 +550,8 @@ static void move_encrypted_block(struct inode *inode, block_t bidx,
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(inode),
.type = DATA,
.rw = READ_SYNC,
.op = REQ_OP_READ,
.op_flags = REQ_SYNC,
.encrypted_page = NULL,
};
struct dnode_of_data dn;
@ -627,7 +628,8 @@ static void move_encrypted_block(struct inode *inode, block_t bidx,
/* allocate block address */
f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
fio.rw = WRITE_SYNC;
fio.op = REQ_OP_WRITE;
fio.op_flags = REQ_SYNC | REQ_NOIDLE;
fio.new_blkaddr = newaddr;
f2fs_submit_page_mbio(&fio);
@ -668,7 +670,8 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type,
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(inode),
.type = DATA,
.rw = WRITE_SYNC,
.op = REQ_OP_WRITE,
.op_flags = REQ_SYNC | REQ_NOIDLE,
.page = page,
.encrypted_page = NULL,
};
@ -767,7 +770,8 @@ next_step:
start_bidx = start_bidx_of_node(nofs, inode);
data_page = get_read_data_page(inode,
start_bidx + ofs_in_node, READA, true);
start_bidx + ofs_in_node, REQ_RAHEAD,
true);
if (IS_ERR(data_page)) {
iput(inode);
continue;

View File

@ -110,7 +110,8 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(dn->inode),
.type = DATA,
.rw = WRITE_SYNC | REQ_PRIO,
.op = REQ_OP_WRITE,
.op_flags = REQ_SYNC | REQ_NOIDLE | REQ_PRIO,
.page = page,
.encrypted_page = NULL,
};

View File

@ -1078,14 +1078,15 @@ fail:
* 0: f2fs_put_page(page, 0)
* LOCKED_PAGE or error: f2fs_put_page(page, 1)
*/
static int read_node_page(struct page *page, int rw)
static int read_node_page(struct page *page, int op_flags)
{
struct f2fs_sb_info *sbi = F2FS_P_SB(page);
struct node_info ni;
struct f2fs_io_info fio = {
.sbi = sbi,
.type = NODE,
.rw = rw,
.op = REQ_OP_READ,
.op_flags = op_flags,
.page = page,
.encrypted_page = NULL,
};
@ -1126,7 +1127,7 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid)
if (!apage)
return;
err = read_node_page(apage, READA);
err = read_node_page(apage, REQ_RAHEAD);
f2fs_put_page(apage, err ? 1 : 0);
}
@ -1144,7 +1145,7 @@ repeat:
if (!page)
return ERR_PTR(-ENOMEM);
err = read_node_page(page, READ_SYNC);
err = read_node_page(page, REQ_SYNC);
if (err < 0) {
f2fs_put_page(page, 1);
return ERR_PTR(err);
@ -1592,7 +1593,8 @@ static int f2fs_write_node_page(struct page *page,
struct f2fs_io_info fio = {
.sbi = sbi,
.type = NODE,
.rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC : WRITE,
.op = REQ_OP_WRITE,
.op_flags = wbc_to_write_flags(wbc),
.page = page,
.encrypted_page = NULL,
};

View File

@ -316,7 +316,8 @@ static int __commit_inmem_pages(struct inode *inode,
struct f2fs_io_info fio = {
.sbi = sbi,
.type = DATA,
.rw = WRITE_SYNC | REQ_PRIO,
.op = REQ_OP_WRITE,
.op_flags = REQ_SYNC | REQ_NOIDLE | REQ_PRIO,
.encrypted_page = NULL,
};
bool submit_bio = false;
@ -466,6 +467,7 @@ static int __submit_flush_wait(struct block_device *bdev)
struct bio *bio = f2fs_bio_alloc(0);
int ret;
bio->bi_rw = REQ_OP_WRITE;
bio->bi_bdev = bdev;
ret = submit_bio_wait(WRITE_FLUSH, bio);
bio_put(bio);
@ -1603,7 +1605,8 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
struct f2fs_io_info fio = {
.sbi = sbi,
.type = META,
.rw = WRITE_SYNC | REQ_META | REQ_PRIO,
.op = REQ_OP_WRITE,
.op_flags = REQ_SYNC | REQ_NOIDLE | REQ_META | REQ_PRIO,
.old_blkaddr = page->index,
.new_blkaddr = page->index,
.page = page,
@ -1611,7 +1614,7 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
};
if (unlikely(page->index >= MAIN_BLKADDR(sbi)))
fio.rw &= ~REQ_META;
fio.op_flags &= ~REQ_META;
set_page_writeback(page);
f2fs_submit_page_mbio(&fio);

View File

@ -25,11 +25,11 @@ static inline void __print_last_io(void)
if (!last_io.len)
return;
trace_printk("%3x:%3x %4x %-16s %2x %5x %12x %4x\n",
trace_printk("%3x:%3x %4x %-16s %2x %5x %5x %12x %4x\n",
last_io.major, last_io.minor,
last_io.pid, "----------------",
last_io.type,
last_io.fio.rw,
last_io.fio.op, last_io.fio.op_flags,
last_io.fio.new_blkaddr,
last_io.len);
memset(&last_io, 0, sizeof(last_io));
@ -101,7 +101,8 @@ void f2fs_trace_ios(struct f2fs_io_info *fio, int flush)
if (last_io.major == major && last_io.minor == minor &&
last_io.pid == pid &&
last_io.type == __file_type(inode, pid) &&
last_io.fio.rw == fio->rw &&
last_io.fio.op == fio->op &&
last_io.fio.op_flags == fio->op_flags &&
last_io.fio.new_blkaddr + last_io.len ==
fio->new_blkaddr) {
last_io.len++;

View File

@ -24,7 +24,8 @@
#define F2FS_BIO_MASK(t) (t & (READA | WRITE_FLUSH_FUA))
#define F2FS_BIO_EXTRA_MASK(t) (t & (REQ_META | REQ_PRIO))
#define show_bio_type(type) show_bio_base(type), show_bio_extra(type)
#define show_bio_type(op, op_flags) \
show_bio_base((op|op_flags)), show_bio_extra((op|op_flags))
#define show_bio_base(type) \
__print_symbolic(F2FS_BIO_MASK(type), \
@ -699,7 +700,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_page_bio,
__field(pgoff_t, index)
__field(block_t, old_blkaddr)
__field(block_t, new_blkaddr)
__field(int, rw)
__field(int, op)
__field(int, op_flags)
__field(int, type)
),
@ -709,7 +711,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_page_bio,
__entry->index = page->index;
__entry->old_blkaddr = fio->old_blkaddr;
__entry->new_blkaddr = fio->new_blkaddr;
__entry->rw = fio->rw;
__entry->op = fio->op;
__entry->op_flags = fio->op_flags;
__entry->type = fio->type;
),
@ -719,7 +722,7 @@ DECLARE_EVENT_CLASS(f2fs__submit_page_bio,
(unsigned long)__entry->index,
(unsigned long long)__entry->old_blkaddr,
(unsigned long long)__entry->new_blkaddr,
show_bio_type(__entry->rw),
show_bio_type(__entry->op, __entry->op_flags),
show_block_type(__entry->type))
);
@ -750,7 +753,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_bio,
TP_STRUCT__entry(
__field(dev_t, dev)
__field(int, rw)
__field(int, op)
__field(int, op_flags)
__field(int, type)
__field(sector_t, sector)
__field(unsigned int, size)
@ -758,7 +762,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_bio,
TP_fast_assign(
__entry->dev = sb->s_dev;
__entry->rw = fio->rw;
__entry->op = fio->op;
__entry->op_flags = fio->op_flags;
__entry->type = fio->type;
__entry->sector = bio->bi_sector;
__entry->size = bio->bi_size;
@ -766,7 +771,7 @@ DECLARE_EVENT_CLASS(f2fs__submit_bio,
TP_printk("dev = (%d,%d), %s%s, %s, sector = %lld, size = %u",
show_dev(__entry),
show_bio_type(__entry->rw),
show_bio_type(__entry->op, __entry->op_flags),
show_block_type(__entry->type),
(unsigned long long)__entry->sector,
__entry->size)