Skip to content

Commit 05cd503

Browse files
Jaegeuk KimJaegeuk Kim
authored andcommitted
FROMGIT: f2fs: keep POSIX_FADV_NOREUSE ranges
This patch records POSIX_FADV_NOREUSE ranges for users to reclaim the caches instantly off from LRU. Bug: 390229090 Reviewed-by: Chao Yu <chao@kernel.org> Change-Id: If83a0b97df99c45464645499ed81979dacd0ac28 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> (cherry picked from commit ef0c333 https: //git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/ dev)
1 parent 1832630 commit 05cd503

5 files changed

Lines changed: 84 additions & 6 deletions

File tree

fs/f2fs/debug.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
164164
si->ndirty_imeta = get_pages(sbi, F2FS_DIRTY_IMETA);
165165
si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE];
166166
si->ndirty_files = sbi->ndirty_inode[FILE_INODE];
167+
si->ndonate_files = sbi->donate_files;
167168
si->nquota_files = sbi->nquota_files;
168169
si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
169170
si->aw_cnt = atomic_read(&sbi->atomic_files);
@@ -501,6 +502,8 @@ static int stat_show(struct seq_file *s, void *v)
501502
si->compr_inode, si->compr_blocks);
502503
seq_printf(s, " - Swapfile Inode: %u\n",
503504
si->swapfile_inode);
505+
seq_printf(s, " - Donate Inode: %u\n",
506+
si->ndonate_files);
504507
seq_printf(s, " - Orphan/Append/Update Inode: %u, %u, %u\n",
505508
si->orphans, si->append, si->update);
506509
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
@@ -851,6 +851,11 @@ struct f2fs_inode_info {
851851
#endif
852852
struct list_head dirty_list; /* dirty list for dirs and files */
853853
struct list_head gdirty_list; /* linked in global dirty list */
854+
855+
/* linked in global inode list for cache donation */
856+
struct list_head gdonate_list;
857+
pgoff_t donate_start, donate_end; /* inclusive */
858+
854859
struct task_struct *atomic_write_task; /* store atomic write task */
855860
struct extent_tree *extent_tree[NR_EXTENT_CACHES];
856861
/* 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 */
@@ -3975,7 +3984,8 @@ struct f2fs_stat_info {
39753984
unsigned long long allocated_data_blocks;
39763985
int ndirty_node, ndirty_dent, ndirty_meta, ndirty_imeta;
39773986
int ndirty_data, ndirty_qdata;
3978-
unsigned int ndirty_dirs, ndirty_files, nquota_files, ndirty_all;
3987+
unsigned int ndirty_dirs, ndirty_files, ndirty_all;
3988+
unsigned int nquota_files, ndonate_files;
39793989
int nats, dirty_nats, sits, dirty_sits;
39803990
int free_nids, avail_nids, alloc_nids;
39813991
int total_count, utilization;

fs/f2fs/file.c

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

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

51845230
err = generic_fadvise(filp, offset, len, advice);
5185-
if (!err && advice == POSIX_FADV_DONTNEED &&
5186-
test_opt(F2FS_I_SB(inode), COMPRESS_CACHE) &&
5187-
f2fs_compressed_file(inode))
5188-
f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino);
5231+
if (err)
5232+
return err;
51895233

5190-
return err;
5234+
if (advice == POSIX_FADV_DONTNEED &&
5235+
(test_opt(F2FS_I_SB(inode), COMPRESS_CACHE) &&
5236+
f2fs_compressed_file(inode)))
5237+
f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino);
5238+
else if (advice == POSIX_FADV_NOREUSE)
5239+
f2fs_keep_noreuse_range(inode, offset, len);
5240+
return 0;
51915241
}
51925242

51935243
#ifdef CONFIG_COMPAT

fs/f2fs/inode.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,19 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
804804
return 0;
805805
}
806806

807+
static void f2fs_remove_donate_inode(struct inode *inode)
808+
{
809+
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
810+
811+
if (list_empty(&F2FS_I(inode)->gdonate_list))
812+
return;
813+
814+
spin_lock(&sbi->inode_lock[DONATE_INODE]);
815+
list_del_init(&F2FS_I(inode)->gdonate_list);
816+
sbi->donate_files--;
817+
spin_unlock(&sbi->inode_lock[DONATE_INODE]);
818+
}
819+
807820
/*
808821
* Called at the last iput() if i_nlink is zero
809822
*/
@@ -838,6 +851,7 @@ void f2fs_evict_inode(struct inode *inode)
838851

839852
f2fs_bug_on(sbi, get_dirty_pages(inode));
840853
f2fs_remove_dirty_inode(inode);
854+
f2fs_remove_donate_inode(inode);
841855

842856
if (!IS_DEVICE_ALIASING(inode))
843857
f2fs_destroy_extent_tree(inode);

fs/f2fs/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
14191419
spin_lock_init(&fi->i_size_lock);
14201420
INIT_LIST_HEAD(&fi->dirty_list);
14211421
INIT_LIST_HEAD(&fi->gdirty_list);
1422+
INIT_LIST_HEAD(&fi->gdonate_list);
14221423
init_f2fs_rwsem(&fi->i_gc_rwsem[READ]);
14231424
init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]);
14241425
init_f2fs_rwsem(&fi->i_xattr_sem);

0 commit comments

Comments
 (0)