Merge tag 'for-f2fs-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[cascardo/linux.git] / fs / f2fs / inline.c
index c15e53c..ccea873 100644 (file)
@@ -59,7 +59,8 @@ void read_inline_data(struct page *page, struct page *ipage)
        memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
        flush_dcache_page(page);
        kunmap_atomic(dst_addr);
-       SetPageUptodate(page);
+       if (!PageUptodate(page))
+               SetPageUptodate(page);
 }
 
 bool truncate_inline_inode(struct page *ipage, u64 from)
@@ -73,7 +74,7 @@ bool truncate_inline_inode(struct page *ipage, u64 from)
 
        f2fs_wait_on_page_writeback(ipage, NODE, true);
        memset(addr + from, 0, MAX_INLINE_DATA - from);
-
+       set_page_dirty(ipage);
        return true;
 }
 
@@ -97,7 +98,8 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
        else
                read_inline_data(page, ipage);
 
-       SetPageUptodate(page);
+       if (!PageUptodate(page))
+               SetPageUptodate(page);
        f2fs_put_page(ipage, 1);
        unlock_page(page);
        return 0;
@@ -139,7 +141,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
                inode_dec_dirty_pages(dn->inode);
 
        /* this converted inline_data should be recovered. */
-       set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE);
+       set_inode_flag(dn->inode, FI_APPEND_WRITE);
 
        /* clear inline data and flag after data writeback */
        truncate_inline_inode(dn->inode_page, 0);
@@ -147,7 +149,6 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
 clear_out:
        stat_dec_inline_inode(dn->inode);
        f2fs_clear_inline_inode(dn->inode);
-       sync_inode_page(dn);
        f2fs_put_dnode(dn);
        return 0;
 }
@@ -213,11 +214,11 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
        dst_addr = inline_data_addr(dn.inode_page);
        memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
        kunmap_atomic(src_addr);
+       set_page_dirty(dn.inode_page);
 
-       set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE);
-       set_inode_flag(F2FS_I(inode), FI_DATA_EXIST);
+       set_inode_flag(inode, FI_APPEND_WRITE);
+       set_inode_flag(inode, FI_DATA_EXIST);
 
-       sync_inode_page(&dn);
        clear_inline_node(dn.inode_page);
        f2fs_put_dnode(&dn);
        return 0;
@@ -253,10 +254,10 @@ process_inline:
                dst_addr = inline_data_addr(ipage);
                memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
 
-               set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
-               set_inode_flag(F2FS_I(inode), FI_DATA_EXIST);
+               set_inode_flag(inode, FI_INLINE_DATA);
+               set_inode_flag(inode, FI_DATA_EXIST);
 
-               update_inode(inode, ipage);
+               set_page_dirty(ipage);
                f2fs_put_page(ipage, 1);
                return true;
        }
@@ -267,7 +268,6 @@ process_inline:
                if (!truncate_inline_inode(ipage, 0))
                        return false;
                f2fs_clear_inline_inode(inode);
-               update_inode(inode, ipage);
                f2fs_put_page(ipage, 1);
        } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
                if (truncate_blocks(inode, 0, false))
@@ -289,8 +289,10 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
        f2fs_hash_t namehash;
 
        ipage = get_node_page(sbi, dir->i_ino);
-       if (IS_ERR(ipage))
+       if (IS_ERR(ipage)) {
+               *res_page = ipage;
                return NULL;
+       }
 
        namehash = f2fs_dentry_hash(&name);
 
@@ -307,25 +309,6 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
        return de;
 }
 
-struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *dir,
-                                                       struct page **p)
-{
-       struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
-       struct page *ipage;
-       struct f2fs_dir_entry *de;
-       struct f2fs_inline_dentry *dentry_blk;
-
-       ipage = get_node_page(sbi, dir->i_ino);
-       if (IS_ERR(ipage))
-               return NULL;
-
-       dentry_blk = inline_data_addr(ipage);
-       de = &dentry_blk->dentry[1];
-       *p = ipage;
-       unlock_page(ipage);
-       return de;
-}
-
 int make_empty_inline_dir(struct inode *inode, struct inode *parent,
                                                        struct page *ipage)
 {
@@ -340,10 +323,8 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent,
        set_page_dirty(ipage);
 
        /* update i_size to MAX_INLINE_DATA */
-       if (i_size_read(inode) < MAX_INLINE_DATA) {
-               i_size_write(inode, MAX_INLINE_DATA);
-               set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR);
-       }
+       if (i_size_read(inode) < MAX_INLINE_DATA)
+               f2fs_i_size_write(inode, MAX_INLINE_DATA);
        return 0;
 }
 
@@ -392,22 +373,19 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
                                        NR_INLINE_DENTRY * F2FS_SLOT_LEN);
 
        kunmap_atomic(dentry_blk);
-       SetPageUptodate(page);
+       if (!PageUptodate(page))
+               SetPageUptodate(page);
        set_page_dirty(page);
 
        /* clear inline dir and flag after data writeback */
        truncate_inline_inode(ipage, 0);
 
        stat_dec_inline_dir(dir);
-       clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY);
+       clear_inode_flag(dir, FI_INLINE_DENTRY);
 
-       F2FS_I(dir)->i_current_depth = 1;
-       if (i_size_read(dir) < PAGE_SIZE) {
-               i_size_write(dir, PAGE_SIZE);
-               set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
-       }
-
-       sync_inode_page(&dn);
+       f2fs_i_depth_write(dir, 1);
+       if (i_size_read(dir) < PAGE_SIZE)
+               f2fs_i_size_write(dir, PAGE_SIZE);
 out:
        f2fs_put_page(page, 1);
        return err;
@@ -465,7 +443,6 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,
                                struct f2fs_inline_dentry *inline_dentry)
 {
        struct f2fs_inline_dentry *backup_dentry;
-       struct f2fs_inode_info *fi = F2FS_I(dir);
        int err;
 
        backup_dentry = f2fs_kmalloc(sizeof(struct f2fs_inline_dentry),
@@ -487,16 +464,15 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,
        lock_page(ipage);
 
        stat_dec_inline_dir(dir);
-       clear_inode_flag(fi, FI_INLINE_DENTRY);
-       update_inode(dir, ipage);
+       clear_inode_flag(dir, FI_INLINE_DENTRY);
        kfree(backup_dentry);
        return 0;
 recover:
        lock_page(ipage);
        memcpy(inline_dentry, backup_dentry, MAX_INLINE_DATA);
-       fi->i_current_depth = 0;
-       i_size_write(dir, MAX_INLINE_DATA);
-       update_inode(dir, ipage);
+       f2fs_i_depth_write(dir, 0);
+       f2fs_i_size_write(dir, MAX_INLINE_DATA);
+       set_page_dirty(ipage);
        f2fs_put_page(ipage, 1);
 
        kfree(backup_dentry);
@@ -560,8 +536,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name,
 
        /* we don't need to mark_inode_dirty now */
        if (inode) {
-               F2FS_I(inode)->i_pino = dir->i_ino;
-               update_inode(inode, page);
+               f2fs_i_pino_write(inode, dir->i_ino);
                f2fs_put_page(page, 1);
        }
 
@@ -569,11 +544,6 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name,
 fail:
        if (inode)
                up_write(&F2FS_I(inode)->i_sem);
-
-       if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) {
-               update_inode(dir, ipage);
-               clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
-       }
 out:
        f2fs_put_page(ipage, 1);
        return err;
@@ -597,13 +567,13 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page,
                                &inline_dentry->dentry_bitmap);
 
        set_page_dirty(page);
+       f2fs_put_page(page, 1);
 
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       f2fs_mark_inode_dirty_sync(dir);
 
        if (inode)
-               f2fs_drop_nlink(dir, inode, page);
-
-       f2fs_put_page(page, 1);
+               f2fs_drop_nlink(dir, inode);
 }
 
 bool f2fs_empty_inline_dir(struct inode *dir)