提交 62913ae9 编写于 作者: T Theodore Ts'o

ext4, jbd2: add an optimized bmap for the journal inode

The generic bmap() function exported by the VFS takes locks and does
checks that are not necessary for the journal inode.  So allow the
file system to set a journal-optimized bmap function in
journal->j_bmap.

Reported-by: syzbot+9543479984ae9e576000@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?id=e4aaa78795e490421c79f76ec3679006c8ff4cf0Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
上级 2b96b4a5
...@@ -5742,6 +5742,28 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb, ...@@ -5742,6 +5742,28 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb,
return journal_inode; return journal_inode;
} }
static int ext4_journal_bmap(journal_t *journal, sector_t *block)
{
struct ext4_map_blocks map;
int ret;
if (journal->j_inode == NULL)
return 0;
map.m_lblk = *block;
map.m_len = 1;
ret = ext4_map_blocks(NULL, journal->j_inode, &map, 0);
if (ret <= 0) {
ext4_msg(journal->j_inode->i_sb, KERN_CRIT,
"journal bmap failed: block %llu ret %d\n",
*block, ret);
jbd2_journal_abort(journal, ret ? ret : -EIO);
return ret;
}
*block = map.m_pblk;
return 0;
}
static journal_t *ext4_get_journal(struct super_block *sb, static journal_t *ext4_get_journal(struct super_block *sb,
unsigned int journal_inum) unsigned int journal_inum)
{ {
...@@ -5762,6 +5784,7 @@ static journal_t *ext4_get_journal(struct super_block *sb, ...@@ -5762,6 +5784,7 @@ static journal_t *ext4_get_journal(struct super_block *sb,
return NULL; return NULL;
} }
journal->j_private = sb; journal->j_private = sb;
journal->j_bmap = ext4_journal_bmap;
ext4_init_journal_params(sb, journal); ext4_init_journal_params(sb, journal);
return journal; return journal;
} }
......
...@@ -970,10 +970,13 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr, ...@@ -970,10 +970,13 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
{ {
int err = 0; int err = 0;
unsigned long long ret; unsigned long long ret;
sector_t block = 0; sector_t block = blocknr;
if (journal->j_inode) { if (journal->j_bmap) {
block = blocknr; err = journal->j_bmap(journal, &block);
if (err == 0)
*retp = block;
} else if (journal->j_inode) {
ret = bmap(journal->j_inode, &block); ret = bmap(journal->j_inode, &block);
if (ret || !block) { if (ret || !block) {
......
...@@ -1308,6 +1308,14 @@ struct journal_s ...@@ -1308,6 +1308,14 @@ struct journal_s
struct buffer_head *bh, struct buffer_head *bh,
enum passtype pass, int off, enum passtype pass, int off,
tid_t expected_commit_id); tid_t expected_commit_id);
/**
* @j_bmap:
*
* Bmap function that should be used instead of the generic
* VFS bmap function.
*/
int (*j_bmap)(struct journal_s *journal, sector_t *block);
}; };
#define jbd2_might_wait_for_commit(j) \ #define jbd2_might_wait_for_commit(j) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册