Loading fs/f2fs/data.c +3 −0 Original line number Diff line number Diff line Loading @@ -1204,6 +1204,7 @@ static int f2fs_write_data_page(struct page *page, loff_t i_size = i_size_read(inode); const pgoff_t end_index = ((unsigned long long) i_size) >> PAGE_SHIFT; loff_t psize = (page->index + 1) << PAGE_SHIFT; unsigned offset = 0; bool need_balance_fs = false; int err = 0; Loading Loading @@ -1265,6 +1266,8 @@ static int f2fs_write_data_page(struct page *page, err = f2fs_write_inline_data(inode, page); if (err == -EAGAIN) err = do_write_data_page(&fio); if (F2FS_I(inode)->last_disk_size < psize) F2FS_I(inode)->last_disk_size = psize; f2fs_unlock_op(sbi); done: if (err && err != -ENOENT) Loading fs/f2fs/f2fs.h +21 −2 Original line number Diff line number Diff line Loading @@ -441,6 +441,7 @@ struct f2fs_inode_info { 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 */ loff_t last_disk_size; /* lastly written file size */ struct list_head dirty_list; /* dirty list for dirs and files */ struct list_head gdirty_list; /* linked in global dirty list */ Loading Loading @@ -1516,6 +1517,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) enum { FI_NEW_INODE, /* indicate newly allocated inode */ FI_DIRTY_INODE, /* indicate inode is dirty or not */ FI_AUTO_RECOVER, /* indicate inode is recoverable */ FI_DIRTY_DIR, /* indicate directory has dirty pages */ FI_INC_LINK, /* need to increment i_nlink */ FI_ACL_MODE, /* indicate acl mode */ Loading Loading @@ -1591,18 +1593,35 @@ static inline void f2fs_i_links_write(struct inode *inode, bool inc) static inline void f2fs_i_blocks_write(struct inode *inode, blkcnt_t diff, bool add) { bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); inode->i_blocks = add ? inode->i_blocks + diff : inode->i_blocks - diff; mark_inode_dirty_sync(inode); if (clean || recover) set_inode_flag(inode, FI_AUTO_RECOVER); } static inline void f2fs_i_size_write(struct inode *inode, loff_t i_size) { bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); if (i_size_read(inode) == i_size) return; i_size_write(inode, i_size); mark_inode_dirty_sync(inode); if (clean || recover) set_inode_flag(inode, FI_AUTO_RECOVER); } static inline bool f2fs_skip_inode_update(struct inode *inode) { if (!is_inode_flag_set(inode, FI_AUTO_RECOVER)) return false; return F2FS_I(inode)->last_disk_size == i_size_read(inode); } static inline void f2fs_i_depth_write(struct inode *inode, unsigned int depth) Loading Loading @@ -1936,8 +1955,8 @@ void ra_node_page(struct f2fs_sb_info *, nid_t); struct page *get_node_page(struct f2fs_sb_info *, pgoff_t); struct page *get_node_page_ra(struct page *, int); void move_node_page(struct page *, int); int fsync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *, bool); int fsync_node_pages(struct f2fs_sb_info *, struct inode *, struct writeback_control *, bool); int sync_node_pages(struct f2fs_sb_info *, struct writeback_control *); bool alloc_nid(struct f2fs_sb_info *, nid_t *); void alloc_nid_done(struct f2fs_sb_info *, nid_t); Loading fs/f2fs/file.c +2 −2 Original line number Diff line number Diff line Loading @@ -208,7 +208,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, } /* if the inode is dirty, let's recover all the time */ if (!datasync) { if (!datasync && !f2fs_skip_inode_update(inode)) { f2fs_write_inode(inode, NULL); goto go_write; } Loading Loading @@ -251,7 +251,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, goto out; } sync_nodes: ret = fsync_node_pages(sbi, ino, &wbc, atomic); ret = fsync_node_pages(sbi, inode, &wbc, atomic); if (ret) goto out; Loading fs/f2fs/inode.c +3 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,9 @@ static int do_read_inode(struct inode *inode) if (__written_first_block(ri)) set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); if (!need_inode_block_update(sbi, inode->i_ino)) fi->last_disk_size = inode->i_size; f2fs_put_page(node_page, 1); stat_inc_inline_xattr(inode); Loading fs/f2fs/node.c +7 −2 Original line number Diff line number Diff line Loading @@ -1293,7 +1293,7 @@ static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino) return last_page; } int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, struct writeback_control *wbc, bool atomic) { pgoff_t index, end; Loading @@ -1301,6 +1301,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, int ret = 0; struct page *last_page = NULL; bool marked = false; nid_t ino = inode->i_ino; if (atomic) { last_page = last_fsync_dnode(sbi, ino); Loading Loading @@ -1354,9 +1355,13 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, if (!atomic || page == last_page) { set_fsync_mark(page, 1); if (IS_INODE(page)) if (IS_INODE(page)) { if (is_inode_flag_set(inode, FI_DIRTY_INODE)) update_inode(inode, page); set_dentry_mark(page, need_dentry_mark(sbi, ino)); } /* may be written by other thread */ if (!PageDirty(page)) set_page_dirty(page); Loading Loading
fs/f2fs/data.c +3 −0 Original line number Diff line number Diff line Loading @@ -1204,6 +1204,7 @@ static int f2fs_write_data_page(struct page *page, loff_t i_size = i_size_read(inode); const pgoff_t end_index = ((unsigned long long) i_size) >> PAGE_SHIFT; loff_t psize = (page->index + 1) << PAGE_SHIFT; unsigned offset = 0; bool need_balance_fs = false; int err = 0; Loading Loading @@ -1265,6 +1266,8 @@ static int f2fs_write_data_page(struct page *page, err = f2fs_write_inline_data(inode, page); if (err == -EAGAIN) err = do_write_data_page(&fio); if (F2FS_I(inode)->last_disk_size < psize) F2FS_I(inode)->last_disk_size = psize; f2fs_unlock_op(sbi); done: if (err && err != -ENOENT) Loading
fs/f2fs/f2fs.h +21 −2 Original line number Diff line number Diff line Loading @@ -441,6 +441,7 @@ struct f2fs_inode_info { 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 */ loff_t last_disk_size; /* lastly written file size */ struct list_head dirty_list; /* dirty list for dirs and files */ struct list_head gdirty_list; /* linked in global dirty list */ Loading Loading @@ -1516,6 +1517,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) enum { FI_NEW_INODE, /* indicate newly allocated inode */ FI_DIRTY_INODE, /* indicate inode is dirty or not */ FI_AUTO_RECOVER, /* indicate inode is recoverable */ FI_DIRTY_DIR, /* indicate directory has dirty pages */ FI_INC_LINK, /* need to increment i_nlink */ FI_ACL_MODE, /* indicate acl mode */ Loading Loading @@ -1591,18 +1593,35 @@ static inline void f2fs_i_links_write(struct inode *inode, bool inc) static inline void f2fs_i_blocks_write(struct inode *inode, blkcnt_t diff, bool add) { bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); inode->i_blocks = add ? inode->i_blocks + diff : inode->i_blocks - diff; mark_inode_dirty_sync(inode); if (clean || recover) set_inode_flag(inode, FI_AUTO_RECOVER); } static inline void f2fs_i_size_write(struct inode *inode, loff_t i_size) { bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); if (i_size_read(inode) == i_size) return; i_size_write(inode, i_size); mark_inode_dirty_sync(inode); if (clean || recover) set_inode_flag(inode, FI_AUTO_RECOVER); } static inline bool f2fs_skip_inode_update(struct inode *inode) { if (!is_inode_flag_set(inode, FI_AUTO_RECOVER)) return false; return F2FS_I(inode)->last_disk_size == i_size_read(inode); } static inline void f2fs_i_depth_write(struct inode *inode, unsigned int depth) Loading Loading @@ -1936,8 +1955,8 @@ void ra_node_page(struct f2fs_sb_info *, nid_t); struct page *get_node_page(struct f2fs_sb_info *, pgoff_t); struct page *get_node_page_ra(struct page *, int); void move_node_page(struct page *, int); int fsync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *, bool); int fsync_node_pages(struct f2fs_sb_info *, struct inode *, struct writeback_control *, bool); int sync_node_pages(struct f2fs_sb_info *, struct writeback_control *); bool alloc_nid(struct f2fs_sb_info *, nid_t *); void alloc_nid_done(struct f2fs_sb_info *, nid_t); Loading
fs/f2fs/file.c +2 −2 Original line number Diff line number Diff line Loading @@ -208,7 +208,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, } /* if the inode is dirty, let's recover all the time */ if (!datasync) { if (!datasync && !f2fs_skip_inode_update(inode)) { f2fs_write_inode(inode, NULL); goto go_write; } Loading Loading @@ -251,7 +251,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, goto out; } sync_nodes: ret = fsync_node_pages(sbi, ino, &wbc, atomic); ret = fsync_node_pages(sbi, inode, &wbc, atomic); if (ret) goto out; Loading
fs/f2fs/inode.c +3 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,9 @@ static int do_read_inode(struct inode *inode) if (__written_first_block(ri)) set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); if (!need_inode_block_update(sbi, inode->i_ino)) fi->last_disk_size = inode->i_size; f2fs_put_page(node_page, 1); stat_inc_inline_xattr(inode); Loading
fs/f2fs/node.c +7 −2 Original line number Diff line number Diff line Loading @@ -1293,7 +1293,7 @@ static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino) return last_page; } int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, struct writeback_control *wbc, bool atomic) { pgoff_t index, end; Loading @@ -1301,6 +1301,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, int ret = 0; struct page *last_page = NULL; bool marked = false; nid_t ino = inode->i_ino; if (atomic) { last_page = last_fsync_dnode(sbi, ino); Loading Loading @@ -1354,9 +1355,13 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, if (!atomic || page == last_page) { set_fsync_mark(page, 1); if (IS_INODE(page)) if (IS_INODE(page)) { if (is_inode_flag_set(inode, FI_DIRTY_INODE)) update_inode(inode, page); set_dentry_mark(page, need_dentry_mark(sbi, ino)); } /* may be written by other thread */ if (!PageDirty(page)) set_page_dirty(page); Loading