|
@@ -29,6 +29,26 @@
|
|
#include "trace.h"
|
|
#include "trace.h"
|
|
#include <trace/events/f2fs.h>
|
|
#include <trace/events/f2fs.h>
|
|
|
|
|
|
|
|
+static bool __is_cp_guaranteed(struct page *page)
|
|
|
|
+{
|
|
|
|
+ struct address_space *mapping = page->mapping;
|
|
|
|
+ struct inode *inode;
|
|
|
|
+ struct f2fs_sb_info *sbi;
|
|
|
|
+
|
|
|
|
+ if (!mapping)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ inode = mapping->host;
|
|
|
|
+ sbi = F2FS_I_SB(inode);
|
|
|
|
+
|
|
|
|
+ if (inode->i_ino == F2FS_META_INO(sbi) ||
|
|
|
|
+ inode->i_ino == F2FS_NODE_INO(sbi) ||
|
|
|
|
+ S_ISDIR(inode->i_mode) ||
|
|
|
|
+ is_cold_data(page))
|
|
|
|
+ return true;
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
static void f2fs_read_end_io(struct bio *bio)
|
|
static void f2fs_read_end_io(struct bio *bio)
|
|
{
|
|
{
|
|
struct bio_vec *bvec;
|
|
struct bio_vec *bvec;
|
|
@@ -71,6 +91,7 @@ static void f2fs_write_end_io(struct bio *bio)
|
|
|
|
|
|
bio_for_each_segment_all(bvec, bio, i) {
|
|
bio_for_each_segment_all(bvec, bio, i) {
|
|
struct page *page = bvec->bv_page;
|
|
struct page *page = bvec->bv_page;
|
|
|
|
+ enum count_type type = WB_DATA_TYPE(page);
|
|
|
|
|
|
fscrypt_pullback_bio_page(&page, true);
|
|
fscrypt_pullback_bio_page(&page, true);
|
|
|
|
|
|
@@ -78,9 +99,11 @@ static void f2fs_write_end_io(struct bio *bio)
|
|
mapping_set_error(page->mapping, -EIO);
|
|
mapping_set_error(page->mapping, -EIO);
|
|
f2fs_stop_checkpoint(sbi, true);
|
|
f2fs_stop_checkpoint(sbi, true);
|
|
}
|
|
}
|
|
|
|
+ dec_page_count(sbi, type);
|
|
|
|
+ clear_cold_data(page);
|
|
end_page_writeback(page);
|
|
end_page_writeback(page);
|
|
}
|
|
}
|
|
- if (atomic_dec_and_test(&sbi->nr_wb_bios) &&
|
|
|
|
|
|
+ if (!get_pages(sbi, F2FS_WB_CP_DATA) &&
|
|
wq_has_sleeper(&sbi->cp_wait))
|
|
wq_has_sleeper(&sbi->cp_wait))
|
|
wake_up(&sbi->cp_wait);
|
|
wake_up(&sbi->cp_wait);
|
|
|
|
|
|
@@ -148,7 +171,6 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
|
|
struct bio *bio, enum page_type type)
|
|
struct bio *bio, enum page_type type)
|
|
{
|
|
{
|
|
if (!is_read_io(bio_op(bio))) {
|
|
if (!is_read_io(bio_op(bio))) {
|
|
- atomic_inc(&sbi->nr_wb_bios);
|
|
|
|
if (f2fs_sb_mounted_blkzoned(sbi->sb) &&
|
|
if (f2fs_sb_mounted_blkzoned(sbi->sb) &&
|
|
current->plug && (type == DATA || type == NODE))
|
|
current->plug && (type == DATA || type == NODE))
|
|
blk_finish_plug(current->plug);
|
|
blk_finish_plug(current->plug);
|
|
@@ -309,6 +331,11 @@ void f2fs_submit_page_mbio(struct f2fs_io_info *fio)
|
|
verify_block_addr(sbi, fio->old_blkaddr);
|
|
verify_block_addr(sbi, fio->old_blkaddr);
|
|
verify_block_addr(sbi, fio->new_blkaddr);
|
|
verify_block_addr(sbi, fio->new_blkaddr);
|
|
|
|
|
|
|
|
+ bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;
|
|
|
|
+
|
|
|
|
+ if (!is_read)
|
|
|
|
+ inc_page_count(sbi, WB_DATA_TYPE(bio_page));
|
|
|
|
+
|
|
down_write(&io->io_rwsem);
|
|
down_write(&io->io_rwsem);
|
|
|
|
|
|
if (io->bio && (io->last_block_in_bio != fio->new_blkaddr - 1 ||
|
|
if (io->bio && (io->last_block_in_bio != fio->new_blkaddr - 1 ||
|
|
@@ -322,8 +349,6 @@ alloc_new:
|
|
io->fio = *fio;
|
|
io->fio = *fio;
|
|
}
|
|
}
|
|
|
|
|
|
- bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;
|
|
|
|
-
|
|
|
|
if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) <
|
|
if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) <
|
|
PAGE_SIZE) {
|
|
PAGE_SIZE) {
|
|
__submit_merged_bio(io);
|
|
__submit_merged_bio(io);
|
|
@@ -1339,7 +1364,6 @@ done:
|
|
if (err && err != -ENOENT)
|
|
if (err && err != -ENOENT)
|
|
goto redirty_out;
|
|
goto redirty_out;
|
|
|
|
|
|
- clear_cold_data(page);
|
|
|
|
out:
|
|
out:
|
|
inode_dec_dirty_pages(inode);
|
|
inode_dec_dirty_pages(inode);
|
|
if (err)
|
|
if (err)
|
|
@@ -1742,7 +1766,6 @@ static int f2fs_write_end(struct file *file,
|
|
goto unlock_out;
|
|
goto unlock_out;
|
|
|
|
|
|
set_page_dirty(page);
|
|
set_page_dirty(page);
|
|
- clear_cold_data(page);
|
|
|
|
|
|
|
|
if (pos + copied > i_size_read(inode))
|
|
if (pos + copied > i_size_read(inode))
|
|
f2fs_i_size_write(inode, pos + copied);
|
|
f2fs_i_size_write(inode, pos + copied);
|