f2fs: introduce f2fs_i_links_write with mark_inode_dirty_sync
authorJaegeuk Kim <jaegeuk@kernel.org>
Fri, 20 May 2016 16:43:20 +0000 (09:43 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 3 Jun 2016 01:05:10 +0000 (18:05 -0700)
This patch introduces f2fs_i_links_write() to call mark_inode_dirty_sync() when
changing inode->i_links.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/namei.c

index aa8cb4559ff8c51fdf59380343b09dcd114cfd56..02e0522beccfba8900636f2387d257fb7e31e5d1 100644 (file)
@@ -535,6 +535,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
        }
 
        clear_nlink(inode);
+       mark_inode_dirty_sync(inode);
 
        /* truncate all the data during iput */
        iput(inode);
index dc4beae14c926161fc0bdcfb353a77cc0aa7161c..f8ca0f31271fe08d0f2a46753168dd24fa59a8fe 100644 (file)
@@ -437,7 +437,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
                 */
                if (inode->i_nlink == 0)
                        remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino);
-               inc_nlink(inode);
+               f2fs_i_links_write(inode, true);
        }
        return page;
 
@@ -456,7 +456,7 @@ void update_parent_metadata(struct inode *dir, struct inode *inode,
 {
        if (inode && is_inode_flag_set(inode, FI_NEW_INODE)) {
                if (S_ISDIR(inode->i_mode)) {
-                       inc_nlink(dir);
+                       f2fs_i_links_write(dir, true);
                        set_inode_flag(dir, FI_UPDATE_DIR);
                }
                clear_inode_flag(inode, FI_NEW_INODE);
@@ -675,7 +675,7 @@ void f2fs_drop_nlink(struct inode *dir, struct inode *inode, struct page *page)
        down_write(&F2FS_I(inode)->i_sem);
 
        if (S_ISDIR(inode->i_mode)) {
-               drop_nlink(dir);
+               f2fs_i_links_write(dir, false);
                if (page)
                        update_inode(dir, page);
                else
@@ -683,9 +683,9 @@ void f2fs_drop_nlink(struct inode *dir, struct inode *inode, struct page *page)
        }
        inode->i_ctime = CURRENT_TIME;
 
-       drop_nlink(inode);
+       f2fs_i_links_write(inode, false);
        if (S_ISDIR(inode->i_mode)) {
-               drop_nlink(inode);
+               f2fs_i_links_write(inode, false);
                f2fs_i_size_write(inode, 0);
        }
        up_write(&F2FS_I(inode)->i_sem);
index 9536e9e17b40cdb96808b2cf317fac4d92ce8ce8..d98aaf3829a6b9cdece7b6f74e291b058781969a 100644 (file)
@@ -1557,6 +1557,15 @@ static inline void set_acl_inode(struct inode *inode, umode_t mode)
        set_inode_flag(inode, FI_ACL_MODE);
 }
 
+static inline void f2fs_i_links_write(struct inode *inode, bool inc)
+{
+       if (inc)
+               inc_nlink(inode);
+       else
+               drop_nlink(inode);
+       mark_inode_dirty_sync(inode);
+}
+
 static inline void f2fs_i_blocks_write(struct inode *inode,
                                        blkcnt_t diff, bool add)
 {
index cbf61a5f0e575a5d3ad37d02cff06a5133167af6..af7c75ab9343ce1949041f1a9eff9cf898628089 100644 (file)
@@ -349,9 +349,6 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
        f2fs_delete_entry(de, page, dir, inode);
        f2fs_unlock_op(sbi);
 
-       /* In order to evict this inode, we set it dirty */
-       mark_inode_dirty(inode);
-
        if (IS_DIRSYNC(dir))
                f2fs_sync_fs(sbi->sb, 1);
 fail:
@@ -597,16 +594,16 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
         * remove all unused data of tmpfile after abnormal power-off.
         */
        add_orphan_inode(sbi, inode->i_ino);
-       f2fs_unlock_op(sbi);
-
        alloc_nid_done(sbi, inode->i_ino);
 
        if (whiteout) {
-               inode_dec_link_count(inode);
+               f2fs_i_links_write(inode, false);
                *whiteout = inode;
        } else {
                d_tmpfile(dentry, inode);
        }
+       /* link_count was changed by d_tmpfile as well. */
+       f2fs_unlock_op(sbi);
        unlock_new_inode(inode);
        return 0;
 
@@ -704,12 +701,10 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                new_inode->i_ctime = CURRENT_TIME;
                down_write(&F2FS_I(new_inode)->i_sem);
                if (old_dir_entry)
-                       drop_nlink(new_inode);
-               drop_nlink(new_inode);
+                       f2fs_i_links_write(new_inode, false);
+               f2fs_i_links_write(new_inode, false);
                up_write(&F2FS_I(new_inode)->i_sem);
 
-               mark_inode_dirty(new_inode);
-
                if (!new_inode->i_nlink)
                        add_orphan_inode(sbi, new_inode->i_ino);
                else
@@ -729,7 +724,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                }
 
                if (old_dir_entry) {
-                       inc_nlink(new_dir);
+                       f2fs_i_links_write(new_dir, true);
                        update_inode_page(new_dir);
                }
 
@@ -784,8 +779,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        f2fs_dentry_kunmap(old_inode, old_dir_page);
                        f2fs_put_page(old_dir_page, 0);
                }
-               drop_nlink(old_dir);
-               mark_inode_dirty(old_dir);
+               f2fs_i_links_write(old_dir, false);
                update_inode_page(old_dir);
        }
 
@@ -913,10 +907,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
        old_dir->i_ctime = CURRENT_TIME;
        if (old_nlink) {
                down_write(&F2FS_I(old_dir)->i_sem);
-               if (old_nlink < 0)
-                       drop_nlink(old_dir);
-               else
-                       inc_nlink(old_dir);
+               f2fs_i_links_write(old_dir, old_nlink > 0);
                up_write(&F2FS_I(old_dir)->i_sem);
        }
        mark_inode_dirty(old_dir);
@@ -934,10 +925,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
        new_dir->i_ctime = CURRENT_TIME;
        if (new_nlink) {
                down_write(&F2FS_I(new_dir)->i_sem);
-               if (new_nlink < 0)
-                       drop_nlink(new_dir);
-               else
-                       inc_nlink(new_dir);
+               f2fs_i_links_write(new_dir, new_nlink > 0);
                up_write(&F2FS_I(new_dir)->i_sem);
        }
        mark_inode_dirty(new_dir);