All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] fsck.f2fs: reduce redundant message
@ 2015-03-27  0:03 Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 2/6] fsck.f2fs: remove inconsistent named directories Jaegeuk Kim
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2015-03-27  0:03 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

This assert message is unnecessary to be shown, since caller shows the reason
already.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/f2fs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 709fbf3..e59bb0b 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -340,7 +340,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
 
 	if (addr >= F2FS_RAW_SUPER(sbi)->block_count ||
 				addr < SM_I(sbi)->main_blkaddr) {
-		ASSERT_MSG("block addr [0x%x]\n", addr);
+		DBG(1, "block addr [0x%x]\n", addr);
 		return 0;
 	}
 
-- 
2.1.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/6] fsck.f2fs: remove inconsistent named directories
  2015-03-27  0:03 [PATCH 1/6] fsck.f2fs: reduce redundant message Jaegeuk Kim
@ 2015-03-27  0:03 ` Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 3/6] fsck.f2fs: check file types Jaegeuk Kim
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2015-03-27  0:03 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

Each inode has its filename inside inode block.
For directory, the name should be matched all the time.
In other cases, it shouldn't, since there is able to be linked to other file
names.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c | 27 ++++++++++++++++++---------
 fsck/fsck.h |  2 +-
 fsck/main.c |  2 +-
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 1b27ae0..e803fa0 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -192,7 +192,7 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
 static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
 			struct f2fs_node *node_blk,
 			enum FILE_TYPE ftype, enum NODE_TYPE ntype,
-			struct node_info *ni)
+			struct node_info *ni, u8 *name)
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
 	int ret;
@@ -263,6 +263,15 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
 		}
 	}
 
+	if (ntype == TYPE_INODE && ftype == F2FS_FT_DIR) {
+		u32 len = le32_to_cpu(node_blk->i.i_namelen);
+		if (name && memcmp(name, node_blk->i.i_name, len)) {
+			ASSERT_MSG("mismatch name [0x%x] [%s vs. %s]",
+					nid, name, node_blk->i.i_name);
+			return -EINVAL;
+		}
+	}
+
 	/* workaround to fix later */
 	if (ftype != F2FS_FT_ORPHAN ||
 			f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
@@ -297,7 +306,7 @@ static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
 
 	/* Sanity check */
 	if (sanity_check_nid(sbi, x_nid, node_blk,
-				F2FS_FT_XATTR, TYPE_XATTR, &ni)) {
+				F2FS_FT_XATTR, TYPE_XATTR, &ni, NULL)) {
 		ret = -EINVAL;
 		goto out;
 	}
@@ -311,7 +320,7 @@ out:
 }
 
 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, u8 *name, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
 		u32 *blk_cnt)
 {
 	struct node_info ni;
@@ -320,7 +329,7 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
 	node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
 	ASSERT(node_blk != NULL);
 
-	if (sanity_check_nid(sbi, nid, node_blk, ftype, ntype, &ni))
+	if (sanity_check_nid(sbi, nid, node_blk, ftype, ntype, &ni, name))
 		goto err;
 
 	if (ntype == TYPE_INODE) {
@@ -496,7 +505,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 		if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) {
 			ret = fsck_chk_node_blk(sbi, &node_blk->i,
 					le32_to_cpu(node_blk->i.i_nid[idx]),
-					ftype, ntype, blk_cnt);
+					NULL, ftype, ntype, blk_cnt);
 			if (!ret) {
 				*blk_cnt = *blk_cnt + 1;
 			} else if (config.fix_on) {
@@ -591,7 +600,7 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
 		if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
 			continue;
 		ret = fsck_chk_node_blk(sbi, inode,
-				le32_to_cpu(node_blk->in.nid[i]),
+				le32_to_cpu(node_blk->in.nid[i]), NULL,
 				ftype, TYPE_DIRECT_NODE, blk_cnt);
 		if (!ret)
 			*blk_cnt = *blk_cnt + 1;
@@ -611,7 +620,7 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
 		if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
 			continue;
 		ret = fsck_chk_node_blk(sbi, inode,
-				le32_to_cpu(node_blk->in.nid[i]),
+				le32_to_cpu(node_blk->in.nid[i]), NULL,
 				ftype, TYPE_INDIRECT_NODE, blk_cnt);
 		if (!ret)
 			*blk_cnt = *blk_cnt + 1;
@@ -764,7 +773,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt,
 
 		blk_cnt = 1;
 		ret = fsck_chk_node_blk(sbi,
-				NULL, le32_to_cpu(dentry[i].ino),
+				NULL, le32_to_cpu(dentry[i].ino), name,
 				ftype, TYPE_INODE, &blk_cnt);
 
 		if (ret && config.fix_on) {
@@ -927,7 +936,7 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
 				continue;
 			}
 			blk_cnt = 1;
-			fsck_chk_node_blk(sbi, NULL, ino,
+			fsck_chk_node_blk(sbi, NULL, ino, NULL,
 					F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
 		}
 		memset(orphan_blk, 0, BLOCK_SZ);
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 98425c6..ff2b25d 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -80,7 +80,7 @@ enum seg_type {
 
 extern void fsck_chk_orphan_node(struct f2fs_sb_info *);
 extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
-		enum FILE_TYPE, enum NODE_TYPE, u32 *);
+		u8 *, enum FILE_TYPE, enum NODE_TYPE, u32 *);
 extern void fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
 		struct f2fs_node *, u32 *, struct node_info *);
 extern int fsck_chk_dnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
diff --git a/fsck/main.c b/fsck/main.c
index 16fab9c..e0b126b 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -152,7 +152,7 @@ static void do_fsck(struct f2fs_sb_info *sbi)
 
 	/* Traverse all block recursively from root inode */
 	blk_cnt = 1;
-	fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num,
+	fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num, (u8 *)"/",
 			F2FS_FT_DIR, TYPE_INODE, &blk_cnt);
 	fsck_verify(sbi);
 	fsck_free(sbi);
-- 
2.1.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/6] fsck.f2fs: check file types
  2015-03-27  0:03 [PATCH 1/6] fsck.f2fs: reduce redundant message Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 2/6] fsck.f2fs: remove inconsistent named directories Jaegeuk Kim
@ 2015-03-27  0:03 ` Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 4/6] fsck.f2fs: fix inodes having wrong i_links Jaegeuk Kim
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2015-03-27  0:03 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

