Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ext4: fix memory leakage in mext_check_coverage

Regression was introduced by following commit 8c854473
TESTCASE (git://oss.sgi.com/xfs/cmds/xfstests.git):
#while true;do ./check 301 || break ;done

Also fix potential memory leakage in get_ext_path() once
ext4_ext_find_extent() have failed.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>

authored by

Dmitry Monakhov and committed by
Theodore Ts'o
0e401101 4f42f80a

+19 -16
+19 -16
fs/ext4/move_extent.c
··· 32 32 */ 33 33 static inline int 34 34 get_ext_path(struct inode *inode, ext4_lblk_t lblock, 35 - struct ext4_ext_path **path) 35 + struct ext4_ext_path **orig_path) 36 36 { 37 37 int ret = 0; 38 + struct ext4_ext_path *path; 38 39 39 - *path = ext4_ext_find_extent(inode, lblock, *path); 40 - if (IS_ERR(*path)) { 41 - ret = PTR_ERR(*path); 42 - *path = NULL; 43 - } else if ((*path)[ext_depth(inode)].p_ext == NULL) 40 + path = ext4_ext_find_extent(inode, lblock, *orig_path); 41 + if (IS_ERR(path)) 42 + ret = PTR_ERR(path); 43 + else if (path[ext_depth(inode)].p_ext == NULL) 44 44 ret = -ENODATA; 45 + else 46 + *orig_path = path; 45 47 46 48 return ret; 47 49 } ··· 613 611 { 614 612 struct ext4_ext_path *path = NULL; 615 613 struct ext4_extent *ext; 614 + int ret = 0; 616 615 ext4_lblk_t last = from + count; 617 616 while (from < last) { 618 617 *err = get_ext_path(inode, from, &path); 619 618 if (*err) 620 - return 0; 619 + goto out; 621 620 ext = path[ext_depth(inode)].p_ext; 622 - if (!ext) { 623 - ext4_ext_drop_refs(path); 624 - return 0; 625 - } 626 - if (uninit != ext4_ext_is_uninitialized(ext)) { 627 - ext4_ext_drop_refs(path); 628 - return 0; 629 - } 621 + if (uninit != ext4_ext_is_uninitialized(ext)) 622 + goto out; 630 623 from += ext4_ext_get_actual_len(ext); 631 624 ext4_ext_drop_refs(path); 632 625 } 633 - return 1; 626 + ret = 1; 627 + out: 628 + if (path) { 629 + ext4_ext_drop_refs(path); 630 + kfree(path); 631 + } 632 + return ret; 634 633 } 635 634 636 635 /**