[f2fs-dev] [PATCH AUTOSEL 4.14 87/95] f2fs: fix to data block override node segment by mistake

2019-05-06 Thread Sasha Levin
From: zhengliang 

[ Upstream commit a0770e13c8da83bdb64738c0209ab02dd3cfff8b ]

v4: Rearrange the previous three versions.

The following scenario could lead to data block override by mistake.

TASK A|  TASK kworker|  
   TASK B|   TASK C
  |  |  
 |
open  |  |  
 |
write |  |  
 |
close |  |  
 |
  |  f2fs_write_data_pages   |  
 |
  |f2fs_write_cache_pages|  
 |
  |  f2fs_outplace_write_data|  
 |
  |f2fs_allocate_data_block (get block in seg S, |  
 |
  |  S is full, and only |  
 |
  |  have this valid data|  
 |
  |  block)  |  
 |
  |  allocate_segment|  
 |
  |  locate_dirty_segment (mark S as PRE)|  
 |
  |f2fs_submit_page_write (submit but is not |  
 |
  |written on dev)   |  
 |
unlink|  |  
 |
 iput_final   |  |  
 |
  f2fs_drop_inode |  |  
 |
f2fs_truncate |  |  
 |
 (not evict)  |  |  
 |
  |  | 
write_checkpoint  |
  |  |  
flush merged bio but not wait file data writeback|
  |  |  
set_prefree_as_free (mark S as FREE) |
  |  |  
 | update NODE/DATA
  |  |  
 | allocate_segment (select 
S)
  | writeback done   |  
 |

So we need to guarantee io complete before truncate inode in f2fs_drop_inode.

Reviewed-by: Chao Yu 
Signed-off-by: Zheng Liang 
Signed-off-by: Jaegeuk Kim 
Signed-off-by: Sasha Levin 
---
 fs/f2fs/super.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4c169ba50c0f..06b75737b1a0 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -668,6 +668,10 @@ static int f2fs_drop_inode(struct inode *inode)
sb_start_intwrite(inode->i_sb);
f2fs_i_size_write(inode, 0);
 
+   f2fs_submit_merged_write_cond(F2FS_I_SB(inode),
+   inode, NULL, 0, DATA);
+   truncate_inode_pages_final(inode->i_mapping);
+
if (F2FS_HAS_BLOCKS(inode))
f2fs_truncate(inode);
 
-- 
2.20.1



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH AUTOSEL 4.19 69/81] f2fs: fix to data block override node segment by mistake

2019-05-06 Thread Sasha Levin
From: zhengliang 

[ Upstream commit a0770e13c8da83bdb64738c0209ab02dd3cfff8b ]

v4: Rearrange the previous three versions.

The following scenario could lead to data block override by mistake.

TASK A|  TASK kworker|  
   TASK B|   TASK C
  |  |  
 |
open  |  |  
 |
write |  |  
 |
close |  |  
 |
  |  f2fs_write_data_pages   |  
 |
  |f2fs_write_cache_pages|  
 |
  |  f2fs_outplace_write_data|  
 |
  |f2fs_allocate_data_block (get block in seg S, |  
 |
  |  S is full, and only |  
 |
  |  have this valid data|  
 |
  |  block)  |  
 |
  |  allocate_segment|  
 |
  |  locate_dirty_segment (mark S as PRE)|  
 |
  |f2fs_submit_page_write (submit but is not |  
 |
  |written on dev)   |  
 |
unlink|  |  
 |
 iput_final   |  |  
 |
  f2fs_drop_inode |  |  
 |
f2fs_truncate |  |  
 |
 (not evict)  |  |  
 |
  |  | 
write_checkpoint  |
  |  |  
flush merged bio but not wait file data writeback|
  |  |  
set_prefree_as_free (mark S as FREE) |
  |  |  
 | update NODE/DATA
  |  |  
 | allocate_segment (select 
S)
  | writeback done   |  
 |

So we need to guarantee io complete before truncate inode in f2fs_drop_inode.

Reviewed-by: Chao Yu 
Signed-off-by: Zheng Liang 
Signed-off-by: Jaegeuk Kim 
Signed-off-by: Sasha Levin 
---
 fs/f2fs/super.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 2264f27fd26d..036eb1e0d557 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -890,6 +890,10 @@ static int f2fs_drop_inode(struct inode *inode)
sb_start_intwrite(inode->i_sb);
f2fs_i_size_write(inode, 0);
 