If the file type is mismatched, we should drop that inode.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index e803fa0..8db8f27 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -189,6 +189,30 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
 	return 0;
 }
 
+static int __check_inode_mode(u32 nid, enum FILE_TYPE ftype, u32 mode)
+{
+	if (ftype >= F2FS_FT_MAX)
+		return 0;
+	if (S_ISLNK(mode) && ftype != F2FS_FT_SYMLINK)
+		goto err;
+	if (S_ISREG(mode) && ftype != F2FS_FT_REG_FILE)
+		goto err;
+	if (S_ISDIR(mode) && ftype != F2FS_FT_DIR)
+		goto err;
+	if (S_ISCHR(mode) && ftype != F2FS_FT_CHRDEV)
+		goto err;
+	if (S_ISBLK(mode) && ftype != F2FS_FT_BLKDEV)
+		goto err;
+	if (S_ISFIFO(mode) && ftype != F2FS_FT_FIFO)
+		goto err;
+	if (S_ISSOCK(mode) && ftype != F2FS_FT_SOCK)
+		goto err;
+	return 0;
+err:
+	ASSERT_MSG("mismatch i_mode [0x%x] [0x%x vs. 0x%x]", nid, ftype, mode);
+	return -1;
+}
+
 static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
 			struct f2fs_node *node_blk,
 			enum FILE_TYPE ftype, enum NODE_TYPE ntype,
@@ -272,6 +296,10 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
 		}
 	}
 
