aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-05-21 19:20:01 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-05-28 02:03:04 -0400
commit39cf72cf09c8f36a383919e7675bdb15bd4db53b (patch)
treec0cfa3c97591790f03224959453a36aa44235e63 /fs/f2fs
parentb292dcab068e141d8a820b77cbcc88d98c610eb4 (diff)
f2fs: fix to handle do_recover_data errors
This patch adds error handling codes of check_index_in_prev_nodes and its caller, do_recover_data. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/recovery.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index eceb6652532d..dcd8e860aad3 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -188,7 +188,7 @@ static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi,
188 } 188 }
189} 189}
190 190
191static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi, 191static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
192 block_t blkaddr, struct dnode_of_data *dn) 192 block_t blkaddr, struct dnode_of_data *dn)
193{ 193{
194 struct seg_entry *sentry; 194 struct seg_entry *sentry;
@@ -205,7 +205,7 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
205 205
206 sentry = get_seg_entry(sbi, segno); 206 sentry = get_seg_entry(sbi, segno);
207 if (!f2fs_test_bit(blkoff, sentry->cur_valid_map)) 207 if (!f2fs_test_bit(blkoff, sentry->cur_valid_map))
208 return; 208 return 0;
209 209
210 /* Get the previous summary */ 210 /* Get the previous summary */
211 for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) { 211 for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) {
@@ -232,16 +232,18 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
232 tdn.node_page = dn->inode_page; 232 tdn.node_page = dn->inode_page;
233 tdn.ofs_in_node = sum.ofs_in_node; 233 tdn.ofs_in_node = sum.ofs_in_node;
234 truncate_data_blocks_range(&tdn, 1); 234 truncate_data_blocks_range(&tdn, 1);
235 return; 235 return 0;
236 } else if (dn->nid == nid) { 236 } else if (dn->nid == nid) {
237 struct dnode_of_data tdn = *dn; 237 struct dnode_of_data tdn = *dn;
238 tdn.ofs_in_node = sum.ofs_in_node; 238 tdn.ofs_in_node = sum.ofs_in_node;
239 truncate_data_blocks_range(&tdn, 1); 239 truncate_data_blocks_range(&tdn, 1);
240 return; 240 return 0;
241 } 241 }
242 242
243 /* Get the node page */ 243 /* Get the node page */
244 node_page = get_node_page(sbi, nid); 244 node_page = get_node_page(sbi, nid);
245 if (IS_ERR(node_page))
246 return PTR_ERR(node_page);
245 bidx = start_bidx_of_node(ofs_of_node(node_page)) + 247 bidx = start_bidx_of_node(ofs_of_node(node_page)) +
246 le16_to_cpu(sum.ofs_in_node); 248 le16_to_cpu(sum.ofs_in_node);
247 ino = ino_of_node(node_page); 249 ino = ino_of_node(node_page);
@@ -250,10 +252,11 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
250 /* Deallocate previous index in the node page */ 252 /* Deallocate previous index in the node page */
251 inode = f2fs_iget(sbi->sb, ino); 253 inode = f2fs_iget(sbi->sb, ino);
252 if (IS_ERR(inode)) 254 if (IS_ERR(inode))
253 return; 255 return PTR_ERR(inode);
254 256
255 truncate_hole(inode, bidx, bidx + 1); 257 truncate_hole(inode, bidx, bidx + 1);
256 iput(inode); 258 iput(inode);
259 return 0;
257} 260}
258 261
259static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, 262static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
@@ -301,7 +304,9 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
301 } 304 }
302 305
303 /* Check the previous node page having this index */ 306 /* Check the previous node page having this index */
304 check_index_in_prev_nodes(sbi, dest, &dn); 307 err = check_index_in_prev_nodes(sbi, dest, &dn);
308 if (err)
309 goto err;
305 310
306 set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); 311 set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
307 312
@@ -324,13 +329,14 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
324 set_page_dirty(dn.node_page); 329 set_page_dirty(dn.node_page);
325 330
326 recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr); 331 recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr);
332err:
327 f2fs_put_dnode(&dn); 333 f2fs_put_dnode(&dn);
328 mutex_unlock_op(sbi, ilock); 334 mutex_unlock_op(sbi, ilock);
329 335
330 f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, " 336 f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, "
331 "recovered_data = %d blocks", 337 "recovered_data = %d blocks, err = %d",
332 inode->i_ino, recovered); 338 inode->i_ino, recovered, err);
333 return 0; 339 return err;
334} 340}
335 341
336static int recover_data(struct f2fs_sb_info *sbi, 342static int recover_data(struct f2fs_sb_info *sbi,