mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
f2fs-for-6.2-rc1
In this round, we've added two features: 1) F2FS_IOC_START_ATOMIC_REPLACE and 2) per-block age-based extent cache. 1) is a variant of the previous atomic write feature which guarantees a per-file atomicity. It would be more efficient than AtomicFile implementation in Android framework. 2) implements another type of extent cache in memory which keeps the per-block age in a file, so that block allocator could split the hot and cold data blocks more accurately. Enhancement: - introduce F2FS_IOC_START_ATOMIC_REPLACE - refactor extent_cache to add a new per-block-age-based extent cache support - introduce discard_urgent_util, gc_mode, max_ordered_discard sysfs knobs - add proc entry to show discard_plist info - optimize iteration over sparse directories - add barrier mount option Bug fix - avoid victim selection from previous victim section - fix to enable compress for newly created file if extension matches - set zstd compress level correctly - initialize locks early in f2fs_fill_super() to fix bugs reported by syzbot - correct i_size change for atomic writes - allow to read node block after shutdown - allow to set compression for inlined file - fix gc mode when gc_urgent_high_remaining is 1 - should put a page when checking the summary info Minor fixes and various clean-ups in GC, discard, debugfs, sysfs, and doc. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE00UqedjCtOrGVvQiQBSofoJIUNIFAmOaTNUACgkQQBSofoJI UNIQnw//V7Q8DUHw5YNj04jutwXH2DNMLAmn/NJh5S6dIzy/LiywlSzVg53/0/FP 4K577urUkIhgilRO+yncUMSnSQk7BluQvGSx4ja2AV+dpDomjxM3GwIacGzSvr7D VfVf8Vig10UEFrrtEEKtv1VFlYHAmo8lLpubzrZHV8aZFLHHYO2fakQhPu8BYsaz eGCJwxjvTZcQUPkaeG9tWto3ChI3F6PzreiQ5TztHhLWSEgw/o0qijpsc+2SthaV my7uGjeBY8EGPeSYbeCxRtdx8g8Qu11K3ISuDj8zBybmjG3IWOGt1CVcrY6tZbal aL70CMtHkMqMn03VqbpCTqBtdWNMrrw5sYSL3qXIUdXlX/2yJBh9fLAeNxKNs5Nu 6veSb2WgYMHqIsClkAAcP0xJ8g6kodGoG60wVr4ek0Vdt4osaQqwq+bnffpwwxtQ F+7aRuinv+rdrHJ4CuFXAmHPKh2lBe2lTTWZEKg2RptTxZ5DhD2Qn6x1khPD2GFA mG2Aeiq6PVxxEeIO+w/VBCuAgpGTFV2N/ZIF8VfjFNdWiN5OGLWQNHC2KGj2G2uV +fA+B91txQWtjY9h72YJb2+aGIixcnLY24ni4mDgDItqtpCB4PW56W8cbnbv9Pl+ aXAWdADqJdDyllHoVB/JQ24gr2fATJGRIDeYDnw+vPP4f5ZT5vg= =f00t -----END PGP SIGNATURE----- Merge tag 'f2fs-for-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs Pull f2fs updates from Jaegeuk Kim: "In this round, we've added two features: F2FS_IOC_START_ATOMIC_REPLACE and a per-block age-based extent cache. F2FS_IOC_START_ATOMIC_REPLACE is a variant of the previous atomic write feature which guarantees a per-file atomicity. It would be more efficient than AtomicFile implementation in Android framework. The per-block age-based extent cache implements another type of extent cache in memory which keeps the per-block age in a file, so that block allocator could split the hot and cold data blocks more accurately. Enhancements: - introduce F2FS_IOC_START_ATOMIC_REPLACE - refactor extent_cache to add a new per-block-age-based extent cache support - introduce discard_urgent_util, gc_mode, max_ordered_discard sysfs knobs - add proc entry to show discard_plist info - optimize iteration over sparse directories - add barrier mount option Bug fixes: - avoid victim selection from previous victim section - fix to enable compress for newly created file if extension matches - set zstd compress level correctly - initialize locks early in f2fs_fill_super() to fix bugs reported by syzbot - correct i_size change for atomic writes - allow to read node block after shutdown - allow to set compression for inlined file - fix gc mode when gc_urgent_high_remaining is 1 - should put a page when checking the summary info Minor fixes and various clean-ups in GC, discard, debugfs, sysfs, and doc" * tag 'f2fs-for-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (63 commits) f2fs: reset wait_ms to default if any of the victims have been selected f2fs: fix some format WARNING in debug.c and sysfs.c f2fs: don't call f2fs_issue_discard_timeout() when discard_cmd_cnt is 0 in f2fs_put_super() f2fs: fix iostat parameter for discard f2fs: Fix spelling mistake in label: free_bio_enrty_cache -> free_bio_entry_cache f2fs: add block_age-based extent cache f2fs: allocate the extent_cache by default f2fs: refactor extent_cache to support for read and more f2fs: remove unnecessary __init_extent_tree f2fs: move internal functions into extent_cache.c f2fs: specify extent cache for read explicitly f2fs: introduce f2fs_is_readonly() for readability f2fs: remove F2FS_SET_FEATURE() and F2FS_CLEAR_FEATURE() macro f2fs: do some cleanup for f2fs module init MAINTAINERS: Add f2fs bug tracker link f2fs: remove the unused flush argument to change_curseg f2fs: open code allocate_segment_by_default f2fs: remove struct segment_allocation default_salloc_ops f2fs: introduce discard_urgent_util sysfs node f2fs: define MIN_DISCARD_GRANULARITY macro ...
This commit is contained in:
commit
041fae9c10
24 changed files with 1654 additions and 939 deletions
79
fs/f2fs/gc.c
79
fs/f2fs/gc.c
|
@ -96,16 +96,6 @@ static int gc_thread_func(void *data)
|
|||
* invalidated soon after by user update or deletion.
|
||||
* So, I'd like to wait some time to collect dirty segments.
|
||||
*/
|
||||
if (sbi->gc_mode == GC_URGENT_HIGH) {
|
||||
spin_lock(&sbi->gc_urgent_high_lock);
|
||||
if (sbi->gc_urgent_high_remaining) {
|
||||
sbi->gc_urgent_high_remaining--;
|
||||
if (!sbi->gc_urgent_high_remaining)
|
||||
sbi->gc_mode = GC_NORMAL;
|
||||
}
|
||||
spin_unlock(&sbi->gc_urgent_high_lock);
|
||||
}
|
||||
|
||||
if (sbi->gc_mode == GC_URGENT_HIGH ||
|
||||
sbi->gc_mode == GC_URGENT_MID) {
|
||||
wait_ms = gc_th->urgent_sleep_time;
|
||||
|
@ -151,6 +141,10 @@ do_gc:
|
|||
/* don't bother wait_ms by foreground gc */
|
||||
if (!foreground)
|
||||
wait_ms = gc_th->no_gc_sleep_time;
|
||||
} else {
|
||||
/* reset wait_ms to default sleep time */
|
||||
if (wait_ms == gc_th->no_gc_sleep_time)
|
||||
wait_ms = gc_th->min_sleep_time;
|
||||
}
|
||||
|
||||
if (foreground)
|
||||
|
@ -162,6 +156,15 @@ do_gc:
|
|||
/* balancing f2fs's metadata periodically */
|
||||
f2fs_balance_fs_bg(sbi, true);
|
||||
next:
|
||||
if (sbi->gc_mode != GC_NORMAL) {
|
||||
spin_lock(&sbi->gc_remaining_trials_lock);
|
||||
if (sbi->gc_remaining_trials) {
|
||||
sbi->gc_remaining_trials--;
|
||||
if (!sbi->gc_remaining_trials)
|
||||
sbi->gc_mode = GC_NORMAL;
|
||||
}
|
||||
spin_unlock(&sbi->gc_remaining_trials_lock);
|
||||
}
|
||||
sb_end_write(sbi->sb);
|
||||
|
||||
} while (!kthread_should_stop());
|
||||
|
@ -172,13 +175,10 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
|
|||
{
|
||||
struct f2fs_gc_kthread *gc_th;
|
||||
dev_t dev = sbi->sb->s_bdev->bd_dev;
|
||||
int err = 0;
|
||||
|
||||
gc_th = f2fs_kmalloc(sbi, sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
|
||||
if (!gc_th) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (!gc_th)
|
||||
return -ENOMEM;
|
||||
|
||||
gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
|
||||
gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
|
||||
|
@ -193,12 +193,14 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
|
|||
sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
|
||||
"f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev));
|
||||
if (IS_ERR(gc_th->f2fs_gc_task)) {
|
||||
err = PTR_ERR(gc_th->f2fs_gc_task);
|
||||
int err = PTR_ERR(gc_th->f2fs_gc_task);
|
||||
|
||||
kfree(gc_th);
|
||||
sbi->gc_thread = NULL;
|
||||
return err;
|
||||
}
|
||||
out:
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi)
|
||||
|
@ -1079,7 +1081,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
|||
{
|
||||
struct page *node_page;
|
||||
nid_t nid;
|
||||
unsigned int ofs_in_node, max_addrs;
|
||||
unsigned int ofs_in_node, max_addrs, base;
|
||||
block_t source_blkaddr;
|
||||
|
||||
nid = le32_to_cpu(sum->nid);
|
||||
|
@ -1105,11 +1107,18 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
|
|||
return false;
|
||||
}
|
||||
|
||||
max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE :
|
||||
DEF_ADDRS_PER_BLOCK;
|
||||
if (ofs_in_node >= max_addrs) {
|
||||
f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
|
||||
ofs_in_node, dni->ino, dni->nid, max_addrs);
|
||||
if (IS_INODE(node_page)) {
|
||||
base = offset_in_addr(F2FS_INODE(node_page));
|
||||
max_addrs = DEF_ADDRS_PER_INODE;
|
||||
} else {
|
||||
base = 0;
|
||||
max_addrs = DEF_ADDRS_PER_BLOCK;
|
||||
}
|
||||
|
||||
if (base + ofs_in_node >= max_addrs) {
|
||||
f2fs_err(sbi, "Inconsistent blkaddr offset: base:%u, ofs_in_node:%u, max:%u, ino:%u, nid:%u",
|
||||
base, ofs_in_node, max_addrs, dni->ino, dni->nid);
|
||||
f2fs_put_page(node_page, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1141,7 +1150,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
|
|||
struct address_space *mapping = inode->i_mapping;
|
||||
struct dnode_of_data dn;
|
||||
struct page *page;
|
||||
struct extent_info ei = {0, 0, 0};
|
||||
struct extent_info ei = {0, };
|
||||
struct f2fs_io_info fio = {
|
||||
.sbi = sbi,
|
||||
.ino = inode->i_ino,
|
||||
|
@ -1159,7 +1168,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
|
|||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
if (f2fs_lookup_extent_cache(inode, index, &ei)) {
|
||||
if (f2fs_lookup_read_extent_cache(inode, index, &ei)) {
|
||||
dn.data_blkaddr = ei.blk + index - ei.fofs;
|
||||
if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr,
|
||||
DATA_GENERIC_ENHANCE_READ))) {
|
||||
|
@ -1563,8 +1572,8 @@ next_step:
|
|||
continue;
|
||||
}
|
||||
|
||||
data_page = f2fs_get_read_data_page(inode,
|
||||
start_bidx, REQ_RAHEAD, true);
|
||||
data_page = f2fs_get_read_data_page(inode, start_bidx,
|
||||
REQ_RAHEAD, true, NULL);
|
||||
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
if (IS_ERR(data_page)) {
|
||||
iput(inode);
|
||||
|
@ -1744,8 +1753,9 @@ freed:
|
|||
get_valid_blocks(sbi, segno, false) == 0)
|
||||
seg_freed++;
|
||||
|
||||
if (__is_large_section(sbi) && segno + 1 < end_segno)
|
||||
sbi->next_victim_seg[gc_type] = segno + 1;
|
||||
if (__is_large_section(sbi))
|
||||
sbi->next_victim_seg[gc_type] =
|
||||
(segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
|
||||
skip:
|
||||
f2fs_put_page(sum_page, 0);
|
||||
}
|
||||
|
@ -1898,9 +1908,7 @@ int __init f2fs_create_garbage_collection_cache(void)
|
|||
{
|
||||
victim_entry_slab = f2fs_kmem_cache_create("f2fs_victim_entry",
|
||||
sizeof(struct victim_entry));
|
||||
if (!victim_entry_slab)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
return victim_entry_slab ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
void f2fs_destroy_garbage_collection_cache(void)
|
||||
|
@ -2133,8 +2141,6 @@ out_unlock:
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
set_sbi_flag(sbi, SBI_IS_RESIZEFS);
|
||||
|
||||
freeze_super(sbi->sb);
|
||||
f2fs_down_write(&sbi->gc_lock);
|
||||
f2fs_down_write(&sbi->cp_global_sem);
|
||||
|
@ -2150,6 +2156,7 @@ out_unlock:
|
|||
if (err)
|
||||
goto out_err;
|
||||
|
||||
set_sbi_flag(sbi, SBI_IS_RESIZEFS);
|
||||
err = free_segment_range(sbi, secs, false);
|
||||
if (err)
|
||||
goto recover_out;
|
||||
|
@ -2173,6 +2180,7 @@ out_unlock:
|
|||
f2fs_commit_super(sbi, false);
|
||||
}
|
||||
recover_out:
|
||||
clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
|
||||
if (err) {
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
f2fs_err(sbi, "resize_fs failed, should run fsck to repair!");
|
||||
|
@ -2185,6 +2193,5 @@ out_err:
|
|||
f2fs_up_write(&sbi->cp_global_sem);
|
||||
f2fs_up_write(&sbi->gc_lock);
|
||||
thaw_super(sbi->sb);
|
||||
clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue