In order to make fs consistency, update_inode_page should not be failed all
the time. Otherwise, it is possible to lose some metadata in the inode like
a link count.

Signed-off-by: Jaegeuk Kim <jaegeuk....@samsung.com>
---
 fs/f2fs/data.c  |  3 +--
 fs/f2fs/f2fs.h  |  8 +++++++-
 fs/f2fs/inode.c | 20 ++++++++++++--------
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 0ae5587..6827359 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -62,8 +62,7 @@ static void f2fs_write_end_io(struct bio *bio, int err)
                if (unlikely(!uptodate)) {
                        SetPageError(page);
                        set_bit(AS_EIO, &page->mapping->flags);
-                       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
-                       sbi->sb->s_flags |= MS_RDONLY;
+                       f2fs_stop_checkpoint(sbi);
                }
                end_page_writeback(page);
                dec_page_count(sbi, F2FS_WRITEBACK);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index af51a0b..42903c3 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1023,6 +1023,12 @@ static inline int f2fs_readonly(struct super_block *sb)
        return sb->s_flags & MS_RDONLY;
 }
 
+static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi)
+{
+       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
+       sbi->sb->s_flags |= MS_RDONLY;
+}
+
 /*
  * file.c
  */
@@ -1044,7 +1050,7 @@ void f2fs_set_inode_flags(struct inode *);
 struct inode *f2fs_iget(struct super_block *, unsigned long);
 int try_to_free_nats(struct f2fs_sb_info *, int);
 void update_inode(struct inode *, struct page *);
-int update_inode_page(struct inode *);
+void update_inode_page(struct inode *);
 int f2fs_write_inode(struct inode *, struct writeback_control *);
 void f2fs_evict_inode(struct inode *);
 
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 4d67ed7..1a4ba27 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -212,24 +212,28 @@ void update_inode(struct inode *inode, struct page 
*node_page)
        clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE);
 }
 
-int update_inode_page(struct inode *inode)
+void update_inode_page(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct page *node_page;
-
+retry:
        node_page = get_node_page(sbi, inode->i_ino);
-       if (IS_ERR(node_page))
-               return PTR_ERR(node_page);
+       if (IS_ERR(node_page)) {
+               if (PTR_ERR(node_page) == -ENOMEM) {
+                       cond_resched();
+                       goto retry;
+               } else {
+                       f2fs_stop_checkpoint(sbi);
+               }
+       }
 
        update_inode(inode, node_page);
        f2fs_put_page(node_page, 1);
-       return 0;
 }
 
 int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       int ret;
 
        if (inode->i_ino == F2FS_NODE_INO(sbi) ||
                        inode->i_ino == F2FS_META_INO(sbi))
@@ -243,13 +247,13 @@ int f2fs_write_inode(struct inode *inode, struct 
writeback_control *wbc)
         * during the urgent cleaning time when runing out of free sections.
         */
        f2fs_lock_op(sbi);
-       ret = update_inode_page(inode);
+       update_inode_page(inode);
        f2fs_unlock_op(sbi);
 
        if (wbc)
                f2fs_balance_fs(sbi);
 
-       return ret;
+       return 0;
 }
 
 /*
-- 
1.8.4.474.g128a96c


------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to