]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ext4: cleanup bh release code in ext4_ind_remove_space()
authorzhangyi (F) <yi.zhang@huawei.com>
Sat, 23 Mar 2019 15:56:01 +0000 (11:56 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 Apr 2019 07:30:19 +0000 (09:30 +0200)
commit 5e86bdda41534e17621d5a071b294943cae4376e upstream.

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) <yi.zhang@huawei.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: Jari Ruusu <jari.ruusu@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ext4/indirect.c

index b6e262b86566259df42ceb780a2810bbe5d7034d..e0690ba577562d4b2b6b6c7f02f3e12b67560316 100644 (file)
@@ -1312,6 +1312,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
        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;
@@ -1353,7 +1354,7 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
                }
 
 
-               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 */
@@ -1378,13 +1379,11 @@ int ext4_ind_remove_space(handle_t *handle, struct inode *inode,
                                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) {
                                /*
@@ -1414,16 +1413,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) {
@@ -1480,15 +1477,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;
                }
 
                /*
@@ -1503,8 +1492,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) {
@@ -1512,11 +1499,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:
@@ -1524,7 +1521,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);
@@ -1532,7 +1529,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);
@@ -1540,7 +1537,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);
@@ -1549,5 +1546,5 @@ do_indirects:
        case EXT4_TIND_BLOCK:
                ;
        }
-       return 0;
+       goto cleanup;
 }