f2fs: introduce f2fs_replace_block() for reuse
Introduce a generic function replace_block base on recover_data_page, and export it. So with it we can operate file's meta data which is in CP/SSA area when we invoke fallocate with FALLOC_FL_COLLAPSE_RANGE flag. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
d5b692b786
commit
19f106bc03
|
@ -1638,8 +1638,8 @@ void write_meta_page(struct f2fs_sb_info *, struct page *);
|
|||
void write_node_page(unsigned int, struct f2fs_io_info *);
|
||||
void write_data_page(struct dnode_of_data *, struct f2fs_io_info *);
|
||||
void rewrite_data_page(struct f2fs_io_info *);
|
||||
void recover_data_page(struct f2fs_sb_info *, struct page *,
|
||||
struct f2fs_summary *, block_t, block_t);
|
||||
void f2fs_replace_block(struct f2fs_sb_info *, struct f2fs_summary *,
|
||||
block_t, block_t, bool);
|
||||
void allocate_data_block(struct f2fs_sb_info *, struct page *,
|
||||
block_t, block_t *, struct f2fs_summary *, int);
|
||||
void f2fs_wait_on_page_writeback(struct page *, enum page_type);
|
||||
|
|
|
@ -412,7 +412,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
|
|||
set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
|
||||
|
||||
/* write dummy data page */
|
||||
recover_data_page(sbi, NULL, &sum, src, dest);
|
||||
f2fs_replace_block(sbi, &sum, src, dest, false);
|
||||
dn.data_blkaddr = dest;
|
||||
set_data_blkaddr(&dn);
|
||||
f2fs_update_extent_cache(&dn);
|
||||
|
|
|
@ -1264,32 +1264,41 @@ void rewrite_data_page(struct f2fs_io_info *fio)
|
|||
f2fs_submit_page_mbio(fio);
|
||||
}
|
||||
|
||||
void recover_data_page(struct f2fs_sb_info *sbi,
|
||||
struct page *page, struct f2fs_summary *sum,
|
||||
block_t old_blkaddr, block_t new_blkaddr)
|
||||
void f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
||||
block_t old_blkaddr, block_t new_blkaddr,
|
||||
bool recover_curseg)
|
||||
{
|
||||
struct sit_info *sit_i = SIT_I(sbi);
|
||||
struct curseg_info *curseg;
|
||||
unsigned int segno, old_cursegno;
|
||||
struct seg_entry *se;
|
||||
int type;
|
||||
unsigned short old_blkoff;
|
||||
|
||||
segno = GET_SEGNO(sbi, new_blkaddr);
|
||||
se = get_seg_entry(sbi, segno);
|
||||
type = se->type;
|
||||
|
||||
if (se->valid_blocks == 0 && !IS_CURSEG(sbi, segno)) {
|
||||
if (old_blkaddr == NULL_ADDR)
|
||||
type = CURSEG_COLD_DATA;
|
||||
else
|
||||
if (!recover_curseg) {
|
||||
/* for recovery flow */
|
||||
if (se->valid_blocks == 0 && !IS_CURSEG(sbi, segno)) {
|
||||
if (old_blkaddr == NULL_ADDR)
|
||||
type = CURSEG_COLD_DATA;
|
||||
else
|
||||
type = CURSEG_WARM_DATA;
|
||||
}
|
||||
} else {
|
||||
if (!IS_CURSEG(sbi, segno))
|
||||
type = CURSEG_WARM_DATA;
|
||||
}
|
||||
|
||||
curseg = CURSEG_I(sbi, type);
|
||||
|
||||
mutex_lock(&curseg->curseg_mutex);
|
||||
mutex_lock(&sit_i->sentry_lock);
|
||||
|
||||
old_cursegno = curseg->segno;
|
||||
old_blkoff = curseg->next_blkoff;
|
||||
|
||||
/* change the current segment */
|
||||
if (segno != curseg->segno) {
|
||||
|
@ -1303,6 +1312,14 @@ void recover_data_page(struct f2fs_sb_info *sbi,
|
|||
refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
|
||||
locate_dirty_segment(sbi, old_cursegno);
|
||||
|
||||
if (recover_curseg) {
|
||||
if (old_cursegno != curseg->segno) {
|
||||
curseg->next_segno = old_cursegno;
|
||||
change_curseg(sbi, type, true);
|
||||
}
|
||||
curseg->next_blkoff = old_blkoff;
|
||||
}
|
||||
|
||||
mutex_unlock(&sit_i->sentry_lock);
|
||||
mutex_unlock(&curseg->curseg_mutex);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue