Skip to content

Commit

Permalink
f2fs: expand counting dirty pages in the inode page cache
Browse files Browse the repository at this point in the history
Previously f2fs only counts dirty dentry pages, but there is no reason not to
expand the scope.

This patch changes the names on the management of dirty pages and to count
dirty pages in each inode info as well.

Signed-off-by: Jaegeuk Kim <[email protected]>
  • Loading branch information
Jaegeuk Kim committed Sep 16, 2014
1 parent 2403c15 commit a7ffdbe
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 26 deletions.
16 changes: 11 additions & 5 deletions fs/f2fs/checkpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,27 +627,33 @@ static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)
return 0;
}

void set_dirty_dir_page(struct inode *inode, struct page *page)
void update_dirty_page(struct inode *inode, struct page *page)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dir_inode_entry *new;
int ret = 0;

if (!S_ISDIR(inode->i_mode))
if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
return;

if (!S_ISDIR(inode->i_mode)) {
inode_inc_dirty_pages(inode);
goto out;
}

new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
new->inode = inode;
INIT_LIST_HEAD(&new->list);

spin_lock(&sbi->dir_inode_lock);
ret = __add_dirty_inode(inode, new);
inode_inc_dirty_dents(inode);
SetPagePrivate(page);
inode_inc_dirty_pages(inode);
spin_unlock(&sbi->dir_inode_lock);

if (ret)
kmem_cache_free(inode_entry_slab, new);
out:
SetPagePrivate(page);
}

void add_dirty_dir_inode(struct inode *inode)
Expand Down Expand Up @@ -677,7 +683,7 @@ void remove_dirty_dir_inode(struct inode *inode)
return;

spin_lock(&sbi->dir_inode_lock);
if (get_dirty_dents(inode) ||
if (get_dirty_pages(inode) ||
!is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) {
spin_unlock(&sbi->dir_inode_lock);
return;
Expand Down
16 changes: 10 additions & 6 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ static int f2fs_write_data_page(struct page *page,
if (unlikely(f2fs_cp_error(sbi))) {
SetPageError(page);
unlock_page(page);
return 0;
goto out;
}

if (!wbc->for_reclaim)
Expand All @@ -863,7 +863,7 @@ static int f2fs_write_data_page(struct page *page,

clear_cold_data(page);
out:
inode_dec_dirty_dents(inode);
inode_dec_dirty_pages(inode);
unlock_page(page);
if (need_balance_fs)
f2fs_balance_fs(sbi);
Expand Down Expand Up @@ -901,7 +901,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
return 0;

if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA) &&
get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
available_free_memory(sbi, DIRTY_DENTS))
goto skip_write;

Expand All @@ -923,7 +923,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
return ret;

skip_write:
wbc->pages_skipped += get_dirty_dents(inode);
wbc->pages_skipped += get_dirty_pages(inode);
return 0;
}

Expand Down Expand Up @@ -1107,8 +1107,12 @@ static void f2fs_invalidate_data_page(struct page *page, unsigned int offset,
unsigned int length)
{
struct inode *inode = page->mapping->host;

if (offset % PAGE_CACHE_SIZE || length != PAGE_CACHE_SIZE)
return;

if (PageDirty(page))
inode_dec_dirty_dents(inode);
inode_dec_dirty_pages(inode);
ClearPagePrivate(page);
}

Expand All @@ -1130,7 +1134,7 @@ static int f2fs_set_data_page_dirty(struct page *page)

if (!PageDirty(page)) {
__set_page_dirty_nobuffers(page);
set_dirty_dir_page(inode, page);
update_dirty_page(inode, page);
return 1;
}
return 0;
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
truncate_hole(dir, page->index, page->index + 1);
clear_page_dirty_for_io(page);
ClearPageUptodate(page);
inode_dec_dirty_dents(dir);
inode_dec_dirty_pages(dir);
}
f2fs_put_page(page, 1);
}
Expand Down
25 changes: 14 additions & 11 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ struct f2fs_inode_info {
/* Use below internally in f2fs*/
unsigned long flags; /* use to pass per-file flags */
struct rw_semaphore i_sem; /* protect fi info */
atomic_t dirty_dents; /* # of dirty dentry pages */
atomic_t dirty_pages; /* # of dirty pages */
f2fs_hash_t chash; /* hash value of given file name */
unsigned int clevel; /* maximum level of given file name */
nid_t i_xattr_nid; /* node id that contains xattrs */
Expand Down Expand Up @@ -747,34 +747,37 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
F2FS_SET_SB_DIRT(sbi);
}

static inline void inode_inc_dirty_dents(struct inode *inode)
static inline void inode_inc_dirty_pages(struct inode *inode)
{
inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
atomic_inc(&F2FS_I(inode)->dirty_dents);
atomic_inc(&F2FS_I(inode)->dirty_pages);
if (S_ISDIR(inode->i_mode))
inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
}

static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
{
atomic_dec(&sbi->nr_pages[count_type]);
}

static inline void inode_dec_dirty_dents(struct inode *inode)
static inline void inode_dec_dirty_pages(struct inode *inode)
{
if (!S_ISDIR(inode->i_mode))
if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
return;

dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
atomic_dec(&F2FS_I(inode)->dirty_dents);
atomic_dec(&F2FS_I(inode)->dirty_pages);

if (S_ISDIR(inode->i_mode))
dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
}

static inline int get_pages(struct f2fs_sb_info *sbi, int count_type)
{
return atomic_read(&sbi->nr_pages[count_type]);
}

static inline int get_dirty_dents(struct inode *inode)
static inline int get_dirty_pages(struct inode *inode)
{
return atomic_read(&F2FS_I(inode)->dirty_dents);
return atomic_read(&F2FS_I(inode)->dirty_pages);
}

static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
Expand Down Expand Up @@ -1302,7 +1305,7 @@ void add_orphan_inode(struct f2fs_sb_info *, nid_t);
void remove_orphan_inode(struct f2fs_sb_info *, nid_t);
void recover_orphan_inodes(struct f2fs_sb_info *);
int get_valid_checkpoint(struct f2fs_sb_info *);
void set_dirty_dir_page(struct inode *, struct page *);
void update_dirty_page(struct inode *, struct page *);
void add_dirty_dir_inode(struct inode *);
void remove_dirty_dir_inode(struct inode *);
void sync_dirty_dir_inodes(struct f2fs_sb_info *);
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ static void move_data_page(struct inode *inode, struct page *page, int gc_type)
f2fs_wait_on_page_writeback(page, DATA);

if (clear_page_dirty_for_io(page))
inode_dec_dirty_dents(inode);
inode_dec_dirty_pages(inode);
set_cold_data(page);
do_write_data_page(page, &fio);
clear_cold_data(page);
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ void f2fs_evict_inode(struct inode *inode)
inode->i_ino == F2FS_META_INO(sbi))
goto out_clear;

f2fs_bug_on(sbi, get_dirty_dents(inode));
f2fs_bug_on(sbi, get_dirty_pages(inode));
remove_dirty_dir_inode(inode);

if (inode->i_nlink || is_bad_inode(inode))
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)

/* Initialize f2fs-specific inode info */
fi->vfs_inode.i_version = 1;
atomic_set(&fi->dirty_dents, 0);
atomic_set(&fi->dirty_pages, 0);
fi->i_current_depth = 1;
fi->i_advise = 0;
rwlock_init(&fi->ext.ext_lock);
Expand Down

0 comments on commit a7ffdbe

Please sign in to comment.