From 85c41564e973e9646278bbcfb81ef881d1f109bb Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Apr 09 2019 13:29:32 +0000 Subject: ext4: cleanup bh release code in ext4_ind_remove_space() (bsc#1131851). Conflicts: series.conf --- diff --git a/patches.fixes/ext4-cleanup-bh-release-code-in-ext4_ind_remove_spac.patch b/patches.fixes/ext4-cleanup-bh-release-code-in-ext4_ind_remove_spac.patch new file mode 100644 index 0000000..46dd7d5 --- /dev/null +++ b/patches.fixes/ext4-cleanup-bh-release-code-in-ext4_ind_remove_spac.patch @@ -0,0 +1,161 @@ +From 5e86bdda41534e17621d5a071b294943cae4376e Mon Sep 17 00:00:00 2001 +From: "zhangyi (F)" +Date: Sat, 23 Mar 2019 11:56:01 -0400 +Subject: [PATCH] ext4: cleanup bh release code in ext4_ind_remove_space() +Git-commit: 5e86bdda41534e17621d5a071b294943cae4376e +Patch-mainline: v5.1-rc2 +References: bsc#1131851 + +Currently, we are releasing the indirect buffer where we are done with +it in ext4_ind_remove_space(), so we can see the brelse() and +BUFFER_TRACE() everywhere. It seems fragile and hard to read, and we +may probably forget to release the buffer some day. This patch cleans +up the code by putting of the code which releases the buffers to the +end of the function. + +Signed-off-by: zhangyi (F) +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Acked-by: Jan Kara + +--- + fs/ext4/indirect.c | 47 ++++++++++++++++++++++------------------------- + 1 file changed, 22 insertions(+), 25 deletions(-) + +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -1217,6 +1217,7 @@ int ext4_ind_remove_space(handle_t *hand + ext4_lblk_t offsets[4], offsets2[4]; + Indirect chain[4], chain2[4]; + Indirect *partial, *partial2; ++ Indirect *p = NULL, *p2 = NULL; + ext4_lblk_t max_block; + __le32 nr = 0, nr2 = 0; + int n = 0, n2 = 0; +@@ -1258,7 +1259,7 @@ int ext4_ind_remove_space(handle_t *hand + } + + +- partial = ext4_find_shared(inode, n, offsets, chain, &nr); ++ partial = p = ext4_find_shared(inode, n, offsets, chain, &nr); + if (nr) { + if (partial == chain) { + /* Shared branch grows from the inode */ +@@ -1283,13 +1284,11 @@ int ext4_ind_remove_space(handle_t *hand + partial->p + 1, + (__le32 *)partial->bh->b_data+addr_per_block, + (chain+n-1) - partial); +- BUFFER_TRACE(partial->bh, "call brelse"); +- brelse(partial->bh); + partial--; + } + + end_range: +- partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); ++ partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); + if (nr2) { + if (partial2 == chain2) { + /* +@@ -1319,16 +1318,14 @@ end_range: + (__le32 *)partial2->bh->b_data, + partial2->p, + (chain2+n2-1) - partial2); +- BUFFER_TRACE(partial2->bh, "call brelse"); +- brelse(partial2->bh); + partial2--; + } + goto do_indirects; + } + + /* Punch happened within the same level (n == n2) */ +- partial = ext4_find_shared(inode, n, offsets, chain, &nr); +- partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); ++ partial = p = ext4_find_shared(inode, n, offsets, chain, &nr); ++ partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); + + /* Free top, but only if partial2 isn't its subtree. */ + if (nr) { +@@ -1385,15 +1382,7 @@ end_range: + partial->p + 1, + partial2->p, + (chain+n-1) - partial); +- while (partial > chain) { +- BUFFER_TRACE(partial->bh, "call brelse"); +- brelse(partial->bh); +- } +- while (partial2 > chain2) { +- BUFFER_TRACE(partial2->bh, "call brelse"); +- brelse(partial2->bh); +- } +- return 0; ++ goto cleanup; + } + + /* +@@ -1408,8 +1397,6 @@ end_range: + partial->p + 1, + (__le32 *)partial->bh->b_data+addr_per_block, + (chain+n-1) - partial); +- BUFFER_TRACE(partial->bh, "call brelse"); +- brelse(partial->bh); + partial--; + } + if (partial2 > chain2 && depth2 <= depth) { +@@ -1417,11 +1404,21 @@ end_range: + (__le32 *)partial2->bh->b_data, + partial2->p, + (chain2+n2-1) - partial2); +- BUFFER_TRACE(partial2->bh, "call brelse"); +- brelse(partial2->bh); + partial2--; + } + } ++ ++cleanup: ++ while (p && p > chain) { ++ BUFFER_TRACE(p->bh, "call brelse"); ++ brelse(p->bh); ++ p--; ++ } ++ while (p2 && p2 > chain2) { ++ BUFFER_TRACE(p2->bh, "call brelse"); ++ brelse(p2->bh); ++ p2--; ++ } + return 0; + + do_indirects: +@@ -1429,7 +1426,7 @@ do_indirects: + switch (offsets[0]) { + default: + if (++n >= n2) +- return 0; ++ break; + nr = i_data[EXT4_IND_BLOCK]; + if (nr) { + ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1); +@@ -1437,7 +1434,7 @@ do_indirects: + } + case EXT4_IND_BLOCK: + if (++n >= n2) +- return 0; ++ break; + nr = i_data[EXT4_DIND_BLOCK]; + if (nr) { + ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2); +@@ -1445,7 +1442,7 @@ do_indirects: + } + case EXT4_DIND_BLOCK: + if (++n >= n2) +- return 0; ++ break; + nr = i_data[EXT4_TIND_BLOCK]; + if (nr) { + ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3); +@@ -1454,5 +1451,5 @@ do_indirects: + case EXT4_TIND_BLOCK: + ; + } +- return 0; ++ goto cleanup; + } diff --git a/series.conf b/series.conf index b071ca7..6db5f3e 100644 --- a/series.conf +++ b/series.conf @@ -44858,6 +44858,7 @@ patches.fixes/ext4-fix-data-corruption-caused-by-unaligned-direct-.patch patches.fixes/ext4-add-missing-brelse-in-add_new_gdb_meta_bg.patch patches.fixes/ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_s.patch + patches.fixes/ext4-cleanup-bh-release-code-in-ext4_ind_remove_spac.patch patches.suse/xsk-fix-umem-memory-leak-on-cleanup.patch patches.drivers/mISDN-hfcpci-Test-both-vendor-device-ID-for-Digium-H.patch patches.fixes/rhashtable-Still-do-rehash-when-we-get-EEXIST.patch