syzbot is reporting lockdep warning at f2fs_handle_error() [1], for
spin_lock(&sbi->error_lock) is called before spin_lock_init() is called.
For safe locking in error handling, move initialization of locks (and
obvious structures) in f2fs_fill_super() to immediately after memory
allocation.

Link: https://syzkaller.appspot.com/bug?extid=40642be9b7e0bb28e0df [1]
Reported-by: syzbot <syzbot+40642be9b7e0bb28e...@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-ker...@i-love.sakura.ne.jp>
Tested-by: syzbot <syzbot+40642be9b7e0bb28e...@syzkaller.appspotmail.com>
---
 fs/f2fs/super.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 3834ead04620..8df94d287a36 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4095,6 +4095,23 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
 
        sbi->sb = sb;
 
+       /* initialize locks within allocated memory */
+       init_f2fs_rwsem(&sbi->gc_lock);
+       mutex_init(&sbi->writepages);
+       init_f2fs_rwsem(&sbi->cp_global_sem);
+       init_f2fs_rwsem(&sbi->node_write);
+       init_f2fs_rwsem(&sbi->node_change);
+       spin_lock_init(&sbi->stat_lock);
+       init_f2fs_rwsem(&sbi->cp_rwsem);
+       init_f2fs_rwsem(&sbi->quota_sem);
+       init_waitqueue_head(&sbi->cp_wait);
+       spin_lock_init(&sbi->error_lock);
+       for (i = 0; i < NR_INODE_TYPE; i++) {
+               INIT_LIST_HEAD(&sbi->inode_list[i]);
+               spin_lock_init(&sbi->inode_lock[i]);
+       }
+       mutex_init(&sbi->flush_lock);
+
        /* Load the checksum driver */
        sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0);
        if (IS_ERR(sbi->s_chksum_driver)) {
@@ -4174,23 +4191,14 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
 
        /* init f2fs-specific super block info */
        sbi->valid_super_block = valid_super_block;
-       init_f2fs_rwsem(&sbi->gc_lock);
-       mutex_init(&sbi->writepages);
-       init_f2fs_rwsem(&sbi->cp_global_sem);
-       init_f2fs_rwsem(&sbi->node_write);
-       init_f2fs_rwsem(&sbi->node_change);
 
        /* disallow all the data/node/meta page writes */
        set_sbi_flag(sbi, SBI_POR_DOING);
-       spin_lock_init(&sbi->stat_lock);
 
        err = f2fs_init_write_merge_io(sbi);
        if (err)
                goto free_bio_info;
 
-       init_f2fs_rwsem(&sbi->cp_rwsem);
-       init_f2fs_rwsem(&sbi->quota_sem);
-       init_waitqueue_head(&sbi->cp_wait);
        init_sb_info(sbi);
 
        err = f2fs_init_iostat(sbi);
@@ -4255,7 +4263,6 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
                goto free_devices;
        }
 
-       spin_lock_init(&sbi->error_lock);
        memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);
 
        sbi->total_valid_node_count =
@@ -4271,12 +4278,6 @@ static int f2fs_fill_super(struct super_block *sb, void 
*data, int silent)
        limit_reserve_root(sbi);
        adjust_unusable_cap_perc(sbi);
 
-       for (i = 0; i < NR_INODE_TYPE; i++) {
-               INIT_LIST_HEAD(&sbi->inode_list[i]);
-               spin_lock_init(&sbi->inode_lock[i]);
-       }
-       mutex_init(&sbi->flush_lock);
-
        f2fs_init_extent_cache_info(sbi);
 
        f2fs_init_ino_entry_info(sbi);
-- 
2.18.4



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to