f2fs: account for orphan inodes during recovery
authorRuss W. Knize <rknize@gmail.com>
Tue, 24 Sep 2013 14:40:57 +0000 (09:40 -0500)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Wed, 25 Sep 2013 08:59:32 +0000 (17:59 +0900)
During recovery, orphan inodes are deleted via truncate_hole().
These orphans are added by recover_dentry() via f2fs_delete_entry().
However, f2fs_delete_entry() adds them via add_orphan_inode()
without calling acquire_orphan_inode() first.  This prevents the
counters from being incremented properly, which causes them to
underflow when remove_orphan_inode() is called later on.

Signed-off-by: Russ Knize <rknize@motorola.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
fs/f2fs/recovery.c

index d43e4cd1f815cf231bba48ef0fd6eeada951e369..a15d122fdc50fff665762037cb64f943f42b474b 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",
This page took 0.027145 seconds and 5 git commands to generate.