+	if (ntype == TYPE_INODE &&
+		__check_inode_mode(nid, ftype, le32_to_cpu(node_blk->i.i_mode)))
+		return -EINVAL;
+
 	/* workaround to fix later */
 	if (ftype != F2FS_FT_ORPHAN ||
 			f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
-- 
2.1.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/6] fsck.f2fs: fix inodes having wrong i_links
  2015-03-27  0:03 [PATCH 1/6] fsck.f2fs: reduce redundant message Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 2/6] fsck.f2fs: remove inconsistent named directories Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 3/6] fsck.f2fs: check file types Jaegeuk Kim
@ 2015-03-27  0:03 ` Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 5/6] fsck.f2fs: skip block count fix when i_links is fixed Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 6/6] fsck.f2fs: preserve orphan blocks Jaegeuk Kim
  4 siblings, 0 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2015-03-27  0:03 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch fixes inodes which have wrong i_links.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c | 41 +++++++++++++++++++++++++++++++++++++++++
 fsck/fsck.h |  1 +
 2 files changed, 42 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 8db8f27..8cfea56 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -63,6 +63,7 @@ static int add_into_hard_link_list(struct f2fs_sb_info *sbi,
 
 	node->nid = nid;
 	node->links = link_cnt;
+	node->actual_links = 1;
 	node->next = NULL;
 
 	if (fsck->hard_link_list_head == NULL) {
@@ -112,6 +113,7 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
 
 	/* Decrease link count */
 	node->links = node->links - 1;
+	node->actual_links++;
 
 	/* if link count becomes one, remove the node */
 	if (node->links == 1) {
@@ -296,6 +298,10 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
 		}
 	}
 
+	/* this if only from fix_hard_links */
+	if (ftype == F2FS_FT_MAX)
+		return 0;
+
 	if (ntype == TYPE_INODE &&
 		__check_inode_mode(nid, ftype, le32_to_cpu(node_blk->i.i_mode)))
 		return -EINVAL;
@@ -999,6 +1005,40 @@ void fsck_init(struct f2fs_sb_info *sbi)
 	ASSERT(tree_mark != NULL);
 }
 
+static void fix_hard_links(struct f2fs_sb_info *sbi)
+{
+	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+	struct hard_link_node *tmp, *node;
+	struct f2fs_node *node_blk = NULL;
+	struct node_info ni;
+	int ret;
+
+	if (fsck->hard_link_list_head == NULL)
+		return;
+
+	node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
+	ASSERT(node_blk != NULL);
+
+	node = fsck->hard_link_list_head;
+	while (node) {
+		/* Sanity check */
+		if (sanity_check_nid(sbi, node->nid, node_blk,
+					F2FS_FT_MAX, TYPE_INODE, &ni, NULL))
+			FIX_MSG("Failed to fix, rerun fsck.f2fs");
+
+		node_blk->i.i_links = cpu_to_le32(node->actual_links);
+
+		FIX_MSG("File: 0x%x i_links= 0x%x -> 0x%x",
+				node->nid, node->links, node->actual_links);
+
+		ret = dev_write_block(node_blk, ni.blk_addr);
+		ASSERT(ret >= 0);
+		tmp = node;
+		node = node->next;
+		free(tmp);
+	}
+}
+
 static void fix_nat_entries(struct f2fs_sb_info *sbi)
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -1223,6 +1263,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
 
 	/* fix global metadata */
 	if (force || (config.bug_on && config.fix_on)) {
+		fix_hard_links(sbi);
 		fix_nat_entries(sbi);
 		rewrite_sit_area_bitmap(sbi);
 		fix_checkpoint(sbi);
diff --git a/fsck/fsck.h b/fsck/fsck.h
index ff2b25d..1c2ef94 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -67,6 +67,7 @@ enum NODE_TYPE {
 struct hard_link_node {
 	u32 nid;
 	u32 links;
+	u32 actual_links;
 	struct hard_link_node *next;
 };
 
-- 
2.1.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/6] fsck.f2fs: skip block count fix when i_links is fixed
  2015-03-27  0:03 [PATCH 1/6] fsck.f2fs: reduce redundant message Jaegeuk Kim
                   ` (2 preceding siblings ...)
  2015-03-27  0:03 ` [PATCH 4/6] fsck.f2fs: fix inodes having wrong i_links Jaegeuk Kim
@ 2015-03-27  0:03 ` Jaegeuk Kim
  2015-03-27  0:03 ` [PATCH 6/6] fsck.f2fs: preserve orphan blocks Jaegeuk Kim
  4 siblings, 0 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2015-03-27  0:03 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

If i_links is wrong, we should not check block count, since it doesn't count
correctly which results in changing the block count to 1.

This patch fixes that.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 8cfea56..97bf6ce 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -440,7 +440,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 						"i_links= 0x%x -> 0x%x",
 						nid, i_links, i_links + 1);
 				}
-				goto check;
+				goto skip_blkcnt_fix;
 			}
 			/* No need to go deep into the node */
 			return;
@@ -550,6 +550,18 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
 		}
 	}
 check:
+	if (i_blocks != *blk_cnt) {
+		ASSERT_MSG("ino: 0x%x has i_blocks: %08"PRIx64", "
+				"but has %u blocks",
+				nid, i_blocks, *blk_cnt);
+		if (config.fix_on) {
+			node_blk->i.i_blocks = cpu_to_le64(*blk_cnt);
+			need_fix = 1;
+			FIX_MSG("[0x%x] i_blocks=0x%08"PRIx64" -> 0x%x",
+					nid, i_blocks, *blk_cnt);
+		}
+	}
+skip_blkcnt_fix:
 	if (ftype == F2FS_FT_DIR)
 		DBG(1, "Directory Inode: 0x%x [%s] depth: %d has %d files\n\n",
 				le32_to_cpu(node_blk->footer.ino),
@@ -562,17 +574,6 @@ check:
 				node_blk->i.i_name,
 				(u32)i_blocks);
 
-	if (i_blocks != *blk_cnt) {
-		ASSERT_MSG("ino: 0x%x has i_blocks: %08"PRIx64", "
-				"but has %u blocks",
-				nid, i_blocks, *blk_cnt);
-		if (config.fix_on) {
-			node_blk->i.i_blocks = cpu_to_le64(*blk_cnt);
-			need_fix = 1;
-			FIX_MSG("[0x%x] i_blocks=0x%08"PRIx64" -> 0x%x",
-					nid, i_blocks, *blk_cnt);
-		}
-	}
 	if (ftype == F2FS_FT_DIR && i_links != child_cnt) {
 		ASSERT_MSG("ino: 0x%x has i_links: %u but real links: %u",
 				nid, i_links, child_cnt);
-- 
2.1.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 6/6] fsck.f2fs: preserve orphan blocks
  2015-03-27  0:03 [PATCH 1/6] fsck.f2fs: reduce redundant message Jaegeuk Kim
                   ` (3 preceding siblings ...)
  2015-03-27  0:03 ` [PATCH 5/6] fsck.f2fs: skip block count fix when i_links is fixed Jaegeuk Kim
@ 2015-03-27  0:03 ` Jaegeuk Kim
  4 siblings, 0 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2015-03-27  0:03 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

