Skip to content

Commit 58eceda

Browse files
Jaegeuk Kimgregkh
authored andcommitted
f2fs: keep POSIX_FADV_NOREUSE ranges
[ Upstream commit ef0c333 ] This patch records POSIX_FADV_NOREUSE ranges for users to reclaim the caches instantly off from LRU. Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Stable-dep-of: e462fc4 ("f2fs: maintain one time GC mode is enabled during whole zoned GC cycle") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3e50b6e commit 58eceda

File tree

5 files changed

+84
-6
lines changed

5 files changed

+84
-6
lines changed

fs/f2fs/debug.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
100100
si->ndirty_imeta = get_pages(sbi, F2FS_DIRTY_IMETA);
101101
si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE];
102102
si->ndirty_files = sbi->ndirty_inode[FILE_INODE];
103+
si->ndonate_files = sbi->donate_files;
103104
si->nquota_files = sbi->nquota_files;
104105
si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
105106
si->aw_cnt = atomic_read(&sbi->atomic_files);
@@ -435,6 +436,8 @@ static int stat_show(struct seq_file *s, void *v)
435436
si->compr_inode, si->compr_blocks);
436437
seq_printf(s, " - Swapfile Inode: %u\n",
437438
si->swapfile_inode);
439+
seq_printf(s, " - Donate Inode: %u\n",
440+
si->ndonate_files);
438441
seq_printf(s, " - Orphan/Append/Update Inode: %u, %u, %u\n",
439442
si->orphans, si->append, si->update);
440443
seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",

fs/f2fs/f2fs.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,11 @@ struct f2fs_inode_info {
849849
#endif
850850
struct list_head dirty_list; /* dirty list for dirs and files */
851851
struct list_head gdirty_list; /* linked in global dirty list */
852+
853+
/* linked in global inode list for cache donation */
854+
struct list_head gdonate_list;
855+
pgoff_t donate_start, donate_end; /* inclusive */
856+
852857
struct task_struct *atomic_write_task; /* store atomic write task */
853858
struct extent_tree *extent_tree[NR_EXTENT_CACHES];
854859
/* cached extent_tree entry */
@@ -1274,6 +1279,7 @@ enum inode_type {
12741279
DIR_INODE, /* for dirty dir inode */
12751280
FILE_INODE, /* for dirty regular/symlink inode */
12761281
DIRTY_META, /* for all dirtied inode metadata */
1282+
DONATE_INODE, /* for all inode to donate pages */
12771283
NR_INODE_TYPE,
12781284
};
12791285

@@ -1629,6 +1635,9 @@ struct f2fs_sb_info {
16291635
unsigned int warm_data_age_threshold;
16301636
unsigned int last_age_weight;
16311637

1638+
/* control donate caches */
1639+
unsigned int donate_files;
1640+
16321641
/* basic filesystem units */
16331642
unsigned int log_sectors_per_block; /* log2 sectors per block */
16341643
unsigned int log_blocksize; /* log2 block size */
@@ -3997,7 +4006,8 @@ struct f2fs_stat_info {
39974006
unsigned long long allocated_data_blocks;
39984007
int ndirty_node, ndirty_dent, ndirty_meta, ndirty_imeta;
39994008
int ndirty_data, ndirty_qdata;
4000-
unsigned int ndirty_dirs, ndirty_files, nquota_files, ndirty_all;
4009+
unsigned int ndirty_dirs, ndirty_files, ndirty_all;
4010+
unsigned int nquota_files, ndonate_files;
40014011
int nats, dirty_nats, sits, dirty_sits;
40024012
int free_nids, avail_nids, alloc_nids;
40034013
int total_count, utilization;

fs/f2fs/file.c

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,6 +2452,52 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
24522452
return ret;
24532453
}
24542454

2455+
static void f2fs_keep_noreuse_range(struct inode *inode,
2456+
loff_t offset, loff_t len)
2457+
{
2458+
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
2459+
u64 max_bytes = F2FS_BLK_TO_BYTES(max_file_blocks(inode));
2460+
u64 start, end;
2461+
2462+
if (!S_ISREG(inode->i_mode))
2463+
return;
2464+
2465+
if (offset >= max_bytes || len > max_bytes ||
2466+
(offset + len) > max_bytes)
2467+
return;
2468+
2469+
start = offset >> PAGE_SHIFT;
2470+
end = DIV_ROUND_UP(offset + len, PAGE_SIZE);
2471+
2472+
inode_lock(inode);
2473+
if (f2fs_is_atomic_file(inode)) {
2474+
inode_unlock(inode);
2475+
return;
2476+
}
2477+
2478+
spin_lock(&sbi->inode_lock[DONATE_INODE]);
2479+
/* let's remove the range, if len = 0 */
2480+
if (!len) {
2481+
if (!list_empty(&F2FS_I(inode)->gdonate_list)) {
2482+
list_del_init(&F2FS_I(inode)->gdonate_list);
2483+
sbi->donate_files--;
2484+
}
2485+
} else {
2486+
if (list_empty(&F2FS_I(inode)->gdonate_list)) {
2487+
list_add_tail(&F2FS_I(inode)->gdonate_list,
2488+
&sbi->inode_list[DONATE_INODE]);
2489+
sbi->donate_files++;
2490+
} else {
2491+
list_move_tail(&F2FS_I(inode)->gdonate_list,
2492+
&sbi->inode_list[DONATE_INODE]);
2493+
}
2494+
F2FS_I(inode)->donate_start = start;
2495+
F2FS_I(inode)->donate_end = end - 1;
2496+
}
2497+
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
2498+
inode_unlock(inode);
2499+
}
2500+
24552501
static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg)
24562502
{
24572503
struct inode *inode = file_inode(filp);
@@ -5144,12 +5190,16 @@ static int f2fs_file_fadvise(struct file *filp, loff_t offset, loff_t len,
51445190
}
51455191

51465192
err = generic_fadvise(filp, offset, len, advice);
5147-
if (!err && advice == POSIX_FADV_DONTNEED &&
5148-
test_opt(F2FS_I_SB(inode), COMPRESS_CACHE) &&
5149-
f2fs_compressed_file(inode))
5150-
f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino);
5193+
if (err)
5194+
return err;
51515195

5152-
return err;
5196+
if (advice == POSIX_FADV_DONTNEED &&
5197+
(test_opt(F2FS_I_SB(inode), COMPRESS_CACHE) &&
5198+
f2fs_compressed_file(inode)))
5199+
f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino);
5200+
else if (advice == POSIX_FADV_NOREUSE)
5201+
f2fs_keep_noreuse_range(inode, offset, len);
5202+
return 0;
51535203
}
51545204

