ext4: release bh in make_indexed_dir
authorgmail <yngsion@gmail.com>
Fri, 30 Sep 2016 05:33:37 +0000 (01:33 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Oct 2016 10:26:56 +0000 (12:26 +0200)
commit e81d44778d1d57bbaef9e24c4eac7c8a7a401d40 upstream.

The commit 6050d47adcad: "ext4: bail out from make_indexed_dir() on
first error" could end up leaking bh2 in the error path.

[ Also avoid renaming bh2 to bh, which just confuses things --tytso ]

Signed-off-by: yangsheng <yngsion@gmail.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ext4/namei.c

index 38eb0c8e43b906d23e2d290a23098583f6d1a193..573b4cbb0cb991e1c60dd12d88d7c3c05d9a0120 100644 (file)
@@ -2017,33 +2017,31 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
        frame->entries = entries;
        frame->at = entries;
        frame->bh = bh;
-       bh = bh2;
 
        retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
        if (retval)
                goto out_frames;        
-       retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
+       retval = ext4_handle_dirty_dirent_node(handle, dir, bh2);
        if (retval)
                goto out_frames;        
 
-       de = do_split(handle,dir, &bh, frame, &fname->hinfo);
+       de = do_split(handle,dir, &bh2, frame, &fname->hinfo);
        if (IS_ERR(de)) {
                retval = PTR_ERR(de);
                goto out_frames;
        }
-       dx_release(frames);
 
-       retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh);
-       brelse(bh);
-       return retval;
+       retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh2);
 out_frames:
        /*
         * Even if the block split failed, we have to properly write
         * out all the changes we did so far. Otherwise we can end up
         * with corrupted filesystem.
         */
-       ext4_mark_inode_dirty(handle, dir);
+       if (retval)
+               ext4_mark_inode_dirty(handle, dir);
        dx_release(frames);
+       brelse(bh2);
        return retval;
 }