Skip to content

Commit

Permalink
f2fs: initialize locks earlier in f2fs_fill_super()
Browse files Browse the repository at this point in the history
commit 92b4cf5 upstream.

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+40642be9b7e0bb28e0df@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Tested-by: syzbot <syzbot+40642be9b7e0bb28e0df@syzkaller.appspotmail.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tetsuo Handa authored and gregkh committed Feb 9, 2023
1 parent 07a9697 commit ddeff03
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions fs/f2fs/super.c
Expand Up @@ -4095,6 +4095,24 @@ 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)) {
Expand All @@ -4118,6 +4136,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_fs_info = sbi;
sbi->raw_super = raw_super;

memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);

/* precompute checksum seed for metadata */
if (f2fs_sb_has_inode_chksum(sbi))
sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid,
Expand Down Expand Up @@ -4174,26 +4194,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;

spin_lock_init(&sbi->error_lock);
memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);

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);
Expand Down Expand Up @@ -4271,12 +4279,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);
Expand Down

0 comments on commit ddeff03

Please sign in to comment.