mirror of
https://gitee.com/openharmony/third_party_f2fs-tools
synced 2024-11-27 04:00:57 +00:00
fsck.f2fs: add basic compress related check/fix
* check/fix i_compr_blocks * check/fix compressed flag in i_flags when compression is not supported. Signed-off-by: Robin Hsu <robinhsu@google.com> [Jaegeuk Kim: minor coding style] Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
529967eac0
commit
9429e865e8
158
fsck/fsck.c
158
fsck/fsck.c
@ -533,7 +533,8 @@ out:
|
|||||||
|
|
||||||
int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
||||||
u32 nid, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
|
u32 nid, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
|
||||||
u32 *blk_cnt, struct child_info *child)
|
u32 *blk_cnt, struct f2fs_compr_blk_cnt *cbc,
|
||||||
|
struct child_info *child)
|
||||||
{
|
{
|
||||||
struct node_info ni;
|
struct node_info ni;
|
||||||
struct f2fs_node *node_blk = NULL;
|
struct f2fs_node *node_blk = NULL;
|
||||||
@ -547,7 +548,8 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
|||||||
if (ntype == TYPE_INODE) {
|
if (ntype == TYPE_INODE) {
|
||||||
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
|
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
|
||||||
|
|
||||||
fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, &ni, child);
|
fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, cbc,
|
||||||
|
&ni, child);
|
||||||
quota_add_inode_usage(fsck->qctx, nid, &node_blk->i);
|
quota_add_inode_usage(fsck->qctx, nid, &node_blk->i);
|
||||||
} else {
|
} else {
|
||||||
switch (ntype) {
|
switch (ntype) {
|
||||||
@ -555,19 +557,19 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
|||||||
f2fs_set_main_bitmap(sbi, ni.blk_addr,
|
f2fs_set_main_bitmap(sbi, ni.blk_addr,
|
||||||
CURSEG_WARM_NODE);
|
CURSEG_WARM_NODE);
|
||||||
fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk,
|
fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk,
|
||||||
blk_cnt, child, &ni);
|
blk_cnt, cbc, child, &ni);
|
||||||
break;
|
break;
|
||||||
case TYPE_INDIRECT_NODE:
|
case TYPE_INDIRECT_NODE:
|
||||||
f2fs_set_main_bitmap(sbi, ni.blk_addr,
|
f2fs_set_main_bitmap(sbi, ni.blk_addr,
|
||||||
CURSEG_COLD_NODE);
|
CURSEG_COLD_NODE);
|
||||||
fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
|
fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
|
||||||
blk_cnt, child);
|
blk_cnt, cbc, child);
|
||||||
break;
|
break;
|
||||||
case TYPE_DOUBLE_INDIRECT_NODE:
|
case TYPE_DOUBLE_INDIRECT_NODE:
|
||||||
f2fs_set_main_bitmap(sbi, ni.blk_addr,
|
f2fs_set_main_bitmap(sbi, ni.blk_addr,
|
||||||
CURSEG_COLD_NODE);
|
CURSEG_COLD_NODE);
|
||||||
fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
|
fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
|
||||||
blk_cnt, child);
|
blk_cnt, cbc, child);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
@ -667,7 +669,8 @@ void fsck_reada_all_direct_node_blocks(struct f2fs_sb_info *sbi,
|
|||||||
/* start with valid nid and blkaddr */
|
/* start with valid nid and blkaddr */
|
||||||
void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
|
void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
|
||||||
enum FILE_TYPE ftype, struct f2fs_node *node_blk,
|
enum FILE_TYPE ftype, struct f2fs_node *node_blk,
|
||||||
u32 *blk_cnt, struct node_info *ni, struct child_info *child_d)
|
u32 *blk_cnt, struct f2fs_compr_blk_cnt *cbc,
|
||||||
|
struct node_info *ni, struct child_info *child_d)
|
||||||
{
|
{
|
||||||
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
|
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
|
||||||
struct child_info child;
|
struct child_info child;
|
||||||
@ -675,6 +678,11 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
|
|||||||
u32 i_links = le32_to_cpu(node_blk->i.i_links);
|
u32 i_links = le32_to_cpu(node_blk->i.i_links);
|
||||||
u64 i_size = le64_to_cpu(node_blk->i.i_size);
|
u64 i_size = le64_to_cpu(node_blk->i.i_size);
|
||||||
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
|
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
|
||||||
|
bool compr_supported = c.feature & cpu_to_le32(F2FS_FEATURE_COMPRESSION);
|
||||||
|
u32 i_flags = le32_to_cpu(node_blk->i.i_flags);
|
||||||
|
bool compressed = i_flags & F2FS_COMPR_FL;
|
||||||
|
bool compr_rel = node_blk->i.i_inline & F2FS_COMPRESS_RELEASED;
|
||||||
|
u64 i_compr_blocks = le64_to_cpu(node_blk->i.i_compr_blocks);
|
||||||
nid_t i_xattr_nid = le32_to_cpu(node_blk->i.i_xattr_nid);
|
nid_t i_xattr_nid = le32_to_cpu(node_blk->i.i_xattr_nid);
|
||||||
int ofs;
|
int ofs;
|
||||||
char *en;
|
char *en;
|
||||||
@ -683,7 +691,23 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
|
|||||||
unsigned short i_gc_failures;
|
unsigned short i_gc_failures;
|
||||||
int need_fix = 0;
|
int need_fix = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 cluster_size = 1 << node_blk->i.i_log_cluster_size;
|
||||||
|
|
||||||
|
if (!compr_supported && compressed) {
|
||||||
|
/*
|
||||||
|
* The 'compression' flag in i_flags affects the traverse of
|
||||||
|
* the node tree. Thus, it must be fixed unconditionally
|
||||||
|
* in the memory (node_blk).
|
||||||
|
*/
|
||||||
|
node_blk->i.i_flags &= ~cpu_to_le32(F2FS_COMPR_FL);
|
||||||
|
compressed = false;
|
||||||
|
if (c.fix_on) {
|
||||||
|
need_fix = 1;
|
||||||
|
FIX_MSG("[0x%x] i_flags=0x%x -> 0x%x",
|
||||||
|
nid, i_flags, node_blk->i.i_flags);
|
||||||
|
}
|
||||||
|
i_flags &= ~F2FS_COMPR_FL;
|
||||||
|
}
|
||||||
memset(&child, 0, sizeof(child));
|
memset(&child, 0, sizeof(child));
|
||||||
child.links = 2;
|
child.links = 2;
|
||||||
child.p_ino = nid;
|
child.p_ino = nid;
|
||||||
@ -899,31 +923,45 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
|
|||||||
/* check extent info */
|
/* check extent info */
|
||||||
check_extent_info(&child, blkaddr, 0);
|
check_extent_info(&child, blkaddr, 0);
|
||||||
|
|
||||||
|
if (blkaddr == NULL_ADDR)
|
||||||
|
continue;
|
||||||
if (blkaddr == COMPRESS_ADDR) {
|
if (blkaddr == COMPRESS_ADDR) {
|
||||||
if (node_blk->i.i_compr_blocks) {
|
if (!compressed || (child.pgofs &
|
||||||
|
(cluster_size - 1)) != 0) {
|
||||||
|
if (c.fix_on) {
|
||||||
|
node_blk->i.i_addr[ofs + idx] =
|
||||||
|
NULL_ADDR;
|
||||||
|
need_fix = 1;
|
||||||
|
FIX_MSG("[0x%x] i_addr[%d] = 0", nid,
|
||||||
|
ofs + idx);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!compr_rel) {
|
||||||
fsck->chk.valid_blk_cnt++;
|
fsck->chk.valid_blk_cnt++;
|
||||||
*blk_cnt = *blk_cnt + 1;
|
*blk_cnt = *blk_cnt + 1;
|
||||||
|
cbc->cheader_pgofs = child.pgofs;
|
||||||
|
cbc->cnt++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!compr_rel && blkaddr == NEW_ADDR &&
|
||||||
if (blkaddr != 0) {
|
child.pgofs - cbc->cheader_pgofs < cluster_size)
|
||||||
ret = fsck_chk_data_blk(sbi,
|
cbc->cnt++;
|
||||||
IS_CASEFOLDED(&node_blk->i),
|
ret = fsck_chk_data_blk(sbi,
|
||||||
blkaddr,
|
IS_CASEFOLDED(&node_blk->i),
|
||||||
&child, (i_blocks == *blk_cnt),
|
blkaddr,
|
||||||
ftype, nid, idx, ni->version,
|
&child, (i_blocks == *blk_cnt),
|
||||||
file_is_encrypt(&node_blk->i));
|
ftype, nid, idx, ni->version,
|
||||||
if (!ret) {
|
file_is_encrypt(&node_blk->i));
|
||||||
*blk_cnt = *blk_cnt + 1;
|
if (!ret) {
|
||||||
if (cur_qtype != -1 && blkaddr != NEW_ADDR)
|
*blk_cnt = *blk_cnt + 1;
|
||||||
qf_last_blkofs[cur_qtype] = child.pgofs;
|
if (cur_qtype != -1 && blkaddr != NEW_ADDR)
|
||||||
} else if (c.fix_on) {
|
qf_last_blkofs[cur_qtype] = child.pgofs;
|
||||||
node_blk->i.i_addr[ofs + idx] = 0;
|
} else if (c.fix_on) {
|
||||||
need_fix = 1;
|
node_blk->i.i_addr[ofs + idx] = 0;
|
||||||
FIX_MSG("[0x%x] i_addr[%d] = 0",
|
need_fix = 1;
|
||||||
nid, ofs + idx);
|
FIX_MSG("[0x%x] i_addr[%d] = 0", nid, ofs + idx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,7 +988,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
|
|||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
ret = fsck_chk_node_blk(sbi, &node_blk->i, i_nid,
|
ret = fsck_chk_node_blk(sbi, &node_blk->i, i_nid,
|
||||||
ftype, ntype, blk_cnt, &child);
|
ftype, ntype, blk_cnt, cbc, &child);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
*blk_cnt = *blk_cnt + 1;
|
*blk_cnt = *blk_cnt + 1;
|
||||||
} else if (ret == -EINVAL) {
|
} else if (ret == -EINVAL) {
|
||||||
@ -994,6 +1032,16 @@ check:
|
|||||||
nid, i_blocks, *blk_cnt);
|
nid, i_blocks, *blk_cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compressed && i_compr_blocks != cbc->cnt) {
|
||||||
|
if (c.fix_on) {
|
||||||
|
node_blk->i.i_compr_blocks = cpu_to_le64(cbc->cnt);
|
||||||
|
need_fix = 1;
|
||||||
|
FIX_MSG("[0x%x] i_compr_blocks=0x%08"PRIx64" -> 0x%x",
|
||||||
|
nid, i_compr_blocks, cbc->cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
skip_blkcnt_fix:
|
skip_blkcnt_fix:
|
||||||
en = malloc(F2FS_PRINT_NAMELEN);
|
en = malloc(F2FS_PRINT_NAMELEN);
|
||||||
ASSERT(en);
|
ASSERT(en);
|
||||||
@ -1132,27 +1180,47 @@ skip_blkcnt_fix:
|
|||||||
|
|
||||||
int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
||||||
u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk,
|
u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk,
|
||||||
u32 *blk_cnt, struct child_info *child, struct node_info *ni)
|
u32 *blk_cnt, struct f2fs_compr_blk_cnt *cbc,
|
||||||
|
struct child_info *child, struct node_info *ni)
|
||||||
{
|
{
|
||||||
int idx, ret;
|
int idx, ret;
|
||||||
int need_fix = 0;
|
int need_fix = 0;
|
||||||
child->p_ino = nid;
|
child->p_ino = nid;
|
||||||
child->pp_ino = le32_to_cpu(inode->i_pino);
|
child->pp_ino = le32_to_cpu(inode->i_pino);
|
||||||
|
u32 i_flags = le32_to_cpu(inode->i_flags);
|
||||||
|
bool compressed = i_flags & F2FS_COMPR_FL;
|
||||||
|
bool compr_rel = inode->i_inline & F2FS_COMPRESS_RELEASED;
|
||||||
|
u32 cluster_size = 1 << inode->i_log_cluster_size;
|
||||||
|
|
||||||
for (idx = 0; idx < ADDRS_PER_BLOCK(inode); idx++, child->pgofs++) {
|
for (idx = 0; idx < ADDRS_PER_BLOCK(inode); idx++, child->pgofs++) {
|
||||||
block_t blkaddr = le32_to_cpu(node_blk->dn.addr[idx]);
|
block_t blkaddr = le32_to_cpu(node_blk->dn.addr[idx]);
|
||||||
|
|
||||||
check_extent_info(child, blkaddr, 0);
|
check_extent_info(child, blkaddr, 0);
|
||||||
|
|
||||||
if (blkaddr == 0x0)
|
if (blkaddr == NULL_ADDR)
|
||||||
continue;
|
continue;
|
||||||
if (blkaddr == COMPRESS_ADDR) {
|
if (blkaddr == COMPRESS_ADDR) {
|
||||||
if (inode->i_compr_blocks) {
|
if (!compressed || (child->pgofs &
|
||||||
|
(cluster_size - 1)) != 0) {
|
||||||
|
if (c.fix_on) {
|
||||||
|
node_blk->dn.addr[idx] = NULL_ADDR;
|
||||||
|
need_fix = 1;
|
||||||
|
FIX_MSG("[0x%x] dn.addr[%d] = 0", nid,
|
||||||
|
idx);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!compr_rel) {
|
||||||
F2FS_FSCK(sbi)->chk.valid_blk_cnt++;
|
F2FS_FSCK(sbi)->chk.valid_blk_cnt++;
|
||||||
*blk_cnt = *blk_cnt + 1;
|
*blk_cnt = *blk_cnt + 1;
|
||||||
|
cbc->cheader_pgofs = child->pgofs;
|
||||||
|
cbc->cnt++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!compr_rel && blkaddr == NEW_ADDR && child->pgofs -
|
||||||
|
cbc->cheader_pgofs < cluster_size)
|
||||||
|
cbc->cnt++;
|
||||||
ret = fsck_chk_data_blk(sbi, IS_CASEFOLDED(inode),
|
ret = fsck_chk_data_blk(sbi, IS_CASEFOLDED(inode),
|
||||||
blkaddr, child,
|
blkaddr, child,
|
||||||
le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype,
|
le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype,
|
||||||
@ -1163,7 +1231,7 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
|||||||
if (cur_qtype != -1 && blkaddr != NEW_ADDR)
|
if (cur_qtype != -1 && blkaddr != NEW_ADDR)
|
||||||
qf_last_blkofs[cur_qtype] = child->pgofs;
|
qf_last_blkofs[cur_qtype] = child->pgofs;
|
||||||
} else if (c.fix_on) {
|
} else if (c.fix_on) {
|
||||||
node_blk->dn.addr[idx] = 0;
|
node_blk->dn.addr[idx] = NULL_ADDR;
|
||||||
need_fix = 1;
|
need_fix = 1;
|
||||||
FIX_MSG("[0x%x] dn.addr[%d] = 0", nid, idx);
|
FIX_MSG("[0x%x] dn.addr[%d] = 0", nid, idx);
|
||||||
}
|
}
|
||||||
@ -1177,7 +1245,7 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
|||||||
|
|
||||||
int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
||||||
enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt,
|
enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt,
|
||||||
struct child_info *child)
|
struct f2fs_compr_blk_cnt *cbc, struct child_info *child)
|
||||||
{
|
{
|
||||||
int need_fix = 0, ret;
|
int need_fix = 0, ret;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -1189,7 +1257,8 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
|||||||
goto skip;
|
goto skip;
|
||||||
ret = fsck_chk_node_blk(sbi, inode,
|
ret = fsck_chk_node_blk(sbi, inode,
|
||||||
le32_to_cpu(node_blk->in.nid[i]),
|
le32_to_cpu(node_blk->in.nid[i]),
|
||||||
ftype, TYPE_DIRECT_NODE, blk_cnt, child);
|
ftype, TYPE_DIRECT_NODE, blk_cnt,
|
||||||
|
cbc, child);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
*blk_cnt = *blk_cnt + 1;
|
*blk_cnt = *blk_cnt + 1;
|
||||||
else if (ret == -EINVAL) {
|
else if (ret == -EINVAL) {
|
||||||
@ -1219,7 +1288,7 @@ skip:
|
|||||||
|
|
||||||
int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
||||||
enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt,
|
enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt,
|
||||||
struct child_info *child)
|
struct f2fs_compr_blk_cnt *cbc, struct child_info *child)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int need_fix = 0, ret = 0;
|
int need_fix = 0, ret = 0;
|
||||||
@ -1231,7 +1300,7 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
|
|||||||
goto skip;
|
goto skip;
|
||||||
ret = fsck_chk_node_blk(sbi, inode,
|
ret = fsck_chk_node_blk(sbi, inode,
|
||||||
le32_to_cpu(node_blk->in.nid[i]),
|
le32_to_cpu(node_blk->in.nid[i]),
|
||||||
ftype, TYPE_INDIRECT_NODE, blk_cnt, child);
|
ftype, TYPE_INDIRECT_NODE, blk_cnt, cbc, child);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
*blk_cnt = *blk_cnt + 1;
|
*blk_cnt = *blk_cnt + 1;
|
||||||
else if (ret == -EINVAL) {
|
else if (ret == -EINVAL) {
|
||||||
@ -1494,6 +1563,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, int casefolded,
|
|||||||
enum FILE_TYPE ftype;
|
enum FILE_TYPE ftype;
|
||||||
int dentries = 0;
|
int dentries = 0;
|
||||||
u32 blk_cnt;
|
u32 blk_cnt;
|
||||||
|
struct f2fs_compr_blk_cnt cbc;
|
||||||
u8 *name;
|
u8 *name;
|
||||||
char en[F2FS_PRINT_NAMELEN];
|
char en[F2FS_PRINT_NAMELEN];
|
||||||
u16 name_len;
|
u16 name_len;
|
||||||
@ -1633,10 +1703,12 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, int casefolded,
|
|||||||
dentry, max, i, last_blk, enc_name);
|
dentry, max, i, last_blk, enc_name);
|
||||||
|
|
||||||
blk_cnt = 1;
|
blk_cnt = 1;
|
||||||
|
cbc.cnt = 0;
|
||||||
|
cbc.cheader_pgofs = CHEADER_PGOFS_NONE;
|
||||||
child->i_namelen = name_len;
|
child->i_namelen = name_len;
|
||||||
ret = fsck_chk_node_blk(sbi,
|
ret = fsck_chk_node_blk(sbi,
|
||||||
NULL, le32_to_cpu(dentry[i].ino),
|
NULL, le32_to_cpu(dentry[i].ino),
|
||||||
ftype, TYPE_INODE, &blk_cnt, child);
|
ftype, TYPE_INODE, &blk_cnt, &cbc, child);
|
||||||
|
|
||||||
if (ret && c.fix_on) {
|
if (ret && c.fix_on) {
|
||||||
int j;
|
int j;
|
||||||
@ -1800,6 +1872,7 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, int casefolded,
|
|||||||
int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
|
int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
|
||||||
{
|
{
|
||||||
u32 blk_cnt = 0;
|
u32 blk_cnt = 0;
|
||||||
|
struct f2fs_compr_blk_cnt cbc = {0, CHEADER_PGOFS_NONE};
|
||||||
block_t start_blk, orphan_blkaddr, i, j;
|
block_t start_blk, orphan_blkaddr, i, j;
|
||||||
struct f2fs_orphan_block *orphan_blk, *new_blk;
|
struct f2fs_orphan_block *orphan_blk, *new_blk;
|
||||||
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
|
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
|
||||||
@ -1831,6 +1904,8 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
|
|||||||
DBG(1, "[%3d] ino [0x%x]\n", i, ino);
|
DBG(1, "[%3d] ino [0x%x]\n", i, ino);
|
||||||
struct node_info ni;
|
struct node_info ni;
|
||||||
blk_cnt = 1;
|
blk_cnt = 1;
|
||||||
|
cbc.cnt = 0;
|
||||||
|
cbc.cheader_pgofs = CHEADER_PGOFS_NONE;
|
||||||
|
|
||||||
if (c.preen_mode == PREEN_MODE_1 && !c.fix_on) {
|
if (c.preen_mode == PREEN_MODE_1 && !c.fix_on) {
|
||||||
get_node_info(sbi, ino, &ni);
|
get_node_info(sbi, ino, &ni);
|
||||||
@ -1846,7 +1921,7 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
|
|||||||
|
|
||||||
ret = fsck_chk_node_blk(sbi, NULL, ino,
|
ret = fsck_chk_node_blk(sbi, NULL, ino,
|
||||||
F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt,
|
F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt,
|
||||||
NULL);
|
&cbc, NULL);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
new_blk->ino[new_entry_count++] =
|
new_blk->ino[new_entry_count++] =
|
||||||
orphan_blk->ino[j];
|
orphan_blk->ino[j];
|
||||||
@ -1876,6 +1951,7 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
|
|||||||
enum quota_type qtype;
|
enum quota_type qtype;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 blk_cnt = 0;
|
u32 blk_cnt = 0;
|
||||||
|
struct f2fs_compr_blk_cnt cbc = {0, CHEADER_PGOFS_NONE};
|
||||||
|
|
||||||
for (qtype = 0; qtype < F2FS_MAX_QUOTAS; qtype++) {
|
for (qtype = 0; qtype < F2FS_MAX_QUOTAS; qtype++) {
|
||||||
cur_qtype = qtype;
|
cur_qtype = qtype;
|
||||||
@ -1886,6 +1962,8 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
|
|||||||
|
|
||||||
DBG(1, "qtype [%d] ino [0x%x]\n", qtype, ino);
|
DBG(1, "qtype [%d] ino [0x%x]\n", qtype, ino);
|
||||||
blk_cnt = 1;
|
blk_cnt = 1;
|
||||||
|
cbc.cnt = 0;
|
||||||
|
cbc.cheader_pgofs = CHEADER_PGOFS_NONE;
|
||||||
|
|
||||||
if (c.preen_mode == PREEN_MODE_1 && !c.fix_on) {
|
if (c.preen_mode == PREEN_MODE_1 && !c.fix_on) {
|
||||||
get_node_info(sbi, ino, &ni);
|
get_node_info(sbi, ino, &ni);
|
||||||
@ -1895,7 +1973,8 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ret = fsck_chk_node_blk(sbi, NULL, ino,
|
ret = fsck_chk_node_blk(sbi, NULL, ino,
|
||||||
F2FS_FT_REG_FILE, TYPE_INODE, &blk_cnt, NULL);
|
F2FS_FT_REG_FILE, TYPE_INODE, &blk_cnt,
|
||||||
|
&cbc, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ASSERT_MSG("wrong quota inode, qtype [%d] ino [0x%x]",
|
ASSERT_MSG("wrong quota inode, qtype [%d] ino [0x%x]",
|
||||||
qtype, ino);
|
qtype, ino);
|
||||||
@ -2806,6 +2885,7 @@ static int fsck_reconnect_file(struct f2fs_sb_info *sbi)
|
|||||||
struct node_info ni;
|
struct node_info ni;
|
||||||
char *reconnect_bitmap;
|
char *reconnect_bitmap;
|
||||||
u32 blk_cnt;
|
u32 blk_cnt;
|
||||||
|
struct f2fs_compr_blk_cnt cbc;
|
||||||
nid_t nid;
|
nid_t nid;
|
||||||
int err, cnt = 0, ftype;
|
int err, cnt = 0, ftype;
|
||||||
|
|
||||||
@ -2849,8 +2929,10 @@ static int fsck_reconnect_file(struct f2fs_sb_info *sbi)
|
|||||||
|
|
||||||
DBG(1, "Check inode 0x%x\n", nid);
|
DBG(1, "Check inode 0x%x\n", nid);
|
||||||
blk_cnt = 1;
|
blk_cnt = 1;
|
||||||
|
cbc.cnt = 0;
|
||||||
|
cbc.cheader_pgofs = CHEADER_PGOFS_NONE;
|
||||||
fsck_chk_inode_blk(sbi, nid, ftype, node,
|
fsck_chk_inode_blk(sbi, nid, ftype, node,
|
||||||
&blk_cnt, &ni, NULL);
|
&blk_cnt, &cbc, &ni, NULL);
|
||||||
|
|
||||||
f2fs_set_bit(nid, reconnect_bitmap);
|
f2fs_set_bit(nid, reconnect_bitmap);
|
||||||
}
|
}
|
||||||
|
14
fsck/fsck.h
14
fsck/fsck.h
@ -169,16 +169,20 @@ extern int fsck_sanity_check_nid(struct f2fs_sb_info *, u32,
|
|||||||
struct node_info *);
|
struct node_info *);
|
||||||
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
|
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
|
||||||
enum FILE_TYPE, enum NODE_TYPE, u32 *,
|
enum FILE_TYPE, enum NODE_TYPE, u32 *,
|
||||||
struct child_info *);
|
struct f2fs_compr_blk_cnt *, struct child_info *);
|
||||||
extern void fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
|
extern void fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
|
||||||
struct f2fs_node *, u32 *, struct node_info *, struct child_info *);
|
struct f2fs_node *, u32 *, struct f2fs_compr_blk_cnt *,
|
||||||
|
struct node_info *, struct child_info *);
|
||||||
extern int fsck_chk_dnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
|
extern int fsck_chk_dnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
|
||||||
u32, enum FILE_TYPE, struct f2fs_node *, u32 *,
|
u32, enum FILE_TYPE, struct f2fs_node *, u32 *,
|
||||||
struct child_info *, struct node_info *);
|
struct f2fs_compr_blk_cnt *, struct child_info *,
|
||||||
|
struct node_info *);
|
||||||
extern int fsck_chk_idnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
|
extern int fsck_chk_idnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
|
||||||
enum FILE_TYPE, struct f2fs_node *, u32 *, struct child_info *);
|
enum FILE_TYPE, struct f2fs_node *, u32 *,
|
||||||
|
struct f2fs_compr_blk_cnt *, struct child_info *);
|
||||||
extern int fsck_chk_didnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
|
extern int fsck_chk_didnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
|
||||||
enum FILE_TYPE, struct f2fs_node *, u32 *, struct child_info *);
|
enum FILE_TYPE, struct f2fs_node *, u32 *,
|
||||||
|
struct f2fs_compr_blk_cnt *, struct child_info *);
|
||||||
extern int fsck_chk_data_blk(struct f2fs_sb_info *, int,
|
extern int fsck_chk_data_blk(struct f2fs_sb_info *, int,
|
||||||
u32, struct child_info *, int, enum FILE_TYPE, u32, u16, u8, int);
|
u32, struct child_info *, int, enum FILE_TYPE, u32, u16, u8, int);
|
||||||
extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, int,
|
extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, int,
|
||||||
|
@ -820,6 +820,7 @@ static int do_fsck(struct f2fs_sb_info *sbi)
|
|||||||
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
|
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
|
||||||
u32 flag = le32_to_cpu(ckpt->ckpt_flags);
|
u32 flag = le32_to_cpu(ckpt->ckpt_flags);
|
||||||
u32 blk_cnt;
|
u32 blk_cnt;
|
||||||
|
struct f2fs_compr_blk_cnt cbc;
|
||||||
errcode_t ret;
|
errcode_t ret;
|
||||||
|
|
||||||
fsck_init(sbi);
|
fsck_init(sbi);
|
||||||
@ -867,6 +868,8 @@ static int do_fsck(struct f2fs_sb_info *sbi)
|
|||||||
|
|
||||||
/* Traverse all block recursively from root inode */
|
/* Traverse all block recursively from root inode */
|
||||||
blk_cnt = 1;
|
blk_cnt = 1;
|
||||||
|
cbc.cnt = 0;
|
||||||
|
cbc.cheader_pgofs = CHEADER_PGOFS_NONE;
|
||||||
|
|
||||||
if (c.feature & cpu_to_le32(F2FS_FEATURE_QUOTA_INO)) {
|
if (c.feature & cpu_to_le32(F2FS_FEATURE_QUOTA_INO)) {
|
||||||
ret = quota_init_context(sbi);
|
ret = quota_init_context(sbi);
|
||||||
@ -877,7 +880,7 @@ static int do_fsck(struct f2fs_sb_info *sbi)
|
|||||||
}
|
}
|
||||||
fsck_chk_orphan_node(sbi);
|
fsck_chk_orphan_node(sbi);
|
||||||
fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num,
|
fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num,
|
||||||
F2FS_FT_DIR, TYPE_INODE, &blk_cnt, NULL);
|
F2FS_FT_DIR, TYPE_INODE, &blk_cnt, &cbc, NULL);
|
||||||
fsck_chk_quota_files(sbi);
|
fsck_chk_quota_files(sbi);
|
||||||
|
|
||||||
ret = fsck_verify(sbi);
|
ret = fsck_verify(sbi);
|
||||||
|
@ -941,6 +941,21 @@ struct f2fs_extent {
|
|||||||
#define F2FS_CASEFOLD_FL 0x40000000 /* Casefolded file */
|
#define F2FS_CASEFOLD_FL 0x40000000 /* Casefolded file */
|
||||||
#define IS_CASEFOLDED(dir) ((dir)->i_flags & F2FS_CASEFOLD_FL)
|
#define IS_CASEFOLDED(dir) ((dir)->i_flags & F2FS_CASEFOLD_FL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fsck i_compr_blocks counting helper
|
||||||
|
*/
|
||||||
|
struct f2fs_compr_blk_cnt {
|
||||||
|
/* counting i_compr_blocks, init 0 */
|
||||||
|
u32 cnt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* previous seen compression header (COMPR_ADDR) page offsets,
|
||||||
|
* use CHEADER_PGOFS_NONE for none
|
||||||
|
*/
|
||||||
|
u32 cheader_pgofs;
|
||||||
|
};
|
||||||
|
#define CHEADER_PGOFS_NONE ((u32)-(1 << MAX_COMPRESS_LOG_SIZE))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* inode flags
|
* inode flags
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user