+   f2fs_submit_merged_write_cond(F2FS_I_SB(inode),
+   inode, NULL, 0, DATA);
+   truncate_inode_pages_final(inode->i_mapping);
+
if (F2FS_HAS_BLOCKS(inode))
f2fs_truncate(inode);
 
-- 
2.20.1



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC PATCH 0/7] xfstests: verify fscrypt-encrypted contents and filenames

2019-05-06 Thread Eric Biggers
On Fri, Apr 26, 2019 at 01:41:46PM -0700, Eric Biggers wrote:
> Hello,
> 
> This series adds xfstests which verify that encrypted contents and
> filenames on ext4 and f2fs are actually correct, i.e. that the
> encryption uses the correct algorithms, keys, IVs, and padding amounts.
> The new tests work by creating encrypted files, unmounting the
> filesystem, reading the ciphertext from disk using dd and debugfs or
> dump.f2fs, and then comparing it against ciphertext computed
> independently by a new test program that implements the same algorithms.
> 
> These tests are important because:
> 
> - The whole point of file encryption is that the files are actually
>   encrypted correctly on-disk.  Except for generic/399, current xfstests
>   only tests the filesystem semantics, not the actual encryption.
>   generic/399 only tests for incompressibility of encrypted file
>   contents using one particular encryption setting, which isn't much.
> 
> - fscrypt now supports 4 main combinations of encryption settings,
>   rather than 1 as it did originally.  This may be doubled to 8 soon
>   (https://patchwork.kernel.org/patch/10908153/).  We should test all
>   settings.  And without tests, even if the initial implementation is
>   correct, breakage in one specific setting could go undetected.
> 
> - Though Linux's crypto API has self-tests, these only test the
>   algorithms themselves, not how they are used, e.g. by fscrypt.
> 
> Patch 1 is a cleanup patch.  Patches 2-4 add the common helpers for
> ciphertext verification tests.  Patches 5-7 add the actual tests.
> 
> These tests require e2fsprogs and f2fs-tools patches I recently sent out
> to fix printing encrypted filenames.  So, this series might not be
> suitable for merging into mainline xfstests until those patches are
> applied.  Regardless, comments are appreciated.  The needed patches are:
> 
>   debugfs: avoid ambiguity when printing filenames 
> (https://marc.info/?l=linux-ext4=155596495624232=2)
>   f2fs-tools: improve filename printing 
> (https://sourceforge.net/p/linux-f2fs/mailman/message/36648641/)
> 
> This series can also be retrieved from git at
> https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/xfstests-dev.git
> branch "ciphertext-verification".
> 
> I also have patches on top of this series which verify the ciphertext
> produced from v2 encryption policies, which are proposed by my kernel
> patch series "fscrypt: key management improvements"
> (https://patchwork.kernel.org/cover/10908107/).  v2 encryption policies
> will use a different key derivation function, and thus their ciphertext
> will be different.  These additional patches can be found at branch
> "fscrypt-key-mgmt-improvements" of my git repo above.  But I've arranged
> things such that this shorter series can potentially be applied earlier,
> to test what's in the kernel now.
> 
> Eric Biggers (7):
>   common/encrypt: introduce helpers for set_encpolicy and get_encpolicy
>   fscrypt-crypt-util: add utility for reproducing fscrypt encrypted data
>   common/encrypt: support requiring other encryption settings
>   common/encrypt: add helper for ciphertext verification tests
>   generic: verify ciphertext of v1 encryption policies with AES-256
>   generic: verify ciphertext of v1 encryption policies with AES-128
>   generic: verify ciphertext of v1 encryption policies with Adiantum
> 
>  .gitignore   |1 +
>  common/encrypt   |  482 ++-
>  src/Makefile |3 +-
>  src/fscrypt-crypt-util.c | 1645 ++
>  tests/ext4/024   |3 +-
>  tests/generic/395|   28 +-
>  tests/generic/395.out|2 +-
>  tests/generic/396|   15 +-
>  tests/generic/397|3 +-
>  tests/generic/398|5 +-
>  tests/generic/399|3 +-
>  tests/generic/419|3 +-
>  tests/generic/421|3 +-
>  tests/generic/429|3 +-
>  tests/generic/435|3 +-
>  tests/generic/440|5 +-
>  tests/generic/700|   41 +
>  tests/generic/700.out|5 +
>  tests/generic/701|   41 +
>  tests/generic/701.out|5 +
>  tests/generic/702|   43 +
>  tests/generic/702.out|   10 +
>  tests/generic/group  |3 +
>  23 files changed, 2308 insertions(+), 47 deletions(-)
>  create mode 100644 src/fscrypt-crypt-util.c
>  create mode 100755 tests/generic/700
>  create mode 100644 tests/generic/700.out
>  create mode 100755 tests/generic/701
>  create mode 100644 tests/generic/701.out
>  create mode 100755 tests/generic/702
>  create mode 100644 tests/generic/702.out
> 
> -- 
> 2.21.0.593.g511ec345e18-goog
> 

Any comments on this?

FYI, the e2fsprogs patch that these tests need was applied.

I'm still waiting for the f2fs-tools patch.

- Eric


___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net

Re: [f2fs-dev] [PATCH 06/13] fscrypt: support encrypting multiple filesystem blocks per page

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:08 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> Rename fscrypt_encrypt_page() to fscrypt_encrypt_pagecache_blocks() and
> redefine its behavior to encrypt all filesystem blocks from the given
> region of the given page, rather than assuming that the region consists
> of just one filesystem block.  Also remove the 'inode' and 'lblk_num'
> parameters, since they can be retrieved from the page as it's already
> assumed to be a pagecache page.
> 
> This is in preparation for allowing encryption on ext4 filesystems with
> blocksize != PAGE_SIZE.
> 
> This is based on work by Chandan Rajendra.

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 08/13] fscrypt: introduce fscrypt_decrypt_block_inplace()

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:10 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> fscrypt_decrypt_page() behaves very differently depending on whether the
> filesystem set FS_CFLG_OWN_PAGES in its fscrypt_operations.  This makes
> the function difficult to understand and document.  It also makes it so
> that all callers have to provide inode and lblk_num, when fscrypt could
> determine these itself for pagecache pages.
> 
> Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function
> fscrypt_decrypt_block_inplace().
>

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 09/13] fscrypt: support decrypting multiple filesystem blocks per page

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:11 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> Rename fscrypt_decrypt_page() to fscrypt_decrypt_pagecache_blocks() and
> redefine its behavior to decrypt all filesystem blocks in the given
> region of the given page, rather than assuming that the region consists
> of just one filesystem block.  Also remove the 'inode' and 'lblk_num'
> parameters, since they can be retrieved from the page as it's already
> assumed to be a pagecache page.
> 
> This is in preparation for allowing encryption on ext4 filesystems with
> blocksize != PAGE_SIZE.
> 
> This is based on work by Chandan Rajendra.

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 05/13] fscrypt: introduce fscrypt_encrypt_block_inplace()

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:07 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> fscrypt_encrypt_page() behaves very differently depending on whether the
> filesystem set FS_CFLG_OWN_PAGES in its fscrypt_operations.  This makes
> the function difficult to understand and document.  It also makes it so
> that all callers have to provide inode and lblk_num, when fscrypt could
> determine these itself for pagecache pages.
> 
> Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function
> fscrypt_encrypt_block_inplace().

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 07/13] fscrypt: handle blocksize < PAGE_SIZE in fscrypt_zeroout_range()

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:09 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> Adjust fscrypt_zeroout_range() to encrypt a block at a time rather than
> a page at a time, so that it works when blocksize < PAGE_SIZE.
> 
> This isn't optimized for performance, but then again this function
> already wasn't optimized for performance.  As a future optimization, we
> could submit much larger bios here.
> 
> This is in preparation for allowing encryption on ext4 filesystems with
> blocksize != PAGE_SIZE.
> 
> This is based on work by Chandan Rajendra.


Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 13/13] ext4: encrypt only up to last block in ext4_bio_write_page()

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:15 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> As an optimization, don't encrypt blocks fully beyond i_size, since
> those definitely won't need to be written out.  Also add a comment.
> 
> This is in preparation for allowing encryption on ext4 filesystems with
> blocksize != PAGE_SIZE.
> 
> This is based on work by Chandan Rajendra.
>

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 04/13] fscrypt: clean up some BUG_ON()s in block encryption/decryption

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:06 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> Replace some BUG_ON()s with WARN_ON_ONCE() and returning an error code,
> and move the check for len divisible by FS_CRYPTO_BLOCK_SIZE into
> fscrypt_crypt_block() so that it's done for both encryption and
> decryption, not just encryption.

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v4 2/2] sload.f2fs: introduce f2fs_sparse_initialize_meta()

2019-05-06 Thread Chao Yu
This patch fixes to initialize NAT/SIT/CP.payload region in sparse
file mode for sload.

Signed-off-by: Chao Yu 
---
- move initialize_meta() before do_umount().
 fsck/fsck.h  |  1 +
 fsck/main.c  |  4 +++
 fsck/mount.c | 70 
 3 files changed, 75 insertions(+)

diff --git a/fsck/fsck.h b/fsck/fsck.h
index dd831de..4db14af 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -181,6 +181,7 @@ extern int fsck_verify(struct f2fs_sb_info *);
 extern void fsck_free(struct f2fs_sb_info *);
 extern int f2fs_do_mount(struct f2fs_sb_info *);
 extern void f2fs_do_umount(struct f2fs_sb_info *);
+extern int f2fs_sparse_initialize_meta(struct f2fs_sb_info *);
 
 extern void flush_journal_entries(struct f2fs_sb_info *);
 extern void zero_journal_entries(struct f2fs_sb_info *);
diff --git a/fsck/main.c b/fsck/main.c
index afdfec9..d844820 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -813,6 +813,10 @@ fsck_again:
if (do_sload(sbi))
goto out_err;
 
+   ret = f2fs_sparse_initialize_meta(sbi);
+   if (ret < 0)
+   goto out_err;
+
f2fs_do_umount(sbi);
 
