f2fs: introduce f2fs_set_page_dirty_nobuffer
Subsystems (2)
Jaegeuk Kim
maintainerPATCH 1/6 f2fs: introduce f2fs_set_page_dirty_nobuffer
This patch adds f2fs_set_page_dirty_nobuffer() copied from __set_page_dirty_buffer. When appending 4KB blocks in f2fs on pmem with multiple cores, this improves the overall performance.
--- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/data.c | 33 ++++++++++++++++++++++++++++++++- fs/f2fs/f2fs.h | 1 + fs/f2fs/node.c | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-)
fs/f2fs/checkpoint.c +1 -1
@@ -366,7 +366,7 @@ static int f2fs_set_meta_page_dirty(struct page *page)SetPageUptodate (page);if (!PageDirty (page)) { -__set_page_dirty_nobuffers (page); +f2fs_set_page_dirty_nobuffers (page);inc_page_count (F2FS_P_SB (page),F2FS_DIRTY_META );SetPagePrivate (page);f2fs_trace_pid (page);
fs/f2fs/data.c +32 -1
@@ -19,6 +19,8 @@#include <linux/bio.h> #include <linux/prefetch.h> #include <linux/uio.h> +#include <linux/mm.h> +#include <linux/memcontrol.h> #include <linux/cleancache.h> #include "f2fs.h"
@@ -1775,6 +1777,35 @@ int f2fs_release_page(struct page *page, gfp_t wait)return 1 ; } +/* +* This was copied from __set_page_dirty_buffers which gives higher performance +* in very high speed storages. (e.g., pmem) +*/ +void f2fs_set_page_dirty_nobuffers (struct page *page) +{ +struct address_space *mapping = page->mapping; +unsigned long flags; + +if (unlikely (!mapping)) +return ; + +spin_lock (&mapping->private_lock); +lock_page_memcg (page); +SetPageDirty (page); +spin_unlock (&mapping->private_lock); + +spin_lock_irqsave (&mapping->tree_lock, flags); +WARN_ON_ONCE (!PageUptodate (page)); +account_page_dirtied (page, mapping); +radix_tree_tag_set (&mapping->page_tree, +page_index (page),PAGECACHE_TAG_DIRTY ); +spin_unlock_irqrestore (&mapping->tree_lock, flags); +unlock_page_memcg (page); + +__mark_inode_dirty (mapping->host,I_DIRTY_PAGES ); +return ; +} +static int f2fs_set_data_page_dirty (struct page *page) {struct address_space *mapping = page->mapping;
@@ -1797,7 +1828,7 @@ static int f2fs_set_data_page_dirty(struct page *page) }if (!PageDirty (page)) { -__set_page_dirty_nobuffers (page); +f2fs_set_page_dirty_nobuffers (page);update_dirty_page (inode, page);return 1 ; }
fs/f2fs/f2fs.h +1 -0
@@ -2097,6 +2097,7 @@ struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);int do_write_data_page (struct f2fs_io_info *);int f2fs_map_blocks (struct inode *,struct f2fs_map_blocks *,int ,int );int f2fs_fiemap (struct inode *inode,struct fiemap_extent_info *,u64 ,u64 ); +void f2fs_set_page_dirty_nobuffers (struct page *);void f2fs_invalidate_page (struct page *,unsigned int ,unsigned int );int f2fs_release_page (struct page *,gfp_t );
fs/f2fs/node.c +1 -1
@@ -1646,7 +1646,7 @@ static int f2fs_set_node_page_dirty(struct page *page)SetPageUptodate (page);if (!PageDirty (page)) { -__set_page_dirty_nobuffers (page); +f2fs_set_page_dirty_nobuffers (page);inc_page_count (F2FS_P_SB (page),F2FS_DIRTY_NODES );SetPagePrivate (page);f2fs_trace_pid (page);
Signature · 1 line
2.8.3
Jaegeuk Kim
maintainerPATCH 2/6 f2fs: call SetPageUptodate if needed
SetPageUptodate() issues memory barrier, resulting in performance degrdation. Let's avoid that.
--- fs/f2fs/checkpoint.c | 6 ++++-- fs/f2fs/data.c | 18 ++++++++++++------ fs/f2fs/file.c | 3 ++- fs/f2fs/inline.c | 9 ++++++--- fs/f2fs/node.c | 9 ++++++--- 5 files changed, 30 insertions(+), 15 deletions(-)
fs/f2fs/checkpoint.c +4 -2
@@ -48,7 +48,8 @@ repeat: goto repeat; }f2fs_wait_on_page_writeback (page,META , true); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);return page; }
@@ -364,7 +365,8 @@ static int f2fs_set_meta_page_dirty(struct page *page) {trace_f2fs_set_page_dirty (page,META ); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);if (!PageDirty (page)) {f2fs_set_page_dirty_nobuffers (page);inc_page_count (F2FS_P_SB (page),F2FS_DIRTY_META );
fs/f2fs/data.c +12 -6
@@ -47,7 +47,8 @@ static void f2fs_read_end_io(struct bio *bio)struct page *page = bvec->bv_page;if (!bio->bi_error) { -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page); }else {ClearPageUptodate (page);SetPageError (page);
@@ -443,7 +444,8 @@ got_it:*/ if (dn.data_blkaddr ==NEW_ADDR ) {zero_user_segment (page,0 ,PAGE_SIZE ); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);unlock_page (page);return page; }
@@ -554,7 +556,8 @@ struct page *get_new_data_page(struct inode *inode,if (dn.data_blkaddr ==NEW_ADDR ) {zero_user_segment (page,0 ,PAGE_SIZE ); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page); }else {f2fs_put_page (page,1 );
@@ -1065,7 +1068,8 @@ got_it: } }else {zero_user_segment (page,0 ,PAGE_SIZE ); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);unlock_page (page); goto next_page; }
@@ -1659,7 +1663,8 @@ repeat: } } out_update: -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page); out_clear:clear_cold_data (page);return 0 ;
@@ -1813,7 +1818,8 @@ static int f2fs_set_data_page_dirty(struct page *page)trace_f2fs_set_page_dirty (page,DATA ); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);if (f2fs_is_atomic_file (inode)) {if (!IS_ATOMIC_WRITTEN_PAGE (page)) {
fs/f2fs/file.c +2 -1
@@ -83,7 +83,8 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,zero_user_segment (page, offset,PAGE_SIZE ); }set_page_dirty (page); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);trace_f2fs_vm_page_mkwrite (page,DATA ); mapped:
fs/f2fs/inline.c +6 -3
@@ -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)
@@ -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 ;
@@ -370,7 +372,8 @@ 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 */
fs/f2fs/node.c +6 -3
@@ -1045,7 +1045,8 @@ struct page *new_node_page(struct dnode_of_data *dn,f2fs_wait_on_page_writeback (page,NODE , true);fill_node_footer (page, dn->nid, dn->inode->i_ino, ofs, true);set_cold_node (dn->inode, page); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);if (set_page_dirty (page)) dn->node_changed = true;
@@ -1644,7 +1645,8 @@ static int f2fs_set_node_page_dirty(struct page *page) {trace_f2fs_set_page_dirty (page,NODE ); -SetPageUptodate (page); +if (!PageUptodate (page)) +SetPageUptodate (page);if (!PageDirty (page)) {f2fs_set_page_dirty_nobuffers (page);inc_page_count (F2FS_P_SB (page),F2FS_DIRTY_NODES );
@@ -2015,7 +2017,8 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)/* Should not use this inode from free nid list */ remove_free_nid (NM_I (sbi), ino); -SetPageUptodate (ipage); +if (!PageUptodate (ipage)) +SetPageUptodate (ipage);fill_node_footer (ipage, ino, ino,0 , true); src =F2FS_INODE (page);
Signature · 1 line
2.8.3
Jaegeuk Kim
maintainerPATCH 3/6 f2fs: shrink critical region in spin_lock
In reply to Jaegeuk KimThis patch shrinks the critical region in spin_lock.
--- fs/f2fs/f2fs.h | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-)
fs/f2fs/f2fs.h +8 -15
@@ -1156,30 +1156,23 @@ static inline void f2fs_i_blocks_write(struct inode *, blkcnt_t, bool);static inline bool inc_valid_block_count (struct f2fs_sb_info *sbi,struct inode *inode,blkcnt_t *count) { -block_t valid_block_count; - -spin_lock (&sbi->stat_lock);#ifdef CONFIG_F2FS_FAULT_INJECTION -if (time_to_inject (FAULT_BLOCK )) { -spin_unlock (&sbi->stat_lock); +if (time_to_inject (FAULT_BLOCK ))return false; - }#endif - valid_block_count = - sbi->total_valid_block_count + (block_t)(*count); -if (unlikely (valid_block_count > sbi->user_block_count)) { - *count = sbi->user_block_count - sbi->total_valid_block_count; +spin_lock (&sbi->stat_lock); + sbi->total_valid_block_count += (block_t)(*count); +if (unlikely (sbi->total_valid_block_count > sbi->user_block_count)) { + *count -= sbi->total_valid_block_count - sbi->user_block_count; + sbi->total_valid_block_count = sbi->user_block_count;if (!*count) {spin_unlock (&sbi->stat_lock);return false; } } -/* *count can be recalculated */ -f2fs_i_blocks_write (inode, *count, true); - sbi->total_valid_block_count = - sbi->total_valid_block_count + (block_t)(*count);spin_unlock (&sbi->stat_lock); +f2fs_i_blocks_write (inode, *count, true);percpu_counter_add (&sbi->alloc_valid_block_count, (*count));return true; }
@@ -1191,9 +1184,9 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,spin_lock (&sbi->stat_lock);f2fs_bug_on (sbi, sbi->total_valid_block_count < (block_t ) count);f2fs_bug_on (sbi, inode->i_blocks < count); -f2fs_i_blocks_write (inode, count, false); sbi->total_valid_block_count -= (block_t )count;spin_unlock (&sbi->stat_lock); +f2fs_i_blocks_write (inode, count, false); }static inline void inc_page_count (struct f2fs_sb_info *sbi,int count_type)
Signature · 1 line
2.8.3
Jaegeuk Kim
maintainerPATCH 4/6 f2fs: skip to check the block address of node page
In reply to Jaegeuk KimIf the node page is up-to-date, it should be alive.
--- fs/f2fs/node.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/f2fs/node.c +3 -3
@@ -1080,6 +1080,9 @@ static int read_node_page(struct page *page, int rw) .encrypted_page = NULL, }; +if (PageUptodate (page)) +return LOCKED_PAGE ; +get_node_info (sbi, page->index, &ni);if (unlikely (ni.blk_addr ==NULL_ADDR )) {
@@ -1087,9 +1090,6 @@ static int read_node_page(struct page *page, int rw)return -ENOENT ; } -if (PageUptodate (page)) -return LOCKED_PAGE ; - fio.new_blkaddr = fio.old_blkaddr = ni.blk_addr;return f2fs_submit_page_bio (&fio); }
Signature · 9 lines
2.8.3 ------------------------------------------------------------------------------ Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San Francisco, CA to explore cutting-edge tech and listen to tech luminaries present their vision of the future. This family event has something for everyone, including kids. Get more information and register today. http://sdm.link/attshape
Jaegeuk Kim
maintainerPATCH 5/6 f2fs: use percpu_rw_semaphore
In reply to Jaegeuk KimThis patch replaces rw_semaphore with percpu_rw_semaphore for:sbi->cp_rwsemnm_i->nat_tree_lock
--- fs/f2fs/f2fs.h | 12 ++++++------ fs/f2fs/node.c | 47 ++++++++++++++++++++++++----------------------- fs/f2fs/super.c | 6 +++++- 3 files changed, 35 insertions(+), 30 deletions(-)
fs/f2fs/f2fs.h +6 -6
@@ -547,7 +547,7 @@ struct f2fs_nm_info {/* NAT cache management */ struct radix_tree_root nat_root;/* root of the nat entry cache */ struct radix_tree_root nat_set_root;/* root of the nat set cache */ -struct rw_semaphore nat_tree_lock;/* protect nat_tree_lock */ +struct percpu_rw_semaphore nat_tree_lock;/* protect nat_tree_lock */ struct list_head nat_entries;/* cached nat entry list (clean) */ unsigned int nat_cnt;/* the # of cached nat entries */ unsigned int dirty_nat_cnt;/* total num of nat entries in set */
@@ -795,7 +795,7 @@ struct f2fs_sb_info {struct f2fs_checkpoint *ckpt;/* raw checkpoint pointer */ struct inode *meta_inode;/* cache meta blocks */ struct mutex cp_mutex;/* checkpoint procedure lock */ -struct rw_semaphore cp_rwsem;/* blocking FS operations */ +struct percpu_rw_semaphore cp_rwsem;/* blocking FS operations */ struct rw_semaphore node_write;/* locking node writes */ wait_queue_head_t cp_wait;unsigned long last_time[MAX_TIME ];/* to store time in jiffies */
@@ -1082,22 +1082,22 @@ static inline void clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)static inline void f2fs_lock_op (struct f2fs_sb_info *sbi) { -down_read (&sbi->cp_rwsem); +percpu_down_read (&sbi->cp_rwsem); }static inline void f2fs_unlock_op (struct f2fs_sb_info *sbi) { -up_read (&sbi->cp_rwsem); +percpu_up_read (&sbi->cp_rwsem); }static inline void f2fs_lock_all (struct f2fs_sb_info *sbi) { -down_write (&sbi->cp_rwsem); +percpu_down_write (&sbi->cp_rwsem); }static inline void f2fs_unlock_all (struct f2fs_sb_info *sbi) { -up_write (&sbi->cp_rwsem); +percpu_up_write (&sbi->cp_rwsem); }static inline int __get_cp_reason (struct f2fs_sb_info *sbi)
fs/f2fs/node.c +24 -23
165 lines not on this page · raw message
fs/f2fs/super.c +5 -1
@@ -695,6 +695,8 @@ static void destroy_percpu_info(struct f2fs_sb_info *sbi)percpu_counter_destroy (&sbi->nr_pages[i]);percpu_counter_destroy (&sbi->alloc_valid_block_count);percpu_counter_destroy (&sbi->total_valid_inode_count); + +percpu_free_rwsem (&sbi->cp_rwsem); }static void f2fs_put_super (struct super_block *sb)
@@ -1471,6 +1473,9 @@ static int init_percpu_info(struct f2fs_sb_info *sbi) {int i, err; +if (percpu_init_rwsem (&sbi->cp_rwsem)) +return -ENOMEM ; +for (i =0 ; i <NR_COUNT_TYPE ; i++) { err =percpu_counter_init (&sbi->nr_pages[i],0 ,GFP_KERNEL );if (err)
@@ -1671,7 +1676,6 @@ try_onemore: sbi->write_io[i].bio =NULL ; } -init_rwsem (&sbi->cp_rwsem);init_waitqueue_head (&sbi->cp_wait);init_sb_info (sbi);
Signature · 1 line
2.8.3
Jaegeuk Kim
maintainerPATCH 6/6 f2fs: avoid mark_inode_dirty and update_inode
In reply to Jaegeuk KimLet's check inode's dirtiness before calling mark_inode_dirty and update_inode.
--- fs/f2fs/acl.c | 2 +- fs/f2fs/dir.c | 6 +++--- fs/f2fs/extent_cache.c | 2 +- fs/f2fs/f2fs.h | 25 +++++++++++++------------ fs/f2fs/file.c | 8 ++++---- fs/f2fs/inline.c | 2 +- fs/f2fs/inode.c | 10 +++++++++- fs/f2fs/namei.c | 6 +++--- fs/f2fs/super.c | 6 ++++-- fs/f2fs/xattr.c | 4 ++-- 10 files changed, 41 insertions(+), 30 deletions(-)
fs/f2fs/acl.c +1 -1
@@ -384,7 +384,7 @@ int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage,if (error)return error; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);if (default_acl) { error = __f2fs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl,
fs/f2fs/dir.c +3 -3
@@ -300,7 +300,7 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,set_page_dirty (page); dir->i_mtime = dir->i_ctime =CURRENT_TIME ; -mark_inode_dirty_sync (dir); +f2fs_mark_inode_dirty_sync (dir);f2fs_put_page (page,1 ); }
@@ -452,7 +452,7 @@ void update_parent_metadata(struct inode *dir, struct inode *inode,clear_inode_flag (inode,FI_NEW_INODE ); } dir->i_mtime = dir->i_ctime =CURRENT_TIME ; -mark_inode_dirty_sync (dir); +f2fs_mark_inode_dirty_sync (dir);if (F2FS_I (dir)->i_current_depth != current_depth)f2fs_i_depth_write (dir, current_depth);
@@ -704,7 +704,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,set_page_dirty (page); dir->i_ctime = dir->i_mtime =CURRENT_TIME ; -mark_inode_dirty_sync (dir); +f2fs_mark_inode_dirty_sync (dir);if (inode)f2fs_drop_nlink (dir, inode);
fs/f2fs/extent_cache.c +1 -1
@@ -172,7 +172,7 @@ static void __drop_largest_extent(struct inode *inode,if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs) { largest->len =0 ; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); } }
fs/f2fs/f2fs.h +13 -12
@@ -526,12 +526,13 @@ static inline bool __is_front_mergeable(struct extent_info *cur,return __is_extent_mergeable (cur, front); } +extern void f2fs_mark_inode_dirty_sync (struct inode *);static inline void __try_update_largest_extent (struct inode *inode,struct extent_tree *et,struct extent_node *en) {if (en->ei.len > et->largest.len) { et->largest = en->ei; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); } }
@@ -1571,7 +1572,7 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,return ;case FI_DATA_EXIST :case FI_INLINE_DOTS : -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); } }
@@ -1598,7 +1599,7 @@ static inline void set_acl_inode(struct inode *inode, umode_t mode) {F2FS_I (inode)->i_acl_mode = mode;set_inode_flag (inode,FI_ACL_MODE ); -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); }static inline void f2fs_i_links_write (struct inode *inode,bool inc)
@@ -1607,7 +1608,7 @@ static inline void f2fs_i_links_write(struct inode *inode, bool inc)inc_nlink (inode); elsedrop_nlink (inode ); -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); } static inline void f2fs_i_blocks_write(struct inode *inode,
@@ -1618,7 +1619,7 @@ static inline void f2fs_i_blocks_write(struct inode *inode, inode->i_blocks = add ? inode->i_blocks + diff : inode->i_blocks - diff; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);if (clean || recover)set_inode_flag (inode,FI_AUTO_RECOVER ); }
@@ -1632,7 +1633,7 @@ static inline void f2fs_i_size_write(struct inode *inode, loff_t i_size)return ;i_size_write (inode, i_size); -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);if (clean || recover)set_inode_flag (inode,FI_AUTO_RECOVER ); }
@@ -1647,19 +1648,19 @@ static inline bool f2fs_skip_inode_update(struct inode *inode)static inline void f2fs_i_depth_write (struct inode *inode,unsigned int depth) {F2FS_I (inode)->i_current_depth = depth; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); }static inline void f2fs_i_xnid_write (struct inode *inode,nid_t xnid) {F2FS_I (inode)->i_xattr_nid = xnid; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); }static inline void f2fs_i_pino_write (struct inode *inode,nid_t pino) {F2FS_I (inode)->i_pino = pino; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); }static inline void get_inline_info (struct inode *inode,struct f2fs_inode *ri)
@@ -1787,13 +1788,13 @@ static inline int is_file(struct inode *inode, int type)static inline void set_file (struct inode *inode,int type) {F2FS_I (inode)->i_advise |= type; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); }static inline void clear_file (struct inode *inode,int type) {F2FS_I (inode)->i_advise &= ~type; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); }static inline int f2fs_readonly (struct super_block *sb)
@@ -1940,7 +1941,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode)/* * super.c */ -void f2fs_inode_synced (struct inode *); +int f2fs_inode_synced (struct inode *);int f2fs_commit_super (struct f2fs_sb_info *,bool );int f2fs_sync_fs (struct super_block *,int ); extern __printf(3, 4)
fs/f2fs/file.c +4 -4
@@ -265,7 +265,7 @@ sync_nodes: }if (need_inode_block_update (sbi, ino)) { -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);f2fs_write_inode (inode,NULL ); goto sync_nodes; }
@@ -670,7 +670,7 @@ int f2fs_truncate(struct inode *inode)return err; inode->i_mtime = inode->i_ctime =CURRENT_TIME ; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);return 0 ; }
@@ -760,7 +760,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) } } -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);return err; }
@@ -1315,7 +1315,7 @@ static long f2fs_fallocate(struct file *file, int mode,if (!ret) { inode->i_mtime = inode->i_ctime =CURRENT_TIME ; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);f2fs_update_time (F2FS_I_SB (inode),REQ_TIME ); }
fs/f2fs/inline.c +1 -1
@@ -569,7 +569,7 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page,f2fs_put_page (page,1 ); dir->i_ctime = dir->i_mtime =CURRENT_TIME ; -mark_inode_dirty_sync (dir); +f2fs_mark_inode_dirty_sync (dir);if (inode)f2fs_drop_nlink (dir, inode);
fs/f2fs/inode.c +9 -1
@@ -18,6 +18,13 @@#include <trace/events/f2fs.h> +void f2fs_mark_inode_dirty_sync (struct inode *inode) +{ +if (is_inode_flag_set (inode,FI_DIRTY_INODE )) +return ; +mark_inode_dirty_sync (inode); +} +void f2fs_set_inode_flags (struct inode *inode) {unsigned int flags =F2FS_I (inode)->i_flags;
@@ -231,7 +238,8 @@ int update_inode(struct inode *inode, struct page *node_page) {struct f2fs_inode *ri; -f2fs_inode_synced (inode); +if (f2fs_inode_synced (inode)) +return 0 ;f2fs_wait_on_page_writeback (node_page,NODE , true);
fs/f2fs/namei.c +3 -3
@@ -757,7 +757,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,up_write (&F2FS_I (old_inode)->i_sem); old_inode->i_ctime =CURRENT_TIME ; -mark_inode_dirty_sync (old_inode); +f2fs_mark_inode_dirty_sync (old_inode);f2fs_delete_entry (old_entry, old_page, old_dir,NULL );
@@ -909,7 +909,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,f2fs_i_links_write (old_dir, old_nlink >0 );up_write (&F2FS_I (old_dir)->i_sem); } -mark_inode_dirty_sync (old_dir); +f2fs_mark_inode_dirty_sync (old_dir);/* update directory entry info of new dir inode */ f2fs_set_link (new_dir, new_entry, new_page, old_inode);
@@ -924,7 +924,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,f2fs_i_links_write (new_dir, new_nlink >0 );up_write (&F2FS_I (new_dir)->i_sem); } -mark_inode_dirty_sync (new_dir); +f2fs_mark_inode_dirty_sync (new_dir);f2fs_unlock_op (sbi);
fs/f2fs/super.c +4 -2
@@ -658,14 +658,14 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)spin_unlock (&sbi->inode_lock[DIRTY_META ]); } -void f2fs_inode_synced (struct inode *inode) +int f2fs_inode_synced (struct inode *inode) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode);spin_lock (&sbi->inode_lock[DIRTY_META ]);if (!is_inode_flag_set (inode,FI_DIRTY_INODE )) {spin_unlock (&sbi->inode_lock[DIRTY_META ]); -return ; +return 1 ; }list_del_init (&F2FS_I (inode)->gdirty_list);clear_inode_flag (inode,FI_DIRTY_INODE );
@@ -673,6 +673,8 @@ void f2fs_inode_synced(struct inode *inode)dec_page_count (sbi,F2FS_DIRTY_IMETA );stat_dec_dirty_inode (F2FS_I_SB (inode),DIRTY_META );spin_unlock (&sbi->inode_lock[DIRTY_META ]); + +return 0 ; }static void f2fs_i_callback (struct rcu_head *head)
fs/f2fs/xattr.c +2 -2
@@ -106,7 +106,7 @@ static int f2fs_xattr_advise_set(const struct xattr_handler *handler,return -EINVAL ;F2FS_I (inode)->i_advise |= *(char *)value; -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode);return 0 ; }
@@ -555,7 +555,7 @@ static int __f2fs_setxattr(struct inode *inode, int index,else file_clear_key (inode); } -mark_inode_dirty_sync (inode); +f2fs_mark_inode_dirty_sync (inode); exit:kzfree (base_addr);return error;
Signature · 1 line
2.8.3