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:
Chao Yu 2015-05-06 13:08:06 +08:00 committed by Jaegeuk Kim
parent d5b692b786
commit 19f106bc03
3 changed files with 27 additions and 10 deletions

View file

@ -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_node_page(unsigned int, struct f2fs_io_info *);
void write_data_page(struct dnode_of_data *, 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 rewrite_data_page(struct f2fs_io_info *);
void recover_data_page(struct f2fs_sb_info *, struct page *, void f2fs_replace_block(struct f2fs_sb_info *, struct f2fs_summary *,
struct f2fs_summary *, block_t, block_t); block_t, block_t, bool);
void allocate_data_block(struct f2fs_sb_info *, struct page *, void allocate_data_block(struct f2fs_sb_info *, struct page *,
block_t, block_t *, struct f2fs_summary *, int); block_t, block_t *, struct f2fs_summary *, int);
void f2fs_wait_on_page_writeback(struct page *, enum page_type); void f2fs_wait_on_page_writeback(struct page *, enum page_type);

View file

@ -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); set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
/* write dummy data page */ /* write dummy data page */
recover_data_page(sbi, NULL, &sum, src, dest); f2fs_replace_block(sbi, &sum, src, dest, false);
dn.data_blkaddr = dest; dn.data_blkaddr = dest;
set_data_blkaddr(&dn); set_data_blkaddr(&dn);
f2fs_update_extent_cache(&dn); f2fs_update_extent_cache(&dn);

View file

@ -1264,32 +1264,41 @@ void rewrite_data_page(struct f2fs_io_info *fio)
f2fs_submit_page_mbio(fio); f2fs_submit_page_mbio(fio);
} }
void recover_data_page(struct f2fs_sb_info *sbi, void f2fs_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
struct page *page, struct f2fs_summary *sum, block_t old_blkaddr, block_t new_blkaddr,
block_t old_blkaddr, block_t new_blkaddr) bool recover_curseg)
{ {
struct sit_info *sit_i = SIT_I(sbi); struct sit_info *sit_i = SIT_I(sbi);
struct curseg_info *curseg; struct curseg_info *curseg;
unsigned int segno, old_cursegno; unsigned int segno, old_cursegno;
struct seg_entry *se; struct seg_entry *se;
int type; int type;
unsigned short old_blkoff;
segno = GET_SEGNO(sbi, new_blkaddr); segno = GET_SEGNO(sbi, new_blkaddr);
se = get_seg_entry(sbi, segno); se = get_seg_entry(sbi, segno);
type = se->type; type = se->type;
if (se->valid_blocks == 0 && !IS_CURSEG(sbi, segno)) { if (!recover_curseg) {
if (old_blkaddr == NULL_ADDR) /* for recovery flow */
type = CURSEG_COLD_DATA; if (se->valid_blocks == 0 && !IS_CURSEG(sbi, segno)) {
else if (old_blkaddr == NULL_ADDR)
type = CURSEG_COLD_DATA;
else
type = CURSEG_WARM_DATA;
}
} else {
if (!IS_CURSEG(sbi, segno))
type = CURSEG_WARM_DATA; type = CURSEG_WARM_DATA;
} }
curseg = CURSEG_I(sbi, type); curseg = CURSEG_I(sbi, type);
mutex_lock(&curseg->curseg_mutex); mutex_lock(&curseg->curseg_mutex);
mutex_lock(&sit_i->sentry_lock); mutex_lock(&sit_i->sentry_lock);
old_cursegno = curseg->segno; old_cursegno = curseg->segno;
old_blkoff = curseg->next_blkoff;
/* change the current segment */ /* change the current segment */
if (segno != curseg->segno) { 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); refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
locate_dirty_segment(sbi, old_cursegno); 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(&sit_i->sentry_lock);
mutex_unlock(&curseg->curseg_mutex); mutex_unlock(&curseg->curseg_mutex);
} }