/* fsck to fix missing quota */
diff --git a/fsck/mount.c b/fsck/mount.c
index 843742e..230f330 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -2721,3 +2721,73 @@ void f2fs_do_umount(struct f2fs_sb_info *sbi)
free(sbi->ckpt);
free(sbi->raw_super);
 }
+
+#ifdef WITH_ANDROID
+int f2fs_sparse_initialize_meta(struct f2fs_sb_info *sbi)
+{
+   struct f2fs_super_block *sb = sbi->raw_super; 
+   u_int32_t sit_seg_count, sit_size;
+   u_int32_t nat_seg_count, nat_size;
+   u_int64_t sit_seg_addr, nat_seg_addr, payload_addr;
+   u_int32_t seg_size = 1 << get_sb(log_blocks_per_seg);
+   int ret;
+
+   if (!c.sparse_mode)
+   return 0;
+
+   sit_seg_addr = get_sb(sit_blkaddr);
+   sit_seg_count = get_sb(segment_count_sit);
+   sit_size = sit_seg_count * seg_size;
+
+   DBG(1, "\tSparse: filling sit area at block offset: 0x%08"PRIx64" len: 
%u\n",
+   sit_seg_addr, sit_size);
+   ret = dev_fill(NULL, sit_seg_addr * F2FS_BLKSIZE,
+   sit_size * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the sit area "
+   "on disk!!!\n");
+   return -1;
+   }
+
+   nat_seg_addr = get_sb(nat_blkaddr);
+   nat_seg_count = get_sb(segment_count_nat);
+   nat_size = nat_seg_count * seg_size;
+
+   DBG(1, "\tSparse: filling nat area at block offset 0x%08"PRIx64" len: 
%u\n",
+   nat_seg_addr, nat_size);
+   ret = dev_fill(NULL, nat_seg_addr * F2FS_BLKSIZE,
+   nat_size * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the nat area "
+   "on disk!!!\n");
+   return -1;
+   }
+
+   payload_addr = get_sb(segment0_blkaddr) + 1;
+
+   DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" 
len: %u\n",
+   payload_addr, get_sb(cp_payload));
+   ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE,
+   get_sb(cp_payload) * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the nat/sit bitmap area "
+   "on disk!!!\n");
+   return -1;
+   }
+
+   payload_addr += seg_size;
+
+   DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" 
len: %u\n",
+   payload_addr, get_sb(cp_payload));
+   ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE,
+   get_sb(cp_payload) * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the nat/sit bitmap area "
+   "on disk!!!\n");
+   return -1;
+   }
+   return 0;
+}
+#else
+int f2fs_sparse_initialize_meta(struct f2fs_sb_info *sbi) { return 0; }
+#endif
-- 
2.18.0.rc1



___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH v3 2/2] f2fs-tools: introduce f2fs_update_sparse_file()

2019-05-06 Thread Chao Yu
This patch fixes to initialize NAT/SIT/CP.payload region in sparse
file mode for fsck/sload/resize/defrag/dump tools.

Signed-off-by: Chao Yu 
---
v3:
- print message after variable assignment.
- use DEFAULT_BLOCKS_PER_SEGMENT instead of get_sb(log_blocks_per_seg).

 fsck/fsck.h  |  1 +
 fsck/main.c  |  5 +++
 fsck/mount.c | 82 
 lib/libf2fs_io.c |  9 --
 4 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/fsck/fsck.h b/fsck/fsck.h
