summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/node.c
diff options
context:
space:
mode:
authorLiFan <fanofcode.li@samsung.com>2017-11-10 15:41:42 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2017-11-10 17:35:07 -0800
commit0dd99ca76f473d488fa9acac67f6a42ca1d7d2b1 (patch)
tree12e9e5ed429bbf978ea1306490623c2e2cf194d8 /fs/f2fs/node.c
parent19526d74cfbe31b04fb81b64c2884687a321f4a0 (diff)
downloadlinux-stable-0dd99ca76f473d488fa9acac67f6a42ca1d7d2b1.tar.gz
linux-stable-0dd99ca76f473d488fa9acac67f6a42ca1d7d2b1.tar.bz2
linux-stable-0dd99ca76f473d488fa9acac67f6a42ca1d7d2b1.zip
f2fs: validate before set/clear free nat bitmap
In flush_nat_entries, all dirty nats will be flushed and if their new address isn't NULL_ADDR, their bitmaps will be updated, the free_nid_count of the bitmaps will be increaced regardless of whether the nats have already been occupied before. This could lead to wrong free_nid_count. So this patch checks the status of the bits beforeactually set/clear them. Fixes: 586d1492f301 ("f2fs: skip scanning free nid bitmap of full NAT blocks") Signed-off-by: Fan li <fanofcode.li@samsung.com> Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r--fs/f2fs/node.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index d2530179cc9c..9abfdbb5aae5 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1906,15 +1906,18 @@ static void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid,
if (!test_bit_le(nat_ofs, nm_i->nat_block_bitmap))
return;
- if (set)
+ if (set) {
+ if (test_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]))
+ return;
__set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
- else
- __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
-
- if (set)
nm_i->free_nid_count[nat_ofs]++;
- else if (!build)
- nm_i->free_nid_count[nat_ofs]--;
+ } else {
+ if (!test_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]))
+ return;
+ __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
+ if (!build)
+ nm_i->free_nid_count[nat_ofs]--;
+ }
}
static void scan_nat_page(struct f2fs_sb_info *sbi,