return -EINVAL;
 }
 
-static int __add_dirty_inode(struct inode *inode, struct inode_entry *new)
+static void __add_dirty_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct f2fs_inode_info *fi = F2FS_I(inode);
 
-       if (is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR))
-               return -EEXIST;
+       if (is_inode_flag_set(fi, FI_DIRTY_DIR))
+               return;
 
-       set_inode_flag(F2FS_I(inode), FI_DIRTY_DIR);
-       F2FS_I(inode)->dirty_dir = new;
-       list_add_tail(&new->list, &sbi->dir_inode_list);
+       set_inode_flag(fi, FI_DIRTY_DIR);
+       list_add_tail(&fi->dirty_list, &sbi->dir_inode_list);
        stat_inc_dirty_dir(sbi);
-       return 0;
+       return;
 }
 
 void update_dirty_page(struct inode *inode, struct page *page)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-       struct inode_entry *new;
-       int ret = 0;
 
        if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
                        !S_ISLNK(inode->i_mode))
                goto out;
        }
 
-       new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
-       new->inode = inode;
-       INIT_LIST_HEAD(&new->list);
-
        spin_lock(&sbi->dir_inode_lock);
-       ret = __add_dirty_inode(inode, new);
+       __add_dirty_inode(inode);
        inode_inc_dirty_pages(inode);
        spin_unlock(&sbi->dir_inode_lock);
 
-       if (ret)
-               kmem_cache_free(inode_entry_slab, new);
 out:
        SetPagePrivate(page);
        f2fs_trace_pid(page);
 void add_dirty_dir_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-       struct inode_entry *new =
-                       f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
-       int ret = 0;
-
-       new->inode = inode;
-       INIT_LIST_HEAD(&new->list);
 
        spin_lock(&sbi->dir_inode_lock);
-       ret = __add_dirty_inode(inode, new);
+       __add_dirty_inode(inode);
        spin_unlock(&sbi->dir_inode_lock);
-
-       if (ret)
-               kmem_cache_free(inode_entry_slab, new);
 }
 
 void remove_dirty_dir_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-       struct inode_entry *entry;
+       struct f2fs_inode_info *fi = F2FS_I(inode);
 
        if (!S_ISDIR(inode->i_mode))
                return;
                return;
        }
 
-       entry = F2FS_I(inode)->dirty_dir;
-       list_del(&entry->list);
-       F2FS_I(inode)->dirty_dir = NULL;
-       clear_inode_flag(F2FS_I(inode), FI_DIRTY_DIR);
+       list_del_init(&fi->dirty_list);
+       clear_inode_flag(fi, FI_DIRTY_DIR);
        stat_dec_dirty_dir(sbi);
        spin_unlock(&sbi->dir_inode_lock);
-       kmem_cache_free(inode_entry_slab, entry);
 
        /* Only from the recovery routine */
-       if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) {
-               clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT);
+       if (is_inode_flag_set(fi, FI_DELAY_IPUT)) {
+               clear_inode_flag(fi, FI_DELAY_IPUT);
                iput(inode);
        }
 }
 void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
 {
        struct list_head *head;
-       struct inode_entry *entry;
        struct inode *inode;
+       struct f2fs_inode_info *fi;
 retry:
        if (unlikely(f2fs_cp_error(sbi)))
                return;
                spin_unlock(&sbi->dir_inode_lock);
                return;
        }
-       entry = list_entry(head->next, struct inode_entry, list);
-       inode = igrab(entry->inode);
+       fi = list_entry(head->next, struct f2fs_inode_info, dirty_list);
+       inode = igrab(&fi->vfs_inode);
        spin_unlock(&sbi->dir_inode_lock);
        if (inode) {
                filemap_fdatawrite(inode->i_mapping);
 
        nid_t ino;              /* inode number */
 };
 
-/*
- * for the list of directory inodes or gc inodes.
- * NOTE: there are two slab users for this structure, if we add/modify/delete
- * fields in structure for one of slab users, it may affect fields or size of
- * other one, in this condition, it's better to split both of slab and related
- * data structure.
- */
+/* for the list of inodes to be GCed */
 struct inode_entry {
        struct list_head list;  /* list head */
        struct inode *inode;    /* vfs inode pointer */
        unsigned int clevel;            /* maximum level of given file name */
        nid_t i_xattr_nid;              /* node id that contains xattrs */
        unsigned long long xattr_ver;   /* cp version of xattr modification */
-       struct inode_entry *dirty_dir;  /* the pointer of dirty dir */
 
+       struct list_head dirty_list;    /* linked in global dirty list */
        struct list_head inmem_pages;   /* inmemory pages managed by f2fs */
        struct mutex inmem_lock;        /* lock for inmemory pages */