]> 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>
Fri, 5 Apr 2019 20:29:04 +0000 (22:29 +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 14007e621d2a18a01e200e385cf6eca917369b6a..d2844fe9040dde42ab90d1fe1665c0fdd27c3284 100644 (file)
@@ -1217,6 +1217,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;
@@ -1258,7 +1259,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 */
@@ -1283,13 +1284,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) {
                                /*
@@ -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;
 }