f2fs: fix race condition in between free nid allocator/initializer
authorChao Yu <yuchao0@huawei.com>
Wed, 22 Mar 2017 06:45:05 +0000 (14:45 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Dec 2018 12:05:13 +0000 (13:05 +0100)
commitcb9b1d4ec206702a4df1cb42ba8142f39acfdd91
treef553d647824d6885cc4d78d47f05139f3d13d219
parent3b19f961d260d1ae12b497e5eb77e5ecc1039fac
f2fs: fix race condition in between free nid allocator/initializer

commit 30a61ddf8117c26ac5b295e1233eaa9629a94ca3 upstream.

In below concurrent case, allocated nid can be loaded into free nid cache
and be allocated again.

Thread A Thread B
- f2fs_create
 - f2fs_new_inode
  - alloc_nid
   - __insert_nid_to_list(ALLOC_NID_LIST)
- f2fs_balance_fs_bg
 - build_free_nids
  - __build_free_nids
   - scan_nat_page
    - add_free_nid
     - __lookup_nat_cache
 - f2fs_add_link
  - init_inode_metadata
   - new_inode_page
    - new_node_page
     - set_node_addr
 - alloc_nid_done
  - __remove_nid_from_list(ALLOC_NID_LIST)
     - __insert_nid_to_list(FREE_NID_LIST)

This patch makes nat cache lookup and free nid list operation being atomical
to avoid this race condition.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[bwh: Backported to 4.9:
 - add_free_nid() returns 0 in case of any error (except low memory)
 - Tree/list addition has not been moved into __insert_nid_to_list()]
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/f2fs/node.c