51555205
#ifdef CONFIG_COMPAT

fs/f2fs/inode.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,19 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
807807
return 0;
808808
}
809809

810+
static void f2fs_remove_donate_inode(struct inode *inode)
811+
{
812+
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
813+
814+
if (list_empty(&F2FS_I(inode)->gdonate_list))
815+
return;
816+
817+
spin_lock(&sbi->inode_lock[DONATE_INODE]);
818+
list_del_init(&F2FS_I(inode)->gdonate_list);
819+
sbi->donate_files--;
820+
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
821+
}
822+
810823
/*
811824
* Called at the last iput() if i_nlink is zero
812825
*/
@@ -841,6 +854,7 @@ void f2fs_evict_inode(struct inode *inode)
841854

842855
f2fs_bug_on(sbi, get_dirty_pages(inode));
843856
f2fs_remove_dirty_inode(inode);
857+
f2fs_remove_donate_inode(inode);
844858

845859
f2fs_destroy_extent_tree(inode);
846860

fs/f2fs/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
14291429
spin_lock_init(&fi->i_size_lock);
14301430
INIT_LIST_HEAD(&fi->dirty_list);
14311431
INIT_LIST_HEAD(&fi->gdirty_list);
1432+
INIT_LIST_HEAD(&fi->gdonate_list);
14321433
init_f2fs_rwsem(&fi->i_gc_rwsem[READ]);
14331434
init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]);
14341435
init_f2fs_rwsem(&fi->i_xattr_sem);

0 commit comments

Comments
 (0)