]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/f2fs/recovery.c
Merge remote-tracking branch 'v9fs/for-next'
[karo-tx-linux.git] / fs / f2fs / recovery.c
index 51ef5eec33d7fec07503e6eb9c90b86256b1dc3a..b278c68b3e0801d0a14454f7e96b74076507ba62 100644 (file)
@@ -64,24 +64,31 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
        name.name = raw_inode->i_name;
 retry:
        de = f2fs_find_entry(dir, &name, &page);
-       if (de && inode->i_ino == le32_to_cpu(de->ino)) {
-               kunmap(page);
-               f2fs_put_page(page, 0);
-               goto out;
-       }
+       if (de && inode->i_ino == le32_to_cpu(de->ino))
+               goto out_unmap_put;
        if (de) {
                einode = f2fs_iget(inode->i_sb, le32_to_cpu(de->ino));
                if (IS_ERR(einode)) {
                        WARN_ON(1);
                        if (PTR_ERR(einode) == -ENOENT)
                                err = -EEXIST;
-                       goto out;
+                       goto out_unmap_put;
+               }
+               err = acquire_orphan_inode(F2FS_SB(inode->i_sb));
+               if (err) {
+                       iput(einode);
+                       goto out_unmap_put;
                }
                f2fs_delete_entry(de, page, einode);
                iput(einode);
                goto retry;
        }
        err = __f2fs_add_link(dir, &name, inode);
+       goto out;
+
+out_unmap_put:
+       kunmap(page);
+       f2fs_put_page(page, 0);
 out:
        f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode and its dentry: "
                        "ino = %x, name = %s, dir = %lx, err = %d",
@@ -285,7 +292,6 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        struct f2fs_summary sum;
        struct node_info ni;
        int err = 0, recovered = 0;
-       int ilock;
 
        start = start_bidx_of_node(ofs_of_node(page), fi);
        if (IS_INODE(page))
@@ -293,12 +299,12 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        else
                end = start + ADDRS_PER_BLOCK;
 
-       ilock = mutex_lock_op(sbi);
+       f2fs_lock_op(sbi);
        set_new_dnode(&dn, inode, NULL, NULL, 0);
 
        err = get_dnode_of_data(&dn, start, ALLOC_NODE);
        if (err) {
-               mutex_unlock_op(sbi, ilock);
+               f2fs_unlock_op(sbi);
                return err;
        }
 
@@ -349,7 +355,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr);
 err:
        f2fs_put_dnode(&dn);
-       mutex_unlock_op(sbi, ilock);
+       f2fs_unlock_op(sbi);
 
        f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, "
                        "recovered_data = %d blocks, err = %d",
@@ -419,6 +425,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
 {
        struct list_head inode_list;
        int err;
+       bool need_writecp = false;
 
        fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
                        sizeof(struct fsync_inode_entry), NULL);
@@ -428,7 +435,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
        INIT_LIST_HEAD(&inode_list);
 
        /* step #1: find fsynced inode numbers */
-       sbi->por_doing = 1;
+       sbi->por_doing = true;
        err = find_fsync_dnodes(sbi, &inode_list);
        if (err)
                goto out;
@@ -436,14 +443,16 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
        if (list_empty(&inode_list))
                goto out;
 
+       need_writecp = true;
+
        /* step #2: recover data */
        err = recover_data(sbi, &inode_list, CURSEG_WARM_NODE);
        BUG_ON(!list_empty(&inode_list));
 out:
        destroy_fsync_dnodes(&inode_list);
        kmem_cache_destroy(fsync_entry_slab);
-       sbi->por_doing = 0;
-       if (!err)
+       sbi->por_doing = false;
+       if (!err && need_writecp)
                write_checkpoint(sbi, false);
        return err;
 }