f2fs: recover invalid/reserved block address for fsynced file
[deliverable/linux.git] / fs / f2fs / recovery.c
index 07a36e413ace422766dd8847df6ff74b5c51d8c9..d2ef0c9f53e769d10386e772d7aafdc93cb79097 100644 (file)
@@ -399,14 +399,35 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
        f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page));
 
-       for (; start < end; start++) {
+       for (; start < end; start++, dn.ofs_in_node++) {
                block_t src, dest;
 
                src = datablock_addr(dn.node_page, dn.ofs_in_node);
                dest = datablock_addr(page, dn.ofs_in_node);
 
-               if (src != dest && dest != NEW_ADDR && dest != NULL_ADDR &&
-                       is_valid_blkaddr(sbi, dest, META_POR)) {
+               /* skip recovering if dest is the same as src */
+               if (src == dest)
+                       continue;
+
+               /* dest is invalid, just invalidate src block */
+               if (dest == NULL_ADDR) {
+                       truncate_data_blocks_range(&dn, 1);
+                       continue;
+               }
+
+               /*
+                * dest is reserved block, invalidate src block
+                * and then reserve one new block in dnode page.
+                */
+               if (dest == NEW_ADDR) {
+                       truncate_data_blocks_range(&dn, 1);
+                       err = reserve_new_block(&dn);
+                       f2fs_bug_on(sbi, err);
+                       continue;
+               }
+
+               /* dest is valid block, try to recover from src to dest */
+               if (is_valid_blkaddr(sbi, dest, META_POR)) {
 
                        if (src == NULL_ADDR) {
                                err = reserve_new_block(&dn);
@@ -424,7 +445,6 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
                                                        ni.version, false);
                        recovered++;
                }
-               dn.ofs_in_node++;
        }
 
        if (IS_INODE(dn.node_page))
This page took 0.031544 seconds and 5 git commands to generate.