index dd831de..95bb7d3 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -181,6 +181,7 @@ extern int fsck_verify(struct f2fs_sb_info *);
 extern void fsck_free(struct f2fs_sb_info *);
 extern int f2fs_do_mount(struct f2fs_sb_info *);
 extern void f2fs_do_umount(struct f2fs_sb_info *);
+extern int f2fs_update_sparse_file(struct f2fs_sb_info *);
 
 extern void flush_journal_entries(struct f2fs_sb_info *);
 extern void zero_journal_entries(struct f2fs_sb_info *);
diff --git a/fsck/main.c b/fsck/main.c
index afdfec9..0670696 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -845,6 +845,11 @@ retry:
goto fsck_again;
}
}
+
+   ret = f2fs_update_sparse_file(sbi);
+   if (ret < 0)
+   return ret;
+
ret = f2fs_finalize_device();
if (ret < 0)
return ret;
diff --git a/fsck/mount.c b/fsck/mount.c
index 843742e..9c73cda 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -2721,3 +2721,85 @@ void f2fs_do_umount(struct f2fs_sb_info *sbi)
free(sbi->ckpt);
free(sbi->raw_super);
 }
+
+#ifdef WITH_ANDROID
+static int sparse_initialize_meta(struct f2fs_sb_info *sbi)
+{
+   u_int32_t sit_seg_count, sit_size;
+   u_int32_t nat_seg_count, nat_size;
+   u_int64_t sit_seg_addr, nat_seg_addr, payload_addr;
+   u_int32_t seg_size = DEFAULT_BLOCKS_PER_SEGMENT;
+   int ret;
+
+   sit_seg_addr = get_sb(sit_blkaddr);
+   sit_seg_count = get_sb(segment_count_sit);
+   sit_size = sit_seg_count * seg_size;
+
+   DBG(1, "\tSparse: filling sit area at block offset: 0x%08"PRIx64" len: 
%u\n",
+   sit_seg_addr, sit_size);
+   ret = dev_fill(NULL, sit_seg_addr * F2FS_BLKSIZE,
+   sit_size * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the sit area "
+   "on disk!!!\n");
+   return -1;
+   }
+
+   nat_seg_addr = get_sb(nat_blkaddr);
+   nat_seg_count = get_sb(segment_count_nat);
+   nat_size = nat_seg_count * seg_size;
+
+   DBG(1, "\tSparse: filling nat area at block offset 0x%08"PRIx64" len: 
%u\n",
+   nat_seg_addr, nat_size);
+   ret = dev_fill(NULL, nat_seg_addr * F2FS_BLKSIZE,
+   nat_size * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the nat area "
+   "on disk!!!\n");
+   return -1;
+   }
+
+   payload_addr = get_sb(segment0_blkaddr) + 1;
+
+   DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" 
len: %u\n",
+   payload_addr, get_sb(cp_payload));
+   ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE,
+   get_sb(cp_payload) * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the nat/sit bitmap area "
+   "on disk!!!\n");
+   return -1;
+   }
+
+   payload_addr += seg_size;
+
+   DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" 
len: %u\n",
+   payload_addr, get_sb(cp_payload));
+   ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE,
+   get_sb(cp_payload) * F2FS_BLKSIZE);
+   if (ret) {
+   MSG(1, "\tError: While zeroing out the nat/sit bitmap area "
+   "on disk!!!\n");
+   return -1;
+   }
+   return 0;
+}
+
+int f2fs_update_sparse_file(struct f2fs_sb_info *sbi)
+{
+   int ret;
+
+   if (!c.sparse_mode)
+   return 0;
+
+   sparse_file_destroy(f2fs_sparse_file);
+   ret = ftruncate(c.devices[0].fd, 0);
+   ASSERT(!ret);
+   lseek(c.devices[0].fd, 0, SEEK_SET);
+   f2fs_sparse_file = sparse_file_new(F2FS_BLKSIZE, c.device_size);
+
+   return sparse_initialize_meta(sbi);
+}
+#else
+int f2fs_update_sparse_file(struct f2fs_sb_info *sbi) { return 0; }
+#endif
diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c
index 4d0ea0d..2f2b6bd 100644
--- a/lib/libf2fs_io.c
+++ b/lib/libf2fs_io.c
@@ -358,15 +358,6 @@ int f2fs_finalize_device(void)
int64_t chunk_start = (blocks[0] == NULL) ? -1 : 0;
uint64_t j;
 
-   if