aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-01-23 19:42:16 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-02-17 00:58:51 -0500
commit744602cf45ce35758b8637f76bc263c871abc6ea (patch)
treead269d5514188d9ca87b7906bae3c863a8b46d3b /fs/f2fs
parent6d0abeca3242a88cab8232e4acd7e2bf088f3bc2 (diff)
f2fs: update_inode_page should be done all the time
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.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/data.c3
-rw-r--r--fs/f2fs/f2fs.h8
-rw-r--r--fs/f2fs/inode.c23
3 files changed, 22 insertions, 12 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 2261ccdd0b5f..20c3c648e56d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -55,8 +55,7 @@ static void f2fs_write_end_io(struct bio *bio, int err)
55 if (unlikely(err)) { 55 if (unlikely(err)) {
56 SetPageError(page); 56 SetPageError(page);
57 set_bit(AS_EIO, &page->mapping->flags); 57 set_bit(AS_EIO, &page->mapping->flags);
58 set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); 58 f2fs_stop_checkpoint(sbi);
59 sbi->sb->s_flags |= MS_RDONLY;
60 } 59 }
61 end_page_writeback(page); 60 end_page_writeback(page);
62 dec_page_count(sbi, F2FS_WRITEBACK); 61 dec_page_count(sbi, F2FS_WRITEBACK);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index fc3c558cb4f3..0f0ad3aa148a 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1023,6 +1023,12 @@ static inline int f2fs_readonly(struct super_block *sb)
1023 return sb->s_flags & MS_RDONLY; 1023 return sb->s_flags & MS_RDONLY;
1024} 1024}
1025 1025
1026static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi)
1027{
1028 set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
1029 sbi->sb->s_flags |= MS_RDONLY;
1030}
1031
1026#define get_inode_mode(i) \ 1032#define get_inode_mode(i) \
1027 ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \ 1033 ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
1028 (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) 1034 (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
@@ -1048,7 +1054,7 @@ void f2fs_set_inode_flags(struct inode *);
1048struct inode *f2fs_iget(struct super_block *, unsigned long); 1054struct inode *f2fs_iget(struct super_block *, unsigned long);
1049int try_to_free_nats(struct f2fs_sb_info *, int); 1055int try_to_free_nats(struct f2fs_sb_info *, int);
1050void update_inode(struct inode *, struct page *); 1056void update_inode(struct inode *, struct page *);
1051int update_inode_page(struct inode *); 1057void update_inode_page(struct inode *);
1052int f2fs_write_inode(struct inode *, struct writeback_control *); 1058int f2fs_write_inode(struct inode *, struct writeback_control *);
1053void f2fs_evict_inode(struct inode *); 1059void f2fs_evict_inode(struct inode *);
1054 1060
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 4d67ed736dca..08d69c94ab8b 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -212,24 +212,29 @@ void update_inode(struct inode *inode, struct page *node_page)
212 clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE); 212 clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE);
213} 213}
214 214
215int update_inode_page(struct inode *inode) 215void update_inode_page(struct inode *inode)
216{ 216{
217 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 217 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
218 struct page *node_page; 218 struct page *node_page;
219 219retry:
220 node_page = get_node_page(sbi, inode->i_ino); 220 node_page = get_node_page(sbi, inode->i_ino);
221 if (IS_ERR(node_page)) 221 if (IS_ERR(node_page)) {
222 return PTR_ERR(node_page); 222 int err = PTR_ERR(node_page);
223 223 if (err == -ENOMEM) {
224 cond_resched();
225 goto retry;
226 } else if (err != -ENOENT) {
227 f2fs_stop_checkpoint(sbi);
228 }
229 return;
230 }
224 update_inode(inode, node_page); 231 update_inode(inode, node_page);
225 f2fs_put_page(node_page, 1); 232 f2fs_put_page(node_page, 1);
226 return 0;
227} 233}
228 234
229int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) 235int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
230{ 236{
231 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 237 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
232 int ret;
233 238
234 if (inode->i_ino == F2FS_NODE_INO(sbi) || 239 if (inode->i_ino == F2FS_NODE_INO(sbi) ||
235 inode->i_ino == F2FS_META_INO(sbi)) 240 inode->i_ino == F2FS_META_INO(sbi))
@@ -243,13 +248,13 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
243 * during the urgent cleaning time when runing out of free sections. 248 * during the urgent cleaning time when runing out of free sections.
244 */ 249 */
245 f2fs_lock_op(sbi); 250 f2fs_lock_op(sbi);
246 ret = update_inode_page(inode); 251 update_inode_page(inode);
247 f2fs_unlock_op(sbi); 252 f2fs_unlock_op(sbi);
248 253
249 if (wbc) 254 if (wbc)
250 f2fs_balance_fs(sbi); 255 f2fs_balance_fs(sbi);
251 256
252 return ret; 257 return 0;
253} 258}
254 259
255/* 260/*