提交 9ab508b4 编写于 作者: H Harshad Shirwadkar 提交者: Zheng Zengkai

ext4: fix fast commit alignment issues

stable inclusion
from stable-5.10.43
commit fb86acc6236934e2b654f50d2a97fa77eac17859
bugzilla: 109284
CVE: NA

--------------------------------

commit a7ba36bc upstream.

Fast commit recovery data on disk may not be aligned. So, when the
recovery code reads it, this patch makes sure that fast commit info
found on-disk is first memcpy-ed into an aligned variable before
accessing it. As a consequence of it, we also remove some macros that
could resulted in unaligned accesses.

Cc: stable@kernel.org
Fixes: 8016e29f ("ext4: fast commit recovery path")
Signed-off-by: NHarshad Shirwadkar <harshadshirwadkar@gmail.com>
Link: https://lore.kernel.org/r/20210519215920.2037527-1-harshads@google.comSigned-off-by: NTheodore Ts'o <tytso@mit.edu>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 80ce3bf3
...@@ -1227,18 +1227,6 @@ static void ext4_fc_cleanup(journal_t *journal, int full) ...@@ -1227,18 +1227,6 @@ static void ext4_fc_cleanup(journal_t *journal, int full)
/* Ext4 Replay Path Routines */ /* Ext4 Replay Path Routines */
/* Get length of a particular tlv */
static inline int ext4_fc_tag_len(struct ext4_fc_tl *tl)
{
return le16_to_cpu(tl->fc_len);
}
/* Get a pointer to "value" of a tlv */
static inline u8 *ext4_fc_tag_val(struct ext4_fc_tl *tl)
{
return (u8 *)tl + sizeof(*tl);
}
/* Helper struct for dentry replay routines */ /* Helper struct for dentry replay routines */
struct dentry_info_args { struct dentry_info_args {
int parent_ino, dname_len, ino, inode_len; int parent_ino, dname_len, ino, inode_len;
...@@ -1246,28 +1234,29 @@ struct dentry_info_args { ...@@ -1246,28 +1234,29 @@ struct dentry_info_args {
}; };
static inline void tl_to_darg(struct dentry_info_args *darg, static inline void tl_to_darg(struct dentry_info_args *darg,
struct ext4_fc_tl *tl) struct ext4_fc_tl *tl, u8 *val)
{ {
struct ext4_fc_dentry_info *fcd; struct ext4_fc_dentry_info fcd;
fcd = (struct ext4_fc_dentry_info *)ext4_fc_tag_val(tl); memcpy(&fcd, val, sizeof(fcd));
darg->parent_ino = le32_to_cpu(fcd->fc_parent_ino); darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino);
darg->ino = le32_to_cpu(fcd->fc_ino); darg->ino = le32_to_cpu(fcd.fc_ino);
darg->dname = fcd->fc_dname; darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname);
darg->dname_len = ext4_fc_tag_len(tl) - darg->dname_len = le16_to_cpu(tl->fc_len) -
sizeof(struct ext4_fc_dentry_info); sizeof(struct ext4_fc_dentry_info);
} }
/* Unlink replay function */ /* Unlink replay function */
static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl) static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{ {
struct inode *inode, *old_parent; struct inode *inode, *old_parent;
struct qstr entry; struct qstr entry;
struct dentry_info_args darg; struct dentry_info_args darg;
int ret = 0; int ret = 0;
tl_to_darg(&darg, tl); tl_to_darg(&darg, tl, val);
trace_ext4_fc_replay(sb, EXT4_FC_TAG_UNLINK, darg.ino, trace_ext4_fc_replay(sb, EXT4_FC_TAG_UNLINK, darg.ino,
darg.parent_ino, darg.dname_len); darg.parent_ino, darg.dname_len);
...@@ -1357,13 +1346,14 @@ static int ext4_fc_replay_link_internal(struct super_block *sb, ...@@ -1357,13 +1346,14 @@ static int ext4_fc_replay_link_internal(struct super_block *sb,
} }
/* Link replay function */ /* Link replay function */
static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl) static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{ {
struct inode *inode; struct inode *inode;
struct dentry_info_args darg; struct dentry_info_args darg;
int ret = 0; int ret = 0;
tl_to_darg(&darg, tl); tl_to_darg(&darg, tl, val);
trace_ext4_fc_replay(sb, EXT4_FC_TAG_LINK, darg.ino, trace_ext4_fc_replay(sb, EXT4_FC_TAG_LINK, darg.ino,
darg.parent_ino, darg.dname_len); darg.parent_ino, darg.dname_len);
...@@ -1408,9 +1398,10 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino) ...@@ -1408,9 +1398,10 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
/* /*
* Inode replay function * Inode replay function
*/ */
static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{ {
struct ext4_fc_inode *fc_inode; struct ext4_fc_inode fc_inode;
struct ext4_inode *raw_inode; struct ext4_inode *raw_inode;
struct ext4_inode *raw_fc_inode; struct ext4_inode *raw_fc_inode;
struct inode *inode = NULL; struct inode *inode = NULL;
...@@ -1418,9 +1409,9 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) ...@@ -1418,9 +1409,9 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag); int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag);
struct ext4_extent_header *eh; struct ext4_extent_header *eh;
fc_inode = (struct ext4_fc_inode *)ext4_fc_tag_val(tl); memcpy(&fc_inode, val, sizeof(fc_inode));
ino = le32_to_cpu(fc_inode->fc_ino); ino = le32_to_cpu(fc_inode.fc_ino);
trace_ext4_fc_replay(sb, tag, ino, 0, 0); trace_ext4_fc_replay(sb, tag, ino, 0, 0);
inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
...@@ -1432,12 +1423,13 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) ...@@ -1432,12 +1423,13 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
ext4_fc_record_modified_inode(sb, ino); ext4_fc_record_modified_inode(sb, ino);
raw_fc_inode = (struct ext4_inode *)fc_inode->fc_raw_inode; raw_fc_inode = (struct ext4_inode *)
(val + offsetof(struct ext4_fc_inode, fc_raw_inode));
ret = ext4_get_fc_inode_loc(sb, ino, &iloc); ret = ext4_get_fc_inode_loc(sb, ino, &iloc);
if (ret) if (ret)
goto out; goto out;
inode_len = ext4_fc_tag_len(tl) - sizeof(struct ext4_fc_inode); inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode);
raw_inode = ext4_raw_inode(&iloc); raw_inode = ext4_raw_inode(&iloc);
memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block)); memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block));
...@@ -1505,14 +1497,15 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) ...@@ -1505,14 +1497,15 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
* inode for which we are trying to create a dentry here, should already have * inode for which we are trying to create a dentry here, should already have
* been replayed before we start here. * been replayed before we start here.
*/ */
static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl) static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{ {
int ret = 0; int ret = 0;
struct inode *inode = NULL; struct inode *inode = NULL;
struct inode *dir = NULL; struct inode *dir = NULL;
struct dentry_info_args darg; struct dentry_info_args darg;
tl_to_darg(&darg, tl); tl_to_darg(&darg, tl, val);
trace_ext4_fc_replay(sb, EXT4_FC_TAG_CREAT, darg.ino, trace_ext4_fc_replay(sb, EXT4_FC_TAG_CREAT, darg.ino,
darg.parent_ino, darg.dname_len); darg.parent_ino, darg.dname_len);
...@@ -1591,9 +1584,9 @@ static int ext4_fc_record_regions(struct super_block *sb, int ino, ...@@ -1591,9 +1584,9 @@ static int ext4_fc_record_regions(struct super_block *sb, int ino,
/* Replay add range tag */ /* Replay add range tag */
static int ext4_fc_replay_add_range(struct super_block *sb, static int ext4_fc_replay_add_range(struct super_block *sb,
struct ext4_fc_tl *tl) struct ext4_fc_tl *tl, u8 *val)
{ {
struct ext4_fc_add_range *fc_add_ex; struct ext4_fc_add_range fc_add_ex;
struct ext4_extent newex, *ex; struct ext4_extent newex, *ex;
struct inode *inode; struct inode *inode;
ext4_lblk_t start, cur; ext4_lblk_t start, cur;
...@@ -1603,15 +1596,14 @@ static int ext4_fc_replay_add_range(struct super_block *sb, ...@@ -1603,15 +1596,14 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
struct ext4_ext_path *path = NULL; struct ext4_ext_path *path = NULL;
int ret; int ret;
fc_add_ex = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl); memcpy(&fc_add_ex, val, sizeof(fc_add_ex));
ex = (struct ext4_extent *)&fc_add_ex->fc_ex; ex = (struct ext4_extent *)&fc_add_ex.fc_ex;
trace_ext4_fc_replay(sb, EXT4_FC_TAG_ADD_RANGE, trace_ext4_fc_replay(sb, EXT4_FC_TAG_ADD_RANGE,
le32_to_cpu(fc_add_ex->fc_ino), le32_to_cpu(ex->ee_block), le32_to_cpu(fc_add_ex.fc_ino), le32_to_cpu(ex->ee_block),
ext4_ext_get_actual_len(ex)); ext4_ext_get_actual_len(ex));
inode = ext4_iget(sb, le32_to_cpu(fc_add_ex->fc_ino), inode = ext4_iget(sb, le32_to_cpu(fc_add_ex.fc_ino), EXT4_IGET_NORMAL);
EXT4_IGET_NORMAL);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
jbd_debug(1, "Inode not found."); jbd_debug(1, "Inode not found.");
return 0; return 0;
...@@ -1720,32 +1712,33 @@ static int ext4_fc_replay_add_range(struct super_block *sb, ...@@ -1720,32 +1712,33 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
/* Replay DEL_RANGE tag */ /* Replay DEL_RANGE tag */
static int static int
ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl) ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{ {
struct inode *inode; struct inode *inode;
struct ext4_fc_del_range *lrange; struct ext4_fc_del_range lrange;
struct ext4_map_blocks map; struct ext4_map_blocks map;
ext4_lblk_t cur, remaining; ext4_lblk_t cur, remaining;
int ret; int ret;
lrange = (struct ext4_fc_del_range *)ext4_fc_tag_val(tl); memcpy(&lrange, val, sizeof(lrange));
cur = le32_to_cpu(lrange->fc_lblk); cur = le32_to_cpu(lrange.fc_lblk);
remaining = le32_to_cpu(lrange->fc_len); remaining = le32_to_cpu(lrange.fc_len);
trace_ext4_fc_replay(sb, EXT4_FC_TAG_DEL_RANGE, trace_ext4_fc_replay(sb, EXT4_FC_TAG_DEL_RANGE,
le32_to_cpu(lrange->fc_ino), cur, remaining); le32_to_cpu(lrange.fc_ino), cur, remaining);
inode = ext4_iget(sb, le32_to_cpu(lrange->fc_ino), EXT4_IGET_NORMAL); inode = ext4_iget(sb, le32_to_cpu(lrange.fc_ino), EXT4_IGET_NORMAL);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange->fc_ino)); jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange.fc_ino));
return 0; return 0;
} }
ret = ext4_fc_record_modified_inode(sb, inode->i_ino); ret = ext4_fc_record_modified_inode(sb, inode->i_ino);
jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n", jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n",
inode->i_ino, le32_to_cpu(lrange->fc_lblk), inode->i_ino, le32_to_cpu(lrange.fc_lblk),
le32_to_cpu(lrange->fc_len)); le32_to_cpu(lrange.fc_len));
while (remaining > 0) { while (remaining > 0) {
map.m_lblk = cur; map.m_lblk = cur;
map.m_len = remaining; map.m_len = remaining;
...@@ -1766,8 +1759,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl) ...@@ -1766,8 +1759,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl)
} }
ret = ext4_punch_hole(inode, ret = ext4_punch_hole(inode,
le32_to_cpu(lrange->fc_lblk) << sb->s_blocksize_bits, le32_to_cpu(lrange.fc_lblk) << sb->s_blocksize_bits,
le32_to_cpu(lrange->fc_len) << sb->s_blocksize_bits); le32_to_cpu(lrange.fc_len) << sb->s_blocksize_bits);
if (ret) if (ret)
jbd_debug(1, "ext4_punch_hole returned %d", ret); jbd_debug(1, "ext4_punch_hole returned %d", ret);
ext4_ext_replay_shrink_inode(inode, ext4_ext_replay_shrink_inode(inode,
...@@ -1909,11 +1902,11 @@ static int ext4_fc_replay_scan(journal_t *journal, ...@@ -1909,11 +1902,11 @@ static int ext4_fc_replay_scan(journal_t *journal,
struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_fc_replay_state *state; struct ext4_fc_replay_state *state;
int ret = JBD2_FC_REPLAY_CONTINUE; int ret = JBD2_FC_REPLAY_CONTINUE;
struct ext4_fc_add_range *ext; struct ext4_fc_add_range ext;
struct ext4_fc_tl *tl; struct ext4_fc_tl tl;
struct ext4_fc_tail *tail; struct ext4_fc_tail tail;
__u8 *start, *end; __u8 *start, *end, *cur, *val;
struct ext4_fc_head *head; struct ext4_fc_head head;
struct ext4_extent *ex; struct ext4_extent *ex;
state = &sbi->s_fc_replay_state; state = &sbi->s_fc_replay_state;
...@@ -1940,15 +1933,17 @@ static int ext4_fc_replay_scan(journal_t *journal, ...@@ -1940,15 +1933,17 @@ static int ext4_fc_replay_scan(journal_t *journal,
} }
state->fc_replay_expected_off++; state->fc_replay_expected_off++;
fc_for_each_tl(start, end, tl) { for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
memcpy(&tl, cur, sizeof(tl));
val = cur + sizeof(tl);
jbd_debug(3, "Scan phase, tag:%s, blk %lld\n", jbd_debug(3, "Scan phase, tag:%s, blk %lld\n",
tag2str(le16_to_cpu(tl->fc_tag)), bh->b_blocknr); tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
switch (le16_to_cpu(tl->fc_tag)) { switch (le16_to_cpu(tl.fc_tag)) {
case EXT4_FC_TAG_ADD_RANGE: case EXT4_FC_TAG_ADD_RANGE:
ext = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl); memcpy(&ext, val, sizeof(ext));
ex = (struct ext4_extent *)&ext->fc_ex; ex = (struct ext4_extent *)&ext.fc_ex;
ret = ext4_fc_record_regions(sb, ret = ext4_fc_record_regions(sb,
le32_to_cpu(ext->fc_ino), le32_to_cpu(ext.fc_ino),
le32_to_cpu(ex->ee_block), ext4_ext_pblock(ex), le32_to_cpu(ex->ee_block), ext4_ext_pblock(ex),
ext4_ext_get_actual_len(ex)); ext4_ext_get_actual_len(ex));
if (ret < 0) if (ret < 0)
...@@ -1962,18 +1957,18 @@ static int ext4_fc_replay_scan(journal_t *journal, ...@@ -1962,18 +1957,18 @@ static int ext4_fc_replay_scan(journal_t *journal,
case EXT4_FC_TAG_INODE: case EXT4_FC_TAG_INODE:
case EXT4_FC_TAG_PAD: case EXT4_FC_TAG_PAD:
state->fc_cur_tag++; state->fc_cur_tag++;
state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl, state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
sizeof(*tl) + ext4_fc_tag_len(tl)); sizeof(tl) + le16_to_cpu(tl.fc_len));
break; break;
case EXT4_FC_TAG_TAIL: case EXT4_FC_TAG_TAIL:
state->fc_cur_tag++; state->fc_cur_tag++;
tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl); memcpy(&tail, val, sizeof(tail));
state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl, state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
sizeof(*tl) + sizeof(tl) +
offsetof(struct ext4_fc_tail, offsetof(struct ext4_fc_tail,
fc_crc)); fc_crc));
if (le32_to_cpu(tail->fc_tid) == expected_tid && if (le32_to_cpu(tail.fc_tid) == expected_tid &&
le32_to_cpu(tail->fc_crc) == state->fc_crc) { le32_to_cpu(tail.fc_crc) == state->fc_crc) {
state->fc_replay_num_tags = state->fc_cur_tag; state->fc_replay_num_tags = state->fc_cur_tag;
state->fc_regions_valid = state->fc_regions_valid =
state->fc_regions_used; state->fc_regions_used;
...@@ -1984,19 +1979,19 @@ static int ext4_fc_replay_scan(journal_t *journal, ...@@ -1984,19 +1979,19 @@ static int ext4_fc_replay_scan(journal_t *journal,
state->fc_crc = 0; state->fc_crc = 0;
break; break;
case EXT4_FC_TAG_HEAD: case EXT4_FC_TAG_HEAD:
head = (struct ext4_fc_head *)ext4_fc_tag_val(tl); memcpy(&head, val, sizeof(head));
if (le32_to_cpu(head->fc_features) & if (le32_to_cpu(head.fc_features) &
~EXT4_FC_SUPPORTED_FEATURES) { ~EXT4_FC_SUPPORTED_FEATURES) {
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
break; break;
} }
if (le32_to_cpu(head->fc_tid) != expected_tid) { if (le32_to_cpu(head.fc_tid) != expected_tid) {
ret = JBD2_FC_REPLAY_STOP; ret = JBD2_FC_REPLAY_STOP;
break; break;
} }
state->fc_cur_tag++; state->fc_cur_tag++;
state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl, state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
sizeof(*tl) + ext4_fc_tag_len(tl)); sizeof(tl) + le16_to_cpu(tl.fc_len));
break; break;
default: default:
ret = state->fc_replay_num_tags ? ret = state->fc_replay_num_tags ?
...@@ -2020,11 +2015,11 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh, ...@@ -2020,11 +2015,11 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
{ {
struct super_block *sb = journal->j_private; struct super_block *sb = journal->j_private;
struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_fc_tl *tl; struct ext4_fc_tl tl;
__u8 *start, *end; __u8 *start, *end, *cur, *val;
int ret = JBD2_FC_REPLAY_CONTINUE; int ret = JBD2_FC_REPLAY_CONTINUE;
struct ext4_fc_replay_state *state = &sbi->s_fc_replay_state; struct ext4_fc_replay_state *state = &sbi->s_fc_replay_state;
struct ext4_fc_tail *tail; struct ext4_fc_tail tail;
if (pass == PASS_SCAN) { if (pass == PASS_SCAN) {
state->fc_current_pass = PASS_SCAN; state->fc_current_pass = PASS_SCAN;
...@@ -2051,49 +2046,52 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh, ...@@ -2051,49 +2046,52 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
start = (u8 *)bh->b_data; start = (u8 *)bh->b_data;
end = (__u8 *)bh->b_data + journal->j_blocksize - 1; end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
fc_for_each_tl(start, end, tl) { for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
memcpy(&tl, cur, sizeof(tl));
val = cur + sizeof(tl);
if (state->fc_replay_num_tags == 0) { if (state->fc_replay_num_tags == 0) {
ret = JBD2_FC_REPLAY_STOP; ret = JBD2_FC_REPLAY_STOP;
ext4_fc_set_bitmaps_and_counters(sb); ext4_fc_set_bitmaps_and_counters(sb);
break; break;
} }
jbd_debug(3, "Replay phase, tag:%s\n", jbd_debug(3, "Replay phase, tag:%s\n",
tag2str(le16_to_cpu(tl->fc_tag))); tag2str(le16_to_cpu(tl.fc_tag)));
state->fc_replay_num_tags--; state->fc_replay_num_tags--;
switch (le16_to_cpu(tl->fc_tag)) { switch (le16_to_cpu(tl.fc_tag)) {
case EXT4_FC_TAG_LINK: case EXT4_FC_TAG_LINK:
ret = ext4_fc_replay_link(sb, tl); ret = ext4_fc_replay_link(sb, &tl, val);
break; break;
case EXT4_FC_TAG_UNLINK: case EXT4_FC_TAG_UNLINK:
ret = ext4_fc_replay_unlink(sb, tl); ret = ext4_fc_replay_unlink(sb, &tl, val);
break; break;
case EXT4_FC_TAG_ADD_RANGE: case EXT4_FC_TAG_ADD_RANGE:
ret = ext4_fc_replay_add_range(sb, tl); ret = ext4_fc_replay_add_range(sb, &tl, val);
break; break;
case EXT4_FC_TAG_CREAT: case EXT4_FC_TAG_CREAT:
ret = ext4_fc_replay_create(sb, tl); ret = ext4_fc_replay_create(sb, &tl, val);
break; break;
case EXT4_FC_TAG_DEL_RANGE: case EXT4_FC_TAG_DEL_RANGE:
ret = ext4_fc_replay_del_range(sb, tl); ret = ext4_fc_replay_del_range(sb, &tl, val);
break; break;
case EXT4_FC_TAG_INODE: case EXT4_FC_TAG_INODE:
ret = ext4_fc_replay_inode(sb, tl); ret = ext4_fc_replay_inode(sb, &tl, val);
break; break;
case EXT4_FC_TAG_PAD: case EXT4_FC_TAG_PAD:
trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0, trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0,
ext4_fc_tag_len(tl), 0); le16_to_cpu(tl.fc_len), 0);
break; break;
case EXT4_FC_TAG_TAIL: case EXT4_FC_TAG_TAIL:
trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0, trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0,
ext4_fc_tag_len(tl), 0); le16_to_cpu(tl.fc_len), 0);
tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl); memcpy(&tail, val, sizeof(tail));
WARN_ON(le32_to_cpu(tail->fc_tid) != expected_tid); WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid);
break; break;
case EXT4_FC_TAG_HEAD: case EXT4_FC_TAG_HEAD:
break; break;
default: default:
trace_ext4_fc_replay(sb, le16_to_cpu(tl->fc_tag), 0, trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0,
ext4_fc_tag_len(tl), 0); le16_to_cpu(tl.fc_len), 0);
ret = -ECANCELED; ret = -ECANCELED;
break; break;
} }
......
...@@ -146,12 +146,5 @@ struct ext4_fc_replay_state { ...@@ -146,12 +146,5 @@ struct ext4_fc_replay_state {
#define region_last(__region) (((__region)->lblk) + ((__region)->len) - 1) #define region_last(__region) (((__region)->lblk) + ((__region)->len) - 1)
#define fc_for_each_tl(__start, __end, __tl) \
for (tl = (struct ext4_fc_tl *)start; \
(u8 *)tl < (u8 *)end; \
tl = (struct ext4_fc_tl *)((u8 *)tl + \
sizeof(struct ext4_fc_tl) + \
+ le16_to_cpu(tl->fc_len)))
#endif /* __FAST_COMMIT_H__ */ #endif /* __FAST_COMMIT_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册