If fsck.f2fs found some orphan blocks, previously fsck.f2fs drops them and
fixes checkpoint, resulting in false alarm on corruption.
This patch preserves orphan blocks to avoid such the alarms.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c | 48 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 97bf6ce..6b687d8 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -946,8 +946,10 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
 {
 	u32 blk_cnt = 0;
 	block_t start_blk, orphan_blkaddr, i, j;
-	struct f2fs_orphan_block *orphan_blk;
+	struct f2fs_orphan_block *orphan_blk, *new_blk;
 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
+	u32 entry_count;
+	u32 new_entry_count = 0;
 
 	if (!is_set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG))
 		return;
@@ -955,28 +957,43 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
 	start_blk = __start_cp_addr(sbi) + 1 +
 		le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
 	orphan_blkaddr = __start_sum_addr(sbi) - 1;
+
 	orphan_blk = calloc(BLOCK_SZ, 1);
+	ASSERT(orphan_blk);
+
+	new_blk = calloc(BLOCK_SZ, 1);
+	ASSERT(new_blk);
 
 	for (i = 0; i < orphan_blkaddr; i++) {
 		int ret = dev_read_block(orphan_blk, start_blk + i);
 
 		ASSERT(ret >= 0);
+		entry_count = le32_to_cpu(orphan_blk->entry_count);
 
-		for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
+		for (j = 0; j < entry_count; j++) {
 			nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
 			DBG(1, "[%3d] ino [0x%x]\n", i, ino);
-			if (config.fix_on) {
-				FIX_MSG("Discard orphan inodes: ino [0x%x]",
-									ino);
-				continue;
-			}
 			blk_cnt = 1;
-			fsck_chk_node_blk(sbi, NULL, ino, NULL,
+			ret = fsck_chk_node_blk(sbi, NULL, ino, NULL,
 					F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
+			if (!ret)
+				new_blk->ino[new_entry_count++] =
+							orphan_blk->ino[j];
+			else if (ret && config.fix_on)
+				FIX_MSG("[0x%x] remove from orphan list", ino);
+			else if (ret)
+				ASSERT_MSG("[0x%x] wrong orphan inode", ino);
+		}
+		if (config.fix_on && entry_count != new_entry_count) {
+			new_blk->entry_count = cpu_to_le32(new_entry_count);
+			ret = dev_write_block(new_blk, start_blk + i);
+			ASSERT(ret >= 0);
 		}
 		memset(orphan_blk, 0, BLOCK_SZ);
+		memset(new_blk, 0, BLOCK_SZ);
 	}
 	free(orphan_blk);
+	free(new_blk);
 }
 
 void fsck_init(struct f2fs_sb_info *sbi)
@@ -1056,15 +1073,20 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
 	struct f2fs_super_block *raw_sb = sbi->raw_super;
 	struct f2fs_checkpoint *ckp = F2FS_CKPT(sbi);
 	unsigned long long cp_blk_no;
+	u32 flags = CP_UMOUNT_FLAG;
+	block_t orphan_blks = 0;
 	u32 i;
 	int ret;
 	u_int32_t crc = 0;
 
-	ckp->ckpt_flags = cpu_to_le32(CP_UMOUNT_FLAG);
+	if (is_set_ckpt_flags(ckp, CP_ORPHAN_PRESENT_FLAG)) {
+		orphan_blks = __start_sum_addr(sbi) - 1;
+		flags |= CP_ORPHAN_PRESENT_FLAG;
+	}
+
+	ckp->ckpt_flags = cpu_to_le32(flags);
 	ckp->cp_pack_total_block_count =
-		cpu_to_le32(8 + le32_to_cpu(raw_sb->cp_payload));
-	ckp->cp_pack_start_sum = cpu_to_le32(1 +
-				le32_to_cpu(raw_sb->cp_payload));
+		cpu_to_le32(8 + orphan_blks + le32_to_cpu(raw_sb->cp_payload));
 
 	ckp->free_segment_count = cpu_to_le32(fsck->chk.free_segs);
 	ckp->valid_block_count = cpu_to_le32(fsck->chk.valid_blk_cnt);
@@ -1088,6 +1110,8 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
 		ASSERT(ret >= 0);
 	}
 
+	cp_blk_no += orphan_blks;
+
 	for (i = 0; i < NO_CHECK_TYPE; i++) {
 		struct curseg_info *curseg = CURSEG_I(sbi, i);
 
-- 
2.1.1


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-03-27  0:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-27  0:03 [PATCH 1/6] fsck.f2fs: reduce redundant message Jaegeuk Kim
2015-03-27  0:03 ` [PATCH 2/6] fsck.f2fs: remove inconsistent named directories Jaegeuk Kim
2015-03-27  0:03 ` [PATCH 3/6] fsck.f2fs: check file types Jaegeuk Kim
2015-03-27  0:03 ` [PATCH 4/6] fsck.f2fs: fix inodes having wrong i_links Jaegeuk Kim
2015-03-27  0:03 ` [PATCH 5/6] fsck.f2fs: skip block count fix when i_links is fixed Jaegeuk Kim
2015-03-27  0:03 ` [PATCH 6/6] fsck.f2fs: preserve orphan blocks Jaegeuk Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.