*/
 bool f2fs_may_inline(struct inode *);
 void read_inline_data(struct page *, struct page *);
+bool truncate_inline_inode(struct page *, u64);
 int f2fs_read_inline_data(struct inode *, struct page *);
 int f2fs_convert_inline_page(struct dnode_of_data *, struct page *);
 int f2fs_convert_inline_inode(struct inode *);
 
        truncate_data_blocks_range(dn, ADDRS_PER_BLOCK);
 }
 
-static int truncate_partial_data_page(struct inode *inode, u64 from)
+static int truncate_partial_data_page(struct inode *inode, u64 from,
+                                                               bool force)
 {
        unsigned offset = from & (PAGE_CACHE_SIZE - 1);
        struct page *page;
 
-       if (!offset)
+       if (!offset && !force)
                return 0;
 
-       page = find_data_page(inode, from >> PAGE_CACHE_SHIFT, false);
+       page = find_data_page(inode, from >> PAGE_CACHE_SHIFT, force);
        if (IS_ERR(page))
                return 0;
 
 
        f2fs_wait_on_page_writeback(page, DATA);
        zero_user(page, offset, PAGE_CACHE_SIZE - offset);
-       set_page_dirty(page);
+       if (!force)
+               set_page_dirty(page);
 out:
        f2fs_put_page(page, 1);
        return 0;
        pgoff_t free_from;
        int count = 0, err = 0;
        struct page *ipage;
+       bool truncate_page = false;
 
        trace_f2fs_truncate_blocks_enter(inode, from);
 
        }
 
        if (f2fs_has_inline_data(inode)) {
+               if (truncate_inline_inode(ipage, from))
+                       set_page_dirty(ipage);
                f2fs_put_page(ipage, 1);
+               truncate_page = true;
                goto out;
        }
 
 
        /* lastly zero out the first data page */
        if (!err)
-               err = truncate_partial_data_page(inode, from);
+               err = truncate_partial_data_page(inode, from, truncate_page);
 
        trace_f2fs_truncate_blocks_exit(inode, err);
        return err;
 
        SetPageUptodate(page);
 }
 
-static void truncate_inline_data(struct page *ipage)
+bool truncate_inline_inode(struct page *ipage, u64 from)
 {
+       void *addr;
+
+       /*
+        * we should never truncate inline data past max inline data size,
+        * because we always convert inline inode to normal one before
+        * truncating real data if new size is past max inline data size.
+        */
+       f2fs_bug_on(F2FS_P_SB(ipage), from > MAX_INLINE_DATA);
+
+       if (from >= MAX_INLINE_DATA)
+               return false;
+
+       addr = inline_data_addr(ipage);
+
        f2fs_wait_on_page_writeback(ipage, NODE);
-       memset(inline_data_addr(ipage), 0, MAX_INLINE_DATA);
+       memset(addr + from, 0, MAX_INLINE_DATA - from);
+
+       return true;
 }
 
 int f2fs_read_inline_data(struct inode *inode, struct page *page)
        set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE);
 
        /* clear inline data and flag after data writeback */
-       truncate_inline_data(dn->inode_page);
+       truncate_inline_inode(dn->inode_page, 0);
 clear_out:
        stat_dec_inline_inode(dn->inode);
        f2fs_clear_inline_inode(dn->inode);
        if (f2fs_has_inline_data(inode)) {
                ipage = get_node_page(sbi, inode->i_ino);
                f2fs_bug_on(sbi, IS_ERR(ipage));
-               truncate_inline_data(ipage);
+               truncate_inline_inode(ipage, 0);
                f2fs_clear_inline_inode(inode);
                update_inode(inode, ipage);
                f2fs_put_page(ipage, 1);
        set_page_dirty(page);
 
        /* clear inline dir and flag after data writeback */
-       truncate_inline_data(ipage);
+       truncate_inline_inode(ipage, 0);
 
        stat_dec_inline_dir(dir);
        clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY);