Commit 7735730d authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: fix to propagate error from __get_meta_page()

If caller of __get_meta_page() can handle error, let's propagate error
from __get_meta_page().
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 18dd6470
...@@ -71,6 +71,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, ...@@ -71,6 +71,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
.encrypted_page = NULL, .encrypted_page = NULL,
.is_meta = is_meta, .is_meta = is_meta,
}; };
int err;
if (unlikely(!is_meta)) if (unlikely(!is_meta))
fio.op_flags &= ~REQ_META; fio.op_flags &= ~REQ_META;
...@@ -85,11 +86,10 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, ...@@ -85,11 +86,10 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
fio.page = page; fio.page = page;
if (f2fs_submit_page_bio(&fio)) { err = f2fs_submit_page_bio(&fio);
memset(page_address(page), 0, PAGE_SIZE); if (err) {
f2fs_stop_checkpoint(sbi, false); f2fs_put_page(page, 1);
f2fs_bug_on(sbi, 1); return ERR_PTR(err);
return page;
} }
lock_page(page); lock_page(page);
...@@ -98,14 +98,9 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, ...@@ -98,14 +98,9 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
goto repeat; goto repeat;
} }
/*
* if there is any IO error when accessing device, make our filesystem
* readonly and make sure do not write checkpoint with non-uptodate
* meta page.
*/
if (unlikely(!PageUptodate(page))) { if (unlikely(!PageUptodate(page))) {
memset(page_address(page), 0, PAGE_SIZE); f2fs_put_page(page, 1);
f2fs_stop_checkpoint(sbi, false); return ERR_PTR(-EIO);
} }
out: out:
return page; return page;
...@@ -116,6 +111,25 @@ struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) ...@@ -116,6 +111,25 @@ struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
return __get_meta_page(sbi, index, true); return __get_meta_page(sbi, index, true);
} }
struct page *f2fs_get_meta_page_nofail(struct f2fs_sb_info *sbi, pgoff_t index)
{
struct page *page;
int count = 0;
retry:
page = __get_meta_page(sbi, index, true);
if (IS_ERR(page)) {
if (PTR_ERR(page) == -EIO &&
++count <= DEFAULT_RETRY_IO_COUNT)
goto retry;
f2fs_stop_checkpoint(sbi, false);
f2fs_bug_on(sbi, 1);
}
return page;
}
/* for POR only */ /* for POR only */
struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index) struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
{ {
...@@ -607,7 +621,9 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) ...@@ -607,7 +621,9 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
/* truncate all the data during iput */ /* truncate all the data during iput */
iput(inode); iput(inode);
f2fs_get_node_info(sbi, ino, &ni); err = f2fs_get_node_info(sbi, ino, &ni);
if (err)
goto err_out;
/* ENOMEM was fully retried in f2fs_evict_inode. */ /* ENOMEM was fully retried in f2fs_evict_inode. */
if (ni.blk_addr != NULL_ADDR) { if (ni.blk_addr != NULL_ADDR) {
...@@ -655,9 +671,15 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) ...@@ -655,9 +671,15 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true); f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
for (i = 0; i < orphan_blocks; i++) { for (i = 0; i < orphan_blocks; i++) {
struct page *page = f2fs_get_meta_page(sbi, start_blk + i); struct page *page;
struct f2fs_orphan_block *orphan_blk; struct f2fs_orphan_block *orphan_blk;
page = f2fs_get_meta_page(sbi, start_blk + i);
if (IS_ERR(page)) {
err = PTR_ERR(page);
goto out;
}
orphan_blk = (struct f2fs_orphan_block *)page_address(page); orphan_blk = (struct f2fs_orphan_block *)page_address(page);
for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) { for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
nid_t ino = le32_to_cpu(orphan_blk->ino[j]); nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
...@@ -748,6 +770,9 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, ...@@ -748,6 +770,9 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr,
__u32 crc = 0; __u32 crc = 0;
*cp_page = f2fs_get_meta_page(sbi, cp_addr); *cp_page = f2fs_get_meta_page(sbi, cp_addr);
if (IS_ERR(*cp_page))
return PTR_ERR(*cp_page);
*cp_block = (struct f2fs_checkpoint *)page_address(*cp_page); *cp_block = (struct f2fs_checkpoint *)page_address(*cp_page);
crc_offset = le32_to_cpu((*cp_block)->checksum_offset); crc_offset = le32_to_cpu((*cp_block)->checksum_offset);
...@@ -873,6 +898,8 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) ...@@ -873,6 +898,8 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)
unsigned char *ckpt = (unsigned char *)sbi->ckpt; unsigned char *ckpt = (unsigned char *)sbi->ckpt;
cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i); cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i);
if (IS_ERR(cur_page))
goto free_fail_no_cp;
sit_bitmap_ptr = page_address(cur_page); sit_bitmap_ptr = page_address(cur_page);
memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
f2fs_put_page(cur_page, 1); f2fs_put_page(cur_page, 1);
......
...@@ -879,6 +879,10 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) ...@@ -879,6 +879,10 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
return -EPERM; return -EPERM;
err = f2fs_get_node_info(sbi, dn->nid, &ni);
if (err)
return err;
dn->data_blkaddr = datablock_addr(dn->inode, dn->data_blkaddr = datablock_addr(dn->inode,
dn->node_page, dn->ofs_in_node); dn->node_page, dn->ofs_in_node);
if (dn->data_blkaddr == NEW_ADDR) if (dn->data_blkaddr == NEW_ADDR)
...@@ -888,7 +892,6 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) ...@@ -888,7 +892,6 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
return err; return err;
alloc: alloc:
f2fs_get_node_info(sbi, dn->nid, &ni);
set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
f2fs_allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr, f2fs_allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
...@@ -1291,7 +1294,11 @@ static int f2fs_xattr_fiemap(struct inode *inode, ...@@ -1291,7 +1294,11 @@ static int f2fs_xattr_fiemap(struct inode *inode,
if (!page) if (!page)
return -ENOMEM; return -ENOMEM;
f2fs_get_node_info(sbi, inode->i_ino, &ni); err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
if (err) {
f2fs_put_page(page, 1);
return err;
}
phys = (__u64)blk_to_logical(inode, ni.blk_addr); phys = (__u64)blk_to_logical(inode, ni.blk_addr);
offset = offsetof(struct f2fs_inode, i_addr) + offset = offsetof(struct f2fs_inode, i_addr) +
...@@ -1318,7 +1325,11 @@ static int f2fs_xattr_fiemap(struct inode *inode, ...@@ -1318,7 +1325,11 @@ static int f2fs_xattr_fiemap(struct inode *inode,
if (!page) if (!page)
return -ENOMEM; return -ENOMEM;
f2fs_get_node_info(sbi, xnid, &ni); err = f2fs_get_node_info(sbi, xnid, &ni);
if (err) {
f2fs_put_page(page, 1);
return err;
}
phys = (__u64)blk_to_logical(inode, ni.blk_addr); phys = (__u64)blk_to_logical(inode, ni.blk_addr);
len = inode->i_sb->s_blocksize; len = inode->i_sb->s_blocksize;
...@@ -1705,6 +1716,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) ...@@ -1705,6 +1716,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct dnode_of_data dn; struct dnode_of_data dn;
struct extent_info ei = {0,0,0}; struct extent_info ei = {0,0,0};
struct node_info ni;
bool ipu_force = false; bool ipu_force = false;
int err = 0; int err = 0;
...@@ -1773,6 +1785,12 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) ...@@ -1773,6 +1785,12 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
fio->need_lock = LOCK_REQ; fio->need_lock = LOCK_REQ;
} }
err = f2fs_get_node_info(fio->sbi, dn.nid, &ni);
if (err)
goto out_writepage;
fio->version = ni.version;
err = encrypt_one_page(fio); err = encrypt_one_page(fio);
if (err) if (err)
goto out_writepage; goto out_writepage;
......
...@@ -513,6 +513,8 @@ enum { ...@@ -513,6 +513,8 @@ enum {
*/ */
}; };
#define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO count */
#define F2FS_LINK_MAX 0xffffffff /* maximum link count per file */ #define F2FS_LINK_MAX 0xffffffff /* maximum link count per file */
#define MAX_DIR_RA_PAGES 4 /* maximum ra pages of dir */ #define MAX_DIR_RA_PAGES 4 /* maximum ra pages of dir */
...@@ -1020,6 +1022,7 @@ struct f2fs_io_info { ...@@ -1020,6 +1022,7 @@ struct f2fs_io_info {
bool retry; /* need to reallocate block address */ bool retry; /* need to reallocate block address */
enum iostat_type io_type; /* io type */ enum iostat_type io_type; /* io type */
struct writeback_control *io_wbc; /* writeback control */ struct writeback_control *io_wbc; /* writeback control */
unsigned char version; /* version of the node */
}; };
#define is_read_io(rw) ((rw) == READ) #define is_read_io(rw) ((rw) == READ)
...@@ -2823,7 +2826,7 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type); ...@@ -2823,7 +2826,7 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type);
int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid); int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid); bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino); bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
struct node_info *ni); struct node_info *ni);
pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs); pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode); int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
...@@ -2850,7 +2853,7 @@ int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink); ...@@ -2850,7 +2853,7 @@ int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
void f2fs_recover_inline_xattr(struct inode *inode, struct page *page); void f2fs_recover_inline_xattr(struct inode *inode, struct page *page);
int f2fs_recover_xattr_data(struct inode *inode, struct page *page); int f2fs_recover_xattr_data(struct inode *inode, struct page *page);
int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page); int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
void f2fs_restore_node_summary(struct f2fs_sb_info *sbi, int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_summary_block *sum); unsigned int segno, struct f2fs_summary_block *sum);
void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc); void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
int f2fs_build_node_manager(struct f2fs_sb_info *sbi); int f2fs_build_node_manager(struct f2fs_sb_info *sbi);
...@@ -2928,6 +2931,7 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi, ...@@ -2928,6 +2931,7 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io); void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_meta_page_nofail(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type); block_t blkaddr, int type);
......
...@@ -1067,7 +1067,12 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, ...@@ -1067,7 +1067,12 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
if (ret) if (ret)
return ret; return ret;
f2fs_get_node_info(sbi, dn.nid, &ni); ret = f2fs_get_node_info(sbi, dn.nid, &ni);
if (ret) {
f2fs_put_dnode(&dn);
return ret;
}
ilen = min((pgoff_t) ilen = min((pgoff_t)
ADDRS_PER_PAGE(dn.node_page, dst_inode) - ADDRS_PER_PAGE(dn.node_page, dst_inode) -
dn.ofs_in_node, len - i); dn.ofs_in_node, len - i);
......
...@@ -517,7 +517,11 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, ...@@ -517,7 +517,11 @@ static void gc_node_segment(struct f2fs_sb_info *sbi,
continue; continue;
} }
f2fs_get_node_info(sbi, nid, &ni); if (f2fs_get_node_info(sbi, nid, &ni)) {
f2fs_put_page(node_page, 1);
continue;
}
if (ni.blk_addr != start_addr + off) { if (ni.blk_addr != start_addr + off) {
f2fs_put_page(node_page, 1); f2fs_put_page(node_page, 1);
continue; continue;
...@@ -576,7 +580,10 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, ...@@ -576,7 +580,10 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
if (IS_ERR(node_page)) if (IS_ERR(node_page))
return false; return false;
f2fs_get_node_info(sbi, nid, dni); if (f2fs_get_node_info(sbi, nid, dni)) {
f2fs_put_page(node_page, 1);
return false;
}
if (sum->version != dni->version) { if (sum->version != dni->version) {
f2fs_msg(sbi->sb, KERN_WARNING, f2fs_msg(sbi->sb, KERN_WARNING,
...@@ -655,7 +662,10 @@ static void move_data_block(struct inode *inode, block_t bidx, ...@@ -655,7 +662,10 @@ static void move_data_block(struct inode *inode, block_t bidx,
*/ */
f2fs_wait_on_page_writeback(page, DATA, true); f2fs_wait_on_page_writeback(page, DATA, true);
f2fs_get_node_info(fio.sbi, dn.nid, &ni); err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
if (err)
goto put_out;
set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
/* read page */ /* read page */
......
...@@ -121,6 +121,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) ...@@ -121,6 +121,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
.encrypted_page = NULL, .encrypted_page = NULL,
.io_type = FS_DATA_IO, .io_type = FS_DATA_IO,
}; };
struct node_info ni;
int dirty, err; int dirty, err;
if (!f2fs_exist_data(dn->inode)) if (!f2fs_exist_data(dn->inode))
...@@ -130,6 +131,14 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) ...@@ -130,6 +131,14 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
if (err) if (err)
return err; return err;
err = f2fs_get_node_info(fio.sbi, dn->nid, &ni);
if (err) {
f2fs_put_dnode(dn);
return err;
}
fio.version = ni.version;
if (unlikely(dn->data_blkaddr != NEW_ADDR)) { if (unlikely(dn->data_blkaddr != NEW_ADDR)) {
f2fs_put_dnode(dn); f2fs_put_dnode(dn);
set_sbi_flag(fio.sbi, SBI_NEED_FSCK); set_sbi_flag(fio.sbi, SBI_NEED_FSCK);
...@@ -690,7 +699,10 @@ int f2fs_inline_data_fiemap(struct inode *inode, ...@@ -690,7 +699,10 @@ int f2fs_inline_data_fiemap(struct inode *inode,
ilen = start + len; ilen = start + len;
ilen -= start; ilen -= start;
f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni); err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
if (err)
goto out;
byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits; byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
byteaddr += (char *)inline_data_addr(inode, ipage) - byteaddr += (char *)inline_data_addr(inode, ipage) -
(char *)F2FS_INODE(ipage); (char *)F2FS_INODE(ipage);
......
...@@ -699,6 +699,7 @@ void f2fs_handle_failed_inode(struct inode *inode) ...@@ -699,6 +699,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct node_info ni; struct node_info ni;
int err;
/* /*
* clear nlink of inode in order to release resource of inode * clear nlink of inode in order to release resource of inode
...@@ -721,10 +722,16 @@ void f2fs_handle_failed_inode(struct inode *inode) ...@@ -721,10 +722,16 @@ void f2fs_handle_failed_inode(struct inode *inode)
* so we can prevent losing this orphan when encoutering checkpoint * so we can prevent losing this orphan when encoutering checkpoint
* and following suddenly power-off. * and following suddenly power-off.
*/ */
f2fs_get_node_info(sbi, inode->i_ino, &ni); err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
if (err) {
set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_msg(sbi->sb, KERN_WARNING,
"May loss orphan inode, run fsck to fix.");
goto out;
}
if (ni.blk_addr != NULL_ADDR) { if (ni.blk_addr != NULL_ADDR) {
int err = f2fs_acquire_orphan_inode(sbi); err = f2fs_acquire_orphan_inode(sbi);
if (err) { if (err) {
set_sbi_flag(sbi, SBI_NEED_FSCK); set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_msg(sbi->sb, KERN_WARNING, f2fs_msg(sbi->sb, KERN_WARNING,
...@@ -737,6 +744,7 @@ void f2fs_handle_failed_inode(struct inode *inode) ...@@ -737,6 +744,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
set_inode_flag(inode, FI_FREE_NID); set_inode_flag(inode, FI_FREE_NID);
} }
out:
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
/* iput will drop the inode object */ /* iput will drop the inode object */
......
...@@ -113,7 +113,7 @@ static void clear_node_page_dirty(struct page *page) ...@@ -113,7 +113,7 @@ static void clear_node_page_dirty(struct page *page)
static struct page *get_current_nat_page(struct f2fs_sb_info *sbi, nid_t nid) static struct page *get_current_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
{ {
pgoff_t index = current_nat_addr(sbi, nid); pgoff_t index = current_nat_addr(sbi, nid);
return f2fs_get_meta_page(sbi, index); return f2fs_get_meta_page_nofail(sbi, index);
} }
static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid) static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
...@@ -419,7 +419,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) ...@@ -419,7 +419,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
/* /*
* This function always returns success * This function always returns success
*/ */
void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
struct node_info *ni) struct node_info *ni)
{ {
struct f2fs_nm_info *nm_i = NM_I(sbi); struct f2fs_nm_info *nm_i = NM_I(sbi);
...@@ -443,7 +443,7 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, ...@@ -443,7 +443,7 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
ni->blk_addr = nat_get_blkaddr(e); ni->blk_addr = nat_get_blkaddr(e);
ni->version = nat_get_version(e); ni->version = nat_get_version(e);
up_read(&nm_i->nat_tree_lock); up_read(&nm_i->nat_tree_lock);
return; return 0;
} }
memset(&ne, 0, sizeof(struct f2fs_nat_entry)); memset(&ne, 0, sizeof(struct f2fs_nat_entry));
...@@ -466,6 +466,9 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, ...@@ -466,6 +466,9 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
up_read(&nm_i->nat_tree_lock); up_read(&nm_i->nat_tree_lock);
page = f2fs_get_meta_page(sbi, index); page = f2fs_get_meta_page(sbi, index);
if (IS_ERR(page))
return PTR_ERR(page);
nat_blk = (struct f2fs_nat_block *)page_address(page); nat_blk = (struct f2fs_nat_block *)page_address(page);
ne = nat_blk->entries[nid - start_nid]; ne = nat_blk->entries[nid - start_nid];
node_info_from_raw_nat(ni, &ne); node_info_from_raw_nat(ni, &ne);
...@@ -473,6 +476,7 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, ...@@ -473,6 +476,7 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
cache: cache:
/* cache nat entry */ /* cache nat entry */
cache_nat_entry(sbi, nid, &ne); cache_nat_entry(sbi, nid, &ne);
return 0;
} }
/* /*
...@@ -722,12 +726,15 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) ...@@ -722,12 +726,15 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
return err; return err;
} }
static void truncate_node(struct dnode_of_data *dn) static int truncate_node(struct dnode_of_data *dn)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct node_info ni; struct node_info ni;
int err;
f2fs_get_node_info(sbi, dn->nid, &ni); err = f2fs_get_node_info(sbi, dn->nid, &ni);
if (err)
return err;
/* Deallocate node address */ /* Deallocate node address */
f2fs_invalidate_blocks(sbi, ni.blk_addr); f2fs_invalidate_blocks(sbi, ni.blk_addr);
...@@ -750,11 +757,14 @@ static void truncate_node(struct dnode_of_data *dn) ...@@ -750,11 +757,14 @@ static void truncate_node(struct dnode_of_data *dn)
dn->node_page = NULL; dn->node_page = NULL;
trace_f2fs_truncate_node(dn->inode, dn->nid, ni.blk_addr); trace_f2fs_truncate_node(dn->inode, dn->nid, ni.blk_addr);
return 0;
} }
static int truncate_dnode(struct dnode_of_data *dn) static int truncate_dnode(struct dnode_of_data *dn)
{ {
struct page *page; struct page *page;
int err;
if (dn->nid == 0) if (dn->nid == 0)
return 1; return 1;
...@@ -770,7 +780,10 @@ static int truncate_dnode(struct dnode_of_data *dn) ...@@ -770,7 +780,10 @@ static int truncate_dnode(struct dnode_of_data *dn)
dn->node_page = page; dn->node_page = page;
dn->ofs_in_node = 0; dn->ofs_in_node = 0;
f2fs_truncate_data_blocks(dn); f2fs_truncate_data_blocks(dn);
truncate_node(dn); err = truncate_node(dn);
if (err)
return err;
return 1; return 1;
} }
...@@ -835,7 +848,9 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, ...@@ -835,7 +848,9 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs,
if (!ofs) { if (!ofs) {
/* remove current indirect node */ /* remove current indirect node */
dn->node_page = page; dn->node_page = page;
truncate_node(dn); ret = truncate_node(dn);
if (ret)
goto out_err;
freed++; freed++;
} else { } else {
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
...@@ -893,7 +908,9 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, ...@@ -893,7 +908,9 @@ static int truncate_partial_nodes(struct dnode_of_data *dn,
if (offset[idx + 1] == 0) { if (offset[idx + 1] == 0) {
dn->node_page = pages[idx]; dn->node_page = pages[idx];
dn->nid = nid[idx]; dn->nid = nid[idx];
truncate_node(dn); err = truncate_node(dn);
if (err)
goto fail;
} else { } else {
f2fs_put_page(pages[idx], 1); f2fs_put_page(pages[idx], 1);
} }
...@@ -1014,6 +1031,7 @@ int f2fs_truncate_xattr_node(struct inode *inode) ...@@ -1014,6 +1031,7 @@ int f2fs_truncate_xattr_node(struct inode *inode)
nid_t nid = F2FS_I(inode)->i_xattr_nid; nid_t nid = F2FS_I(inode)->i_xattr_nid;
struct dnode_of_data dn; struct dnode_of_data dn;
struct page *npage; struct page *npage;
int err;
if (!nid) if (!nid)
return 0; return 0;
...@@ -1022,10 +1040,15 @@ int f2fs_truncate_xattr_node(struct inode *inode) ...@@ -1022,10 +1040,15 @@ int f2fs_truncate_xattr_node(struct inode *inode)
if (IS_ERR(npage)) if (IS_ERR(npage))
return PTR_ERR(npage); return PTR_ERR(npage);
set_new_dnode(&dn, inode, NULL, npage, nid);
err = truncate_node(&dn);
if (err) {
f2fs_put_page(npage, 1);
return err;
}
f2fs_i_xnid_write(inode, 0); f2fs_i_xnid_write(inode, 0);
set_new_dnode(&dn, inode, NULL, npage, nid);
truncate_node(&dn);
return 0; return 0;
} }
...@@ -1059,7 +1082,11 @@ int f2fs_remove_inode_page(struct inode *inode) ...@@ -1059,7 +1082,11 @@ int f2fs_remove_inode_page(struct inode *inode)
inode->i_blocks != 0 && inode->i_blocks != 8); inode->i_blocks != 0 && inode->i_blocks != 8);
/* will put inode & node pages */ /* will put inode & node pages */
truncate_node(&dn); err = truncate_node(&dn);
if (err) {
f2fs_put_dnode(&dn);
return err;
}
return 0; return 0;
} }
...@@ -1092,7 +1119,11 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs) ...@@ -1092,7 +1119,11 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
goto fail; goto fail;
#ifdef CONFIG_F2FS_CHECK_FS #ifdef CONFIG_F2FS_CHECK_FS
f2fs_get_node_info(sbi, dn->nid, &new_ni); err = f2fs_get_node_info(sbi, dn->nid, &new_ni);
if (err) {
dec_valid_node_count(sbi, dn->inode, !ofs);
goto fail;
}
f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR); f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR);
#endif #endif
new_ni.nid = dn->nid; new_ni.nid = dn->nid;
...@@ -1140,6 +1171,7 @@ static int read_node_page(struct page *page, int op_flags) ...@@ -1140,6 +1171,7 @@ static int read_node_page(struct page *page, int op_flags)
.page = page, .page = page,
.encrypted_page = NULL, .encrypted_page = NULL,
}; };
int err;
if (PageUptodate(page)) { if (PageUptodate(page)) {
#ifdef CONFIG_F2FS_CHECK_FS #ifdef CONFIG_F2FS_CHECK_FS
...@@ -1148,7 +1180,9 @@ static int read_node_page(struct page *page, int op_flags) ...@@ -1148,7 +1180,9 @@ static int read_node_page(struct page *page, int op_flags)
return LOCKED_PAGE; return LOCKED_PAGE;
} }
f2fs_get_node_info(sbi, page->index, &ni); err = f2fs_get_node_info(sbi, page->index, &ni);
if (err)
return err;
if (unlikely(ni.blk_addr == NULL_ADDR) || if (unlikely(ni.blk_addr == NULL_ADDR) ||
is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) { is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) {
...@@ -1383,6 +1417,9 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, ...@@ -1383,6 +1417,9 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
nid = nid_of_node(page); nid = nid_of_node(page);
f2fs_bug_on(sbi, page->index != nid); f2fs_bug_on(sbi, page->index != nid);
if (f2fs_get_node_info(sbi, nid, &ni))
goto redirty_out;
if (wbc->for_reclaim) { if (wbc->for_reclaim) {
if (!down_read_trylock(&sbi->node_write)) if (!down_read_trylock(&sbi->node_write))
goto redirty_out; goto redirty_out;
...@@ -1390,8 +1427,6 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, ...@@ -1390,8 +1427,6 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
down_read(&sbi->node_write); down_read(&sbi->node_write);
} }
f2fs_get_node_info(sbi, nid, &ni);
/* This page is already truncated */ /* This page is already truncated */
if (unlikely(ni.blk_addr == NULL_ADDR)) { if (unlikely(ni.blk_addr == NULL_ADDR)) {
ClearPageUptodate(page); ClearPageUptodate(page);
...@@ -2311,12 +2346,16 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page) ...@@ -2311,12 +2346,16 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
struct dnode_of_data dn; struct dnode_of_data dn;
struct node_info ni; struct node_info ni;
struct page *xpage; struct page *xpage;
int err;
if (!prev_xnid) if (!prev_xnid)
goto recover_xnid; goto recover_xnid;
/* 1: invalidate the previous xattr nid */ /* 1: invalidate the previous xattr nid */
f2fs_get_node_info(sbi, prev_xnid, &ni); err = f2fs_get_node_info(sbi, prev_xnid, &ni);
if (err)
return err;
f2fs_invalidate_blocks(sbi, ni.blk_addr); f2fs_invalidate_blocks(sbi, ni.blk_addr);
dec_valid_node_count(sbi, inode, false); dec_valid_node_count(sbi, inode, false);
set_node_addr(sbi, &ni, NULL_ADDR, false); set_node_addr(sbi, &ni, NULL_ADDR, false);
...@@ -2351,8 +2390,11 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) ...@@ -2351,8 +2390,11 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
nid_t ino = ino_of_node(page); nid_t ino = ino_of_node(page);
struct node_info old_ni, new_ni; struct node_info old_ni, new_ni;
struct page *ipage; struct page *ipage;
int err;
f2fs_get_node_info(sbi, ino, &old_ni); err = f2fs_get_node_info(sbi, ino, &old_ni);
if (err)
return err;
if (unlikely(old_ni.blk_addr != NULL_ADDR)) if (unlikely(old_ni.blk_addr != NULL_ADDR))
return -EINVAL; return -EINVAL;
...@@ -2406,7 +2448,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) ...@@ -2406,7 +2448,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
return 0; return 0;
} }
void f2fs_restore_node_summary(struct f2fs_sb_info *sbi, int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_summary_block *sum) unsigned int segno, struct f2fs_summary_block *sum)
{ {
struct f2fs_node *rn; struct f2fs_node *rn;
...@@ -2428,6 +2470,9 @@ void f2fs_restore_node_summary(struct f2fs_sb_info *sbi, ...@@ -2428,6 +2470,9 @@ void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
for (idx = addr; idx < addr + nrpages; idx++) { for (idx = addr; idx < addr + nrpages; idx++) {
struct page *page = f2fs_get_tmp_page(sbi, idx); struct page *page = f2fs_get_tmp_page(sbi, idx);
if (IS_ERR(page))
return PTR_ERR(page);
rn = F2FS_NODE(page); rn = F2FS_NODE(page);
sum_entry->nid = rn->footer.nid; sum_entry->nid = rn->footer.nid;
sum_entry->version = 0; sum_entry->version = 0;
...@@ -2439,6 +2484,7 @@ void f2fs_restore_node_summary(struct f2fs_sb_info *sbi, ...@@ -2439,6 +2484,7 @@ void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
invalidate_mapping_pages(META_MAPPING(sbi), addr, invalidate_mapping_pages(META_MAPPING(sbi), addr,
addr + nrpages); addr + nrpages);
} }
return 0;
} }
static void remove_nats_in_journal(struct f2fs_sb_info *sbi) static void remove_nats_in_journal(struct f2fs_sb_info *sbi)
...@@ -2675,7 +2721,13 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi) ...@@ -2675,7 +2721,13 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi)
nat_bits_addr = __start_cp_addr(sbi) + sbi->blocks_per_seg - nat_bits_addr = __start_cp_addr(sbi) + sbi->blocks_per_seg -
nm_i->nat_bits_blocks; nm_i->nat_bits_blocks;
for (i = 0; i < nm_i->nat_bits_blocks; i++) { for (i = 0; i < nm_i->nat_bits_blocks; i++) {
struct page *page = f2fs_get_meta_page(sbi, nat_bits_addr++); struct page *page;
page = f2fs_get_meta_page(sbi, nat_bits_addr++);
if (IS_ERR(page)) {
disable_nat_bits(sbi, true);
return PTR_ERR(page);
}
memcpy(nm_i->nat_bits + (i << F2FS_BLKSIZE_BITS), memcpy(nm_i->nat_bits + (i << F2FS_BLKSIZE_BITS),
page_address(page), F2FS_BLKSIZE); page_address(page), F2FS_BLKSIZE);
......
...@@ -256,6 +256,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, ...@@ -256,6 +256,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
return 0; return 0;
page = f2fs_get_tmp_page(sbi, blkaddr); page = f2fs_get_tmp_page(sbi, blkaddr);
if (IS_ERR(page)) {
err = PTR_ERR(page);
break;
}
if (!is_recoverable_dnode(page)) if (!is_recoverable_dnode(page))
break; break;
...@@ -471,7 +475,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, ...@@ -471,7 +475,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
f2fs_wait_on_page_writeback(dn.node_page, NODE, true); f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
f2fs_get_node_info(sbi, dn.nid, &ni); err = f2fs_get_node_info(sbi, dn.nid, &ni);
if (err)
goto err;
f2fs_bug_on(sbi, ni.ino != ino_of_node(page)); f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page)); f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page));
...@@ -574,6 +581,10 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list, ...@@ -574,6 +581,10 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
f2fs_ra_meta_pages_cond(sbi, blkaddr); f2fs_ra_meta_pages_cond(sbi, blkaddr);
page = f2fs_get_tmp_page(sbi, blkaddr); page = f2fs_get_tmp_page(sbi, blkaddr);
if (IS_ERR(page)) {
err = PTR_ERR(page);
break;
}
if (!is_recoverable_dnode(page)) { if (!is_recoverable_dnode(page)) {
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
......
...@@ -250,7 +250,13 @@ static int __revoke_inmem_pages(struct inode *inode, ...@@ -250,7 +250,13 @@ static int __revoke_inmem_pages(struct inode *inode,
err = -EAGAIN; err = -EAGAIN;
goto next; goto next;
} }
f2fs_get_node_info(sbi, dn.nid, &ni);
err = f2fs_get_node_info(sbi, dn.nid, &ni);
if (err) {
f2fs_put_dnode(&dn);
return err;
}
if (cur->old_addr == NEW_ADDR) { if (cur->old_addr == NEW_ADDR) {
f2fs_invalidate_blocks(sbi, dn.data_blkaddr); f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
f2fs_update_data_blkaddr(&dn, NEW_ADDR); f2fs_update_data_blkaddr(&dn, NEW_ADDR);
...@@ -2051,7 +2057,7 @@ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra) ...@@ -2051,7 +2057,7 @@ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
*/ */
struct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno) struct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
{ {
return f2fs_get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno)); return f2fs_get_meta_page_nofail(sbi, GET_SUM_BLOCK(sbi, segno));
} }
void f2fs_update_meta_page(struct f2fs_sb_info *sbi, void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
...@@ -2911,11 +2917,9 @@ void f2fs_outplace_write_data(struct dnode_of_data *dn, ...@@ -2911,11 +2917,9 @@ void f2fs_outplace_write_data(struct dnode_of_data *dn,
{ {
struct f2fs_sb_info *sbi = fio->sbi; struct f2fs_sb_info *sbi = fio->sbi;
struct f2fs_summary sum; struct f2fs_summary sum;
struct node_info ni;
f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR); f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR);
f2fs_get_node_info(sbi, dn->nid, &ni); set_summary(&sum, dn->nid, dn->ofs_in_node, fio->version);
set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
do_write_page(&sum, fio); do_write_page(&sum, fio);
f2fs_update_data_blkaddr(dn, fio->new_blkaddr); f2fs_update_data_blkaddr(dn, fio->new_blkaddr);
...@@ -3077,7 +3081,7 @@ void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr) ...@@ -3077,7 +3081,7 @@ void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
} }
} }
static void read_compacted_summaries(struct f2fs_sb_info *sbi) static int read_compacted_summaries(struct f2fs_sb_info *sbi)
{ {
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct curseg_info *seg_i; struct curseg_info *seg_i;
...@@ -3089,6 +3093,8 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi) ...@@ -3089,6 +3093,8 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
start = start_sum_block(sbi); start = start_sum_block(sbi);
page = f2fs_get_meta_page(sbi, start++); page = f2fs_get_meta_page(sbi, start++);
if (IS_ERR(page))
return PTR_ERR(page);
kaddr = (unsigned char *)page_address(page); kaddr = (unsigned char *)page_address(page);
/* Step 1: restore nat cache */ /* Step 1: restore nat cache */
...@@ -3129,11 +3135,14 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi) ...@@ -3129,11 +3135,14 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
page = NULL; page = NULL;
page = f2fs_get_meta_page(sbi, start++); page = f2fs_get_meta_page(sbi, start++);
if (IS_ERR(page))
return PTR_ERR(page);
kaddr = (unsigned char *)page_address(page); kaddr = (unsigned char *)page_address(page);
offset = 0; offset = 0;
} }
} }
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
return 0;
} }
static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
...@@ -3145,6 +3154,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -3145,6 +3154,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
unsigned short blk_off; unsigned short blk_off;
unsigned int segno = 0; unsigned int segno = 0;
block_t blk_addr = 0; block_t blk_addr = 0;
int err = 0;
/* get segment number and block addr */ /* get segment number and block addr */
if (IS_DATASEG(type)) { if (IS_DATASEG(type)) {
...@@ -3168,6 +3178,8 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -3168,6 +3178,8 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
} }
new = f2fs_get_meta_page(sbi, blk_addr); new = f2fs_get_meta_page(sbi, blk_addr);
if (IS_ERR(new))
return PTR_ERR(new);
sum = (struct f2fs_summary_block *)page_address(new); sum = (struct f2fs_summary_block *)page_address(new);
if (IS_NODESEG(type)) { if (IS_NODESEG(type)) {
...@@ -3179,7 +3191,9 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -3179,7 +3191,9 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
ns->ofs_in_node = 0; ns->ofs_in_node = 0;
} }
} else { } else {
f2fs_restore_node_summary(sbi, segno, sum); err = f2fs_restore_node_summary(sbi, segno, sum);
if (err)
goto out;
} }
} }
...@@ -3199,8 +3213,9 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -3199,8 +3213,9 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
curseg->alloc_type = ckpt->alloc_type[type]; curseg->alloc_type = ckpt->alloc_type[type];
curseg->next_blkoff = blk_off; curseg->next_blkoff = blk_off;
mutex_unlock(&curseg->curseg_mutex); mutex_unlock(&curseg->curseg_mutex);
out:
f2fs_put_page(new, 1); f2fs_put_page(new, 1);
return 0; return err;
} }
static int restore_curseg_summaries(struct f2fs_sb_info *sbi) static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
...@@ -3218,7 +3233,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) ...@@ -3218,7 +3233,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
META_CP, true); META_CP, true);
/* restore for compacted data summary */ /* restore for compacted data summary */
read_compacted_summaries(sbi); err = read_compacted_summaries(sbi);
if (err)
return err;
type = CURSEG_HOT_NODE; type = CURSEG_HOT_NODE;
} }
...@@ -3349,7 +3366,7 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type, ...@@ -3349,7 +3366,7 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
static struct page *get_current_sit_page(struct f2fs_sb_info *sbi, static struct page *get_current_sit_page(struct f2fs_sb_info *sbi,
unsigned int segno) unsigned int segno)
{ {
return f2fs_get_meta_page(sbi, current_sit_addr(sbi, segno)); return f2fs_get_meta_page_nofail(sbi, current_sit_addr(sbi, segno));
} }
static struct page *get_next_sit_page(struct f2fs_sb_info *sbi, static struct page *get_next_sit_page(struct f2fs_sb_info *sbi,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment