Re: [f2fs-dev] [PATCH v2] f2fs: fix sbi->extent_list corruption issue
On Mon, Nov 26, 2018 at 10:17:20AM +0530, Sahitya Tummala wrote: > When there is a failure in f2fs_fill_super() after/during > the recovery of fsync'd nodes, it frees the current sbi and > retries again. This time the mount is successful, but the files > that got recovered before retry, still holds the extent tree, > whose extent nodes list is corrupted since sbi and sbi->extent_list > is freed up. The list_del corruption issue is observed when the > file system is getting unmounted and when those recoverd files extent > node is being freed up in the below context. > > list_del corruption. prev->next should be fff1e1ef5480, but was (null) > <...> > kernel BUG at kernel/msm-4.14/lib/list_debug.c:53! > task: fff1f46f2280 task.stack: ff8008068000 > lr : __list_del_entry_valid+0x94/0xb4 > pc : __list_del_entry_valid+0x94/0xb4 > <...> > Call trace: > __list_del_entry_valid+0x94/0xb4 > __release_extent_node+0xb0/0x114 > __free_extent_tree+0x58/0x7c > f2fs_shrink_extent_tree+0xdc/0x3b0 > f2fs_leave_shrinker+0x28/0x7c > f2fs_put_super+0xfc/0x1e0 > generic_shutdown_super+0x70/0xf4 > kill_block_super+0x2c/0x5c > kill_f2fs_super+0x44/0x50 > deactivate_locked_super+0x60/0x8c > deactivate_super+0x68/0x74 > cleanup_mnt+0x40/0x78 > __cleanup_mnt+0x1c/0x28 > task_work_run+0x48/0xd0 > do_notify_resume+0x678/0xe98 > work_pending+0x8/0x14 > > Fix this by cleaning up inodes, extent tree and nodes of those > recovered files before freeing up sbi and before next retry. > Hi Jaegeuk, Chao, I have observed another scenario where the similar list corruption issue can happen with sbi->inode_list as well. If recover_fsync_data() fails at some point in write_checkpoint() due to some error and if those recovered inodes are still dirty, then after the mount is successful, this issue is observed when that dirty inode is under writeback. [ 90.400500] list_del corruption. prev->next should be ffed1f566208, but was (null) [ 90.675349] Call trace: [ 90.677869] __list_del_entry_valid+0x94/0xb4 [ 90.682351] remove_dirty_inode+0xac/0x114 [ 90.686563] __f2fs_write_data_pages+0x6a8/0x6c8 [ 90.691302] f2fs_write_data_pages+0x40/0x4c [ 90.695695] do_writepages+0x80/0xf0 [ 90.699372] __writeback_single_inode+0xdc/0x4ac [ 90.704113] writeback_sb_inodes+0x280/0x440 [ 90.708501] wb_writeback+0x1b8/0x3d0 [ 90.712267] wb_workfn+0x1a8/0x4d4 [ 90.715765] process_one_work+0x1c0/0x3d4 [ 90.719883] worker_thread+0x224/0x344 [ 90.723739] kthread+0x120/0x130 [ 90.727055] ret_from_fork+0x10/0x18 I think it is better to cleanup those inodes completely before freeing sbi and before next retry as done in this patch. Would you like to re-consider this patch for this new issue? Please share your comments. Thanks, > Signed-off-by: Sahitya Tummala > --- > v2: > -call evict_inodes() and f2fs_shrink_extent_tree() to cleanup inodes > > fs/f2fs/f2fs.h | 1 + > fs/f2fs/shrinker.c | 2 +- > fs/f2fs/super.c| 13 - > 3 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 1e03197..aaee63b 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -3407,6 +3407,7 @@ struct rb_entry *f2fs_lookup_rb_tree_ret(struct > rb_root_cached *root, > bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, > struct rb_root_cached *root); > unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int > nr_shrink); > +unsigned long __count_extent_cache(struct f2fs_sb_info *sbi); > bool f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext); > void f2fs_drop_extent_tree(struct inode *inode); > unsigned int f2fs_destroy_extent_node(struct inode *inode); > diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c > index 9e13db9..7e3c13b 100644 > --- a/fs/f2fs/shrinker.c > +++ b/fs/f2fs/shrinker.c > @@ -30,7 +30,7 @@ static unsigned long __count_free_nids(struct f2fs_sb_info > *sbi) > return count > 0 ? count : 0; > } > > -static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi) > +unsigned long __count_extent_cache(struct f2fs_sb_info *sbi) > { > return atomic_read(&sbi->total_zombie_tree) + > atomic_read(&sbi->total_ext_node); > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index af58b2c..769e7b1 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -3016,6 +3016,16 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info > *sbi) > sbi->readdir_ra = 1; > } > > +static void f2fs_cleanup_inodes(struct f2fs_sb_info *sbi) > +{ > + struct super_block *sb = sbi->sb; > + > + sync_filesystem(sb); > + shrink_dcache_sb(sb); > + evict_inodes(sb); > + f2fs_shrink_extent_tree(sbi, __count_extent_cache(sbi)); > +} > + > static int f2fs_fill_super(struct super_block *sb, void *data, int silent) > { > struct f2fs_sb_info *sbi; > @@ -3402,6 +3412,8 @@ static int f2fs_fill_super(struct sup
Re: [f2fs-dev] [PATCH] f2fs: export pin_file flag to user
On 2019/1/4 12:19, Jaegeuk Kim wrote: > This exports pin_file status to user. Semantics of pin_file flag is the same as nocow flag which is more widely used in lsattr/chattr and vfs now. #define FS_NOCOW_FL 0x0080 /* Do not cow file */ lsattr/chattr no copy on write (C) How about exporting it via F2FS_NOCOW_FL(0x0080)? Thanks, > > Signed-off-by: Jaegeuk Kim > --- > fs/f2fs/f2fs.h | 3 ++- > fs/f2fs/file.c | 2 ++ > 2 files changed, 4 insertions(+), 1 deletion(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 12fabd6735dd..036fd62010c1 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -2303,9 +2303,10 @@ static inline void f2fs_change_bit(unsigned int nr, > char *addr) > #define F2FS_EOFBLOCKS_FL0x0040 /* Blocks allocated beyond > EOF */ > #define F2FS_INLINE_DATA_FL 0x1000 /* Inode has inline data. */ > #define F2FS_PROJINHERIT_FL 0x2000 /* Create with parents > projid */ > +#define F2FS_PIN_FILE_FL 0x4000 /* pin_file status */ > #define F2FS_RESERVED_FL 0x8000 /* reserved for ext4 lib */ > > -#define F2FS_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */ > +#define F2FS_FL_USER_VISIBLE 0x704BDFFF /* User visible flags */ > #define F2FS_FL_USER_MODIFIABLE 0x204BC0FF /* User modifiable > flags */ > > /* Flags we can manipulate with through F2FS_IOC_FSSETXATTR */ > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c > index ae2b45e75847..eb099f1ee937 100644 > --- a/fs/f2fs/file.c > +++ b/fs/f2fs/file.c > @@ -1651,6 +1651,8 @@ static int f2fs_ioc_getflags(struct file *filp, > unsigned long arg) > flags |= F2FS_ENCRYPT_FL; > if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) > flags |= F2FS_INLINE_DATA_FL; > + if (is_inode_flag_set(inode, FI_PIN_FILE)) > + flags |= F2FS_PIN_FILE_FL; > > flags &= F2FS_FL_USER_VISIBLE; > > ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 1/2] f2fs: wait on atomic writes to count F2FS_CP_WB_DATA
On 2019/1/4 12:20, Jaegeuk Kim wrote: > Otherwise, we can get wrong counts incurring checkpoint hang. > > IO_W (CP: -24, Data: 24, Flush: ( 001), Discard: ( 00)) > > Cc: > Signed-off-by: Jaegeuk Kim Good catch! ;) I can understand this condition, but for other new developer who reads this commit, it will be a little hard to understand situation here. How about explaining a little more about problem here, maybe: Thread AThread B - f2fs_write_data_pages - __write_data_page - f2fs_submit_page_write - inc_page_count(F2FS_WB_DATA) type is F2FS_WB_DATA due to file is non-atomic one - f2fs_ioc_start_atomic_write - set_inode_flag(FI_ATOMIC_FILE) - f2fs_write_end_io - dec_page_count(F2FS_WB_CP_DATA) type is F2FS_WB_DATA due to file becomes atomic one Reviewed-by: Chao Yu Thanks, ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 2/2] f2fs: don't access node/meta inode mapping after iput
On 2019/1/4 12:20, Jaegeuk Kim wrote: > This fixes wrong access of address spaces of node and meta inodes after iput. > > Fixes: 60aa4d5536ab ("f2fs: fix use-after-free issue when accessing > sbi->stat_info") > Signed-off-by: Jaegeuk Kim Reviewed-by: Chao Yu Thanks, ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] f2fs: check inject_rate validity during configuring
Type of inject_rate is unsigned int, let's check new value's validity during configuring. Signed-off-by: Chao Yu --- fs/f2fs/sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 0575edbe3ed6..02d4012a9183 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -222,6 +222,8 @@ static ssize_t __sbi_store(struct f2fs_attr *a, #ifdef CONFIG_F2FS_FAULT_INJECTION if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX)) return -EINVAL; + if (a->struct_type == FAULT_INFO_RATE && t >= UINT_MAX) + return -EINVAL; #endif if (a->struct_type == RESERVED_BLOCKS) { spin_lock(&sbi->stat_lock); -- 2.18.0.rc1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v2 1/2] f2fs-dev: support multi-device direct IO
From: Qiuyang Sun Changelog v1 ==> v2: 1. Modify the definition of update_device_state(), and call it in direct write; 2. Move some local variables into branches where they are used. Signed-off-by: Qiuyang Sun --- fs/f2fs/data.c| 25 - fs/f2fs/f2fs.h| 3 +-- fs/f2fs/segment.c | 11 +-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e5cd3fd..010300c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1076,6 +1076,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, struct extent_info ei = {0,0,0}; block_t blkaddr; unsigned int start_pgofs; + block_t end_blk; if (!maxblocks) return 0; @@ -1207,8 +1208,17 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, map->m_pblk = blkaddr; map->m_len = 1; + + if (sbi->s_ndevs && blkaddr != NEW_ADDR && + blkaddr != NULL_ADDR) { + int devi; + + devi = f2fs_target_device_index(sbi, blkaddr); + end_blk = FDEV(devi).end_blk; + } } else if ((map->m_pblk != NEW_ADDR && - blkaddr == (map->m_pblk + ofs)) || + blkaddr == (map->m_pblk + ofs) && + (!sbi->s_ndevs || blkaddr <= end_blk)) || (map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) || flag == F2FS_GET_BLOCK_PRE_DIO) { ofs++; @@ -1322,6 +1332,7 @@ static int __get_data_block(struct inode *inode, sector_t iblock, { struct f2fs_map_blocks map; int err; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); map.m_lblk = iblock; map.m_len = bh->b_size >> inode->i_blkbits; @@ -1333,6 +1344,18 @@ static int __get_data_block(struct inode *inode, sector_t iblock, err = f2fs_map_blocks(inode, &map, create, flag); if (!err) { map_bh(bh, inode->i_sb, map.m_pblk); + if (sbi->s_ndevs) { + int devi; + + devi = f2fs_target_device_index(sbi, map.m_pblk); + if (devi) { + bh->b_bdev = FDEV(devi).bdev; + bh->b_blocknr -= FDEV(devi).start_blk; + } + if (may_write) + update_device_state(sbi, inode->i_ino, + map.m_pblk); + } bh->b_state = (bh->b_state & ~F2FS_MAP_FLAGS) | map.m_flags; bh->b_size = (u64)map.m_len << inode->i_blkbits; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index eeede26..659e1e0 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3056,6 +3056,7 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type, int f2fs_rw_hint_to_seg_type(enum rw_hint hint); enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi, enum page_type type, enum temp_type temp); +void update_device_state(struct f2fs_sb_info *sbi, nid_t ino, block_t blkaddr); /* * checkpoint.c @@ -3595,8 +3596,6 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, if (f2fs_post_read_required(inode)) return true; - if (sbi->s_ndevs) - return true; /* * for blkzoned device, fallback direct IO to buffered IO, so * all IOs can be serialized by log-structured write. diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index a361d61..eec5db1 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3050,18 +3050,17 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, up_read(&SM_I(sbi)->curseg_lock); } -static void update_device_state(struct f2fs_io_info *fio) +void update_device_state(struct f2fs_sb_info *sbi, nid_t ino, block_t blkaddr) { - struct f2fs_sb_info *sbi = fio->sbi; unsigned int devidx; if (!sbi->s_ndevs) return; - devidx = f2fs_target_device_index(sbi, fio->new_blkaddr); + devidx = f2fs_target_device_index(sbi, blkaddr); /* update device state for fsync */ - f2fs_set_dirty_device(sbi, fio->ino, devidx, FLUSH_INO); + f2fs_set_dirty_device(sbi, ino, devidx, FLUSH_INO); /* update device state for checkpoint */ if (!f2fs_test_bit(devidx, (char *)&sbi->dirty_device)) { @@ -3092,7 +3091,7 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) goto reallocate; } - update_device_state(fio); + update_device_state(fio->sbi, fio->ino, fio->new_blkaddr); if (keep_order) up_read(&fio->sbi->io_order_lock); @@ -3168,7
[f2fs-dev] [PATCH] f2fs: check if file namelen exceeds max value
Dentry bitmap is not enough to detect incorrect dentries. So this patch also checks the namelen value of a dentry. Signed-off-by: Gong Chen Signed-off-by: Sheng Yong --- fs/f2fs/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index c0c845da12fa..07cfd826f090 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -810,7 +810,8 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, /* check memory boundary before moving forward */ bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); - if (unlikely(bit_pos > d->max)) { + if (unlikely(bit_pos > d->max) || + le16_to_cpu(de->name_len > F2FS_NAME_LEN)) { f2fs_msg(sbi->sb, KERN_WARNING, "%s: corrupted namelen=%d, run fsck to fix.", __func__, le16_to_cpu(de->name_len)); -- 2.17.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] f2fs: no need to check return value of debugfs_create functions
When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Jaegeuk Kim Cc: Chao Yu Cc: linux-f2fs-devel@lists.sourceforge.net Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/debug.c | 20 +++- fs/f2fs/f2fs.h | 4 ++-- fs/f2fs/super.c | 5 + 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index ebcc121920ba..fd7f170e2f2d 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -506,30 +506,16 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi) kvfree(si); } -int __init f2fs_create_root_stats(void) +void __init f2fs_create_root_stats(void) { - struct dentry *file; - f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL); - if (!f2fs_debugfs_root) - return -ENOMEM; - file = debugfs_create_file("status", S_IRUGO, f2fs_debugfs_root, - NULL, &stat_fops); - if (!file) { - debugfs_remove(f2fs_debugfs_root); - f2fs_debugfs_root = NULL; - return -ENOMEM; - } - - return 0; + debugfs_create_file("status", S_IRUGO, f2fs_debugfs_root, NULL, + &stat_fops); } void f2fs_destroy_root_stats(void) { - if (!f2fs_debugfs_root) - return; - debugfs_remove_recursive(f2fs_debugfs_root); f2fs_debugfs_root = NULL; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 12fabd6735dd..8f23ee6e8eb9 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3328,7 +3328,7 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) int f2fs_build_stats(struct f2fs_sb_info *sbi); void f2fs_destroy_stats(struct f2fs_sb_info *sbi); -int __init f2fs_create_root_stats(void); +void __init f2fs_create_root_stats(void); void f2fs_destroy_root_stats(void); #else #define stat_inc_cp_count(si) do { } while (0) @@ -3366,7 +3366,7 @@ void f2fs_destroy_root_stats(void); static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { } -static inline int __init f2fs_create_root_stats(void) { return 0; } +static inline void __init f2fs_create_root_stats(void) { } static inline void f2fs_destroy_root_stats(void) { } #endif diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c46a1d4318d4..3d3ce9eb6d13 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3545,9 +3545,7 @@ static int __init init_f2fs_fs(void) err = register_filesystem(&f2fs_fs_type); if (err) goto free_shrinker; - err = f2fs_create_root_stats(); - if (err) - goto free_filesystem; + f2fs_create_root_stats(); err = f2fs_init_post_read_processing(); if (err) goto free_root_stats; @@ -3555,7 +3553,6 @@ static int __init init_f2fs_fs(void) free_root_stats: f2fs_destroy_root_stats(); -free_filesystem: unregister_filesystem(&f2fs_fs_type); free_shrinker: unregister_shrinker(&f2fs_shrinker_info); -- 2.20.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v2] f2fs: fix sbi->extent_list corruption issue
On 01/04, Sahitya Tummala wrote: > On Mon, Nov 26, 2018 at 10:17:20AM +0530, Sahitya Tummala wrote: > > When there is a failure in f2fs_fill_super() after/during > > the recovery of fsync'd nodes, it frees the current sbi and > > retries again. This time the mount is successful, but the files > > that got recovered before retry, still holds the extent tree, > > whose extent nodes list is corrupted since sbi and sbi->extent_list > > is freed up. The list_del corruption issue is observed when the > > file system is getting unmounted and when those recoverd files extent > > node is being freed up in the below context. > > > > list_del corruption. prev->next should be fff1e1ef5480, but was (null) > > <...> > > kernel BUG at kernel/msm-4.14/lib/list_debug.c:53! > > task: fff1f46f2280 task.stack: ff8008068000 > > lr : __list_del_entry_valid+0x94/0xb4 > > pc : __list_del_entry_valid+0x94/0xb4 > > <...> > > Call trace: > > __list_del_entry_valid+0x94/0xb4 > > __release_extent_node+0xb0/0x114 > > __free_extent_tree+0x58/0x7c > > f2fs_shrink_extent_tree+0xdc/0x3b0 > > f2fs_leave_shrinker+0x28/0x7c > > f2fs_put_super+0xfc/0x1e0 > > generic_shutdown_super+0x70/0xf4 > > kill_block_super+0x2c/0x5c > > kill_f2fs_super+0x44/0x50 > > deactivate_locked_super+0x60/0x8c > > deactivate_super+0x68/0x74 > > cleanup_mnt+0x40/0x78 > > __cleanup_mnt+0x1c/0x28 > > task_work_run+0x48/0xd0 > > do_notify_resume+0x678/0xe98 > > work_pending+0x8/0x14 > > > > Fix this by cleaning up inodes, extent tree and nodes of those > > recovered files before freeing up sbi and before next retry. > > > Hi Jaegeuk, Chao, > > I have observed another scenario where the similar list corruption issue > can happen with sbi->inode_list as well. If recover_fsync_data() > fails at some point in write_checkpoint() due to some error and if > those recovered inodes are still dirty, then after the mount is > successful, this issue is observed when that dirty inode is under > writeback. recover_fsync_data() does iget/iput in pair, and destroy_fsync_dnodes() drops its dirty list and call iput(), when there is an error. So, after then, there'd be no dirty inodes. If there's no error, checkpoint() flushes quota/dentry pages in dirty inodes as well. Can we check where this dirty inode came from? Oh, one sceanrio can be an error by f2fs_disable_checkpoint() which will do GC. > > [ 90.400500] list_del corruption. prev->next should be ffed1f566208, > but was (null) > [ 90.675349] Call trace: > [ 90.677869] __list_del_entry_valid+0x94/0xb4 > [ 90.682351] remove_dirty_inode+0xac/0x114 > [ 90.686563] __f2fs_write_data_pages+0x6a8/0x6c8 > [ 90.691302] f2fs_write_data_pages+0x40/0x4c > [ 90.695695] do_writepages+0x80/0xf0 > [ 90.699372] __writeback_single_inode+0xdc/0x4ac > [ 90.704113] writeback_sb_inodes+0x280/0x440 > [ 90.708501] wb_writeback+0x1b8/0x3d0 > [ 90.712267] wb_workfn+0x1a8/0x4d4 > [ 90.715765] process_one_work+0x1c0/0x3d4 > [ 90.719883] worker_thread+0x224/0x344 > [ 90.723739] kthread+0x120/0x130 > [ 90.727055] ret_from_fork+0x10/0x18 > > I think it is better to cleanup those inodes completely before freeing sbi > and before next retry as done in this patch. Would you like to re-consider > this patch for this new issue? The patch was merged in mainline already. Could you take a look at this patch? >From cb1d20e640402beed300c2bdce79311ee8a781ad Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 4 Jan 2019 12:29:00 -0800 Subject: [PATCH] f2fs: sync filesystem after roll-forward recovery Some works after roll-forward recovery can get an error which will release all the data structures. Let's flush them in order to make it clean. One possible corruption came from: [ 90.400500] list_del corruption. prev->next should be ffed1f566208, but was (null) [ 90.675349] Call trace: [ 90.677869] __list_del_entry_valid+0x94/0xb4 [ 90.682351] remove_dirty_inode+0xac/0x114 [ 90.686563] __f2fs_write_data_pages+0x6a8/0x6c8 [ 90.691302] f2fs_write_data_pages+0x40/0x4c [ 90.695695] do_writepages+0x80/0xf0 [ 90.699372] __writeback_single_inode+0xdc/0x4ac [ 90.704113] writeback_sb_inodes+0x280/0x440 [ 90.708501] wb_writeback+0x1b8/0x3d0 [ 90.712267] wb_workfn+0x1a8/0x4d4 [ 90.715765] process_one_work+0x1c0/0x3d4 [ 90.719883] worker_thread+0x224/0x344 [ 90.723739] kthread+0x120/0x130 [ 90.727055] ret_from_fork+0x10/0x18 Reported-by: Sahitya Tummala Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 547cb7459be7..bb02186293a3 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3357,7 +3357,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) if (test_opt(sbi, DISABLE_CHECKPOINT)) { err = f2fs_disable_checkpoint(sbi); if (err) - goto free_meta; +
Re: [f2fs-dev] [PATCH] f2fs: export pin_file flag to user
On 01/04, Chao Yu wrote: > On 2019/1/4 12:19, Jaegeuk Kim wrote: > > This exports pin_file status to user. > > Semantics of pin_file flag is the same as nocow flag which is more widely > used in lsattr/chattr and vfs now. > > #define FS_NOCOW_FL 0x0080 /* Do not cow file */ > > lsattr/chattr > no copy on write (C) > > How about exporting it via F2FS_NOCOW_FL(0x0080)? Yeah, let me send v2. > > Thanks, > > > > > Signed-off-by: Jaegeuk Kim > > --- > > fs/f2fs/f2fs.h | 3 ++- > > fs/f2fs/file.c | 2 ++ > > 2 files changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index 12fabd6735dd..036fd62010c1 100644 > > --- a/fs/f2fs/f2fs.h > > +++ b/fs/f2fs/f2fs.h > > @@ -2303,9 +2303,10 @@ static inline void f2fs_change_bit(unsigned int nr, > > char *addr) > > #define F2FS_EOFBLOCKS_FL 0x0040 /* Blocks allocated beyond > > EOF */ > > #define F2FS_INLINE_DATA_FL0x1000 /* Inode has inline > > data. */ > > #define F2FS_PROJINHERIT_FL0x2000 /* Create with > > parents projid */ > > +#define F2FS_PIN_FILE_FL 0x4000 /* pin_file status */ > > #define F2FS_RESERVED_FL 0x8000 /* reserved for ext4 lib */ > > > > -#define F2FS_FL_USER_VISIBLE 0x304BDFFF /* User visible > > flags */ > > +#define F2FS_FL_USER_VISIBLE 0x704BDFFF /* User visible > > flags */ > > #define F2FS_FL_USER_MODIFIABLE0x204BC0FF /* User modifiable > > flags */ > > > > /* Flags we can manipulate with through F2FS_IOC_FSSETXATTR */ > > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c > > index ae2b45e75847..eb099f1ee937 100644 > > --- a/fs/f2fs/file.c > > +++ b/fs/f2fs/file.c > > @@ -1651,6 +1651,8 @@ static int f2fs_ioc_getflags(struct file *filp, > > unsigned long arg) > > flags |= F2FS_ENCRYPT_FL; > > if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) > > flags |= F2FS_INLINE_DATA_FL; > > + if (is_inode_flag_set(inode, FI_PIN_FILE)) > > + flags |= F2FS_PIN_FILE_FL; > > > > flags &= F2FS_FL_USER_VISIBLE; > > > > ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 1/2] f2fs: wait on atomic writes to count F2FS_CP_WB_DATA
On 01/04, Chao Yu wrote: > On 2019/1/4 12:20, Jaegeuk Kim wrote: > > Otherwise, we can get wrong counts incurring checkpoint hang. > > > > IO_W (CP: -24, Data: 24, Flush: ( 001), Discard: ( 00)) > > > > Cc: > > Signed-off-by: Jaegeuk Kim > > Good catch! ;) > > I can understand this condition, but for other new developer who reads this > commit, it will be a little hard to understand situation here. > > How about explaining a little more about problem here, maybe: > > Thread A Thread B > - f2fs_write_data_pages > - __write_data_page > - f2fs_submit_page_write >- inc_page_count(F2FS_WB_DATA) > type is F2FS_WB_DATA due to file is non-atomic one > - f2fs_ioc_start_atomic_write > - set_inode_flag(FI_ATOMIC_FILE) > - f2fs_write_end_io >- dec_page_count(F2FS_WB_CP_DATA) > type is F2FS_WB_DATA due to file becomes > atomic one > > Reviewed-by: Chao Yu Thanks, added the comment. :P > > Thanks, > ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v2 01/12] fs-verity: add a documentation file
On Sat, Dec 22, 2018 at 8:46 PM Theodore Y. Ts'o wrote: > > On Sat, Dec 22, 2018 at 08:10:07PM -0800, Matthew Wilcox wrote: > > Pretty much every file format has the ability to put arbitrary blocks > > of information into a file somewhere the tools which don't know about > > it will skip it. For example, ZIP "includes an extra field facility > > within file headers, which can be used to store extra data not defined > > by existing ZIP specifications, and which allow compliant archivers that > > do not recognize the fields to safely skip them. Header IDs 0–31 are > > reserved for use by PKWARE. The remaining IDs can be used by third-party > > vendors for proprietary usage. " (Wikipedia) > > > > ELF, PNG, PDF and many other formats have the ability to put data > > _somewhere_. It might not be at the tail of the file, but there's > > somewhere to do it. > > > > (I appreciate this isn't what Linus is asking for, but I'm pointing out > > that this is by no means as intractable as you make it sound.) > > That design would require the fs-verity code to know the type of eacho > file, and where to find the in-band Merkle tree for each file type > that we wanted to support. And if you wanted to use fs-verity to > protect a sudoers text configuration file (for example), we'd have to > teach sudo how to ignore the userspace visible Merkle tree. I'm pretty late to the game, but I just want to bring up one approach that I'm not sure people have previously considered. You can't put the verification blob in an xattr due to xattr size limits, but you *can* put a filename in an xattr. What if, at open time, fs-verity looked for a specially-named xattr attached to a file, resolved that name like a symlink target, opened the pointed-to file, and just used *that* as the authentication blob? It'd also be possible to teach unlink to delete the pointed-to file when the pointer file is deleted --- sort of like a simple and stupid kind of data fork. For example, if you wanted to secure /usr/bin/emacs, you could set an security.fsverify.verification_file xattr (in the system namespace because the xattr has special semantics) to "/.verification-blobs/@usr@bin@emacs.hashtree" or something like that. Then, open(2) on /usr/bin/emacs would, internally to VFS, also open /.verification-blobs/@usr@bin@emacs.hashtree and read verification data from it, transparently to both users and the underlying filesystem. If someone deleted /usr/bin/emacs, VFS would automatically delete /.verification-blobs/@usr@bin@emacs.hashtree. If /.verification-blobs/@usr@bin@emacs.hashtree didn't exist at time of open(2) of /usr/bin/emacs, or couldn't be opened for whatever reason, the open(2) of /usr/bin/emacs would fail. ISTM that a scheme like this would give you some of the advantages of jumbo xattrs, but with much less implementation complexity. If someone's proposed something like this before, sorry for the noise. ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v2] f2fs: export FS_NOCOW_FL flag to user
This exports pin_file status to user. Signed-off-by: Jaegeuk Kim --- v2: - use F2FS_NOCOW_FL (aka FS_NOCOW_FL) fs/f2fs/f2fs.h | 3 ++- fs/f2fs/file.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 12fabd6735dd..9286ec381453 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2301,11 +2301,12 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) #define F2FS_EXTENTS_FL0x0008 /* Inode uses extents */ #define F2FS_EA_INODE_FL 0x0020 /* Inode used for large EA */ #define F2FS_EOFBLOCKS_FL 0x0040 /* Blocks allocated beyond EOF */ +#define F2FS_NOCOW_FL 0x0080 /* Do not cow file */ #define F2FS_INLINE_DATA_FL0x1000 /* Inode has inline data. */ #define F2FS_PROJINHERIT_FL0x2000 /* Create with parents projid */ #define F2FS_RESERVED_FL 0x8000 /* reserved for ext4 lib */ -#define F2FS_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */ +#define F2FS_FL_USER_VISIBLE 0x30CBDFFF /* User visible flags */ #define F2FS_FL_USER_MODIFIABLE0x204BC0FF /* User modifiable flags */ /* Flags we can manipulate with through F2FS_IOC_FSSETXATTR */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index ae2b45e75847..0d461321edfc 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1651,6 +1651,8 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg) flags |= F2FS_ENCRYPT_FL; if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) flags |= F2FS_INLINE_DATA_FL; + if (is_inode_flag_set(inode, FI_PIN_FILE)) + flags |= F2FS_NOCOW_FL; flags &= F2FS_FL_USER_VISIBLE; -- 2.19.0.605.g01d371f741-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel