]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
f2fs: truncate data blocks for orphan inode
authorJaegeuk Kim <jaegeuk@kernel.org>
Wed, 13 May 2015 21:35:14 +0000 (14:35 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 1 Jun 2015 23:20:54 +0000 (16:20 -0700)
As Hu reported, F2FS has a space leak problem, when conducting:

1) format a 4GB f2fs partition
2) dd a 3G file,
3) unlink it.

So, when doing f2fs_drop_inode(), we need to truncate data blocks
before skipping it.
We can also drop unused caches assigned to each inode.

Reported-by: hujianyang <hujianyang@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/super.c

index d5dfd143c3943dbaa2e3c6d203981ae07d249e4f..bfc900e87fccc1a9a2f6d4d334e37c13691251c4 100644 (file)
@@ -431,8 +431,30 @@ static int f2fs_drop_inode(struct inode *inode)
         *    - f2fs_gc -> iput -> evict
         *       - inode_wait_for_writeback(inode)
         */
-       if (!inode_unhashed(inode) && inode->i_state & I_SYNC)
+       if (!inode_unhashed(inode) && inode->i_state & I_SYNC) {
+               if (!inode->i_nlink && !is_bad_inode(inode)) {
+                       spin_unlock(&inode->i_lock);
+
+                       /* some remained atomic pages should discarded */
+                       if (f2fs_is_atomic_file(inode))
+                               commit_inmem_pages(inode, true);
+
+                       sb_start_intwrite(inode->i_sb);
+                       i_size_write(inode, 0);
+
+                       if (F2FS_HAS_BLOCKS(inode))
+                               f2fs_truncate(inode);
+
+                       sb_end_intwrite(inode->i_sb);
+
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+                       if (F2FS_I(inode)->i_crypt_info)
+                               f2fs_free_encryption_info(inode);
+#endif
+                       spin_lock(&inode->i_lock);
+               }
                return 0;
+       }
        return generic_drop_inode(inode);
 }