Commit 0e401101 authored by Dmitry Monakhov's avatar Dmitry Monakhov Committed by Theodore Ts'o

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: default avatarDmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 4f42f80a
...@@ -32,16 +32,18 @@ ...@@ -32,16 +32,18 @@
*/ */
static inline int static inline int
get_ext_path(struct inode *inode, ext4_lblk_t lblock, get_ext_path(struct inode *inode, ext4_lblk_t lblock,
struct ext4_ext_path **path) struct ext4_ext_path **orig_path)
{ {
int ret = 0; int ret = 0;
struct ext4_ext_path *path;
*path = ext4_ext_find_extent(inode, lblock, *path); path = ext4_ext_find_extent(inode, lblock, *orig_path);
if (IS_ERR(*path)) { if (IS_ERR(path))
ret = PTR_ERR(*path); ret = PTR_ERR(path);
*path = NULL; else if (path[ext_depth(inode)].p_ext == NULL)
} else if ((*path)[ext_depth(inode)].p_ext == NULL)
ret = -ENODATA; ret = -ENODATA;
else
*orig_path = path;
return ret; return ret;
} }
...@@ -611,24 +613,25 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count, ...@@ -611,24 +613,25 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
{ {
struct ext4_ext_path *path = NULL; struct ext4_ext_path *path = NULL;
struct ext4_extent *ext; struct ext4_extent *ext;
int ret = 0;
ext4_lblk_t last = from + count; ext4_lblk_t last = from + count;
while (from < last) { while (from < last) {
*err = get_ext_path(inode, from, &path); *err = get_ext_path(inode, from, &path);
if (*err) if (*err)
return 0; goto out;
ext = path[ext_depth(inode)].p_ext; ext = path[ext_depth(inode)].p_ext;
if (!ext) { if (uninit != ext4_ext_is_uninitialized(ext))
ext4_ext_drop_refs(path); goto out;
return 0;
}
if (uninit != ext4_ext_is_uninitialized(ext)) {
ext4_ext_drop_refs(path);
return 0;
}
from += ext4_ext_get_actual_len(ext); from += ext4_ext_get_actual_len(ext);
ext4_ext_drop_refs(path); ext4_ext_drop_refs(path);
} }
return 1; ret = 1;
out:
if (path) {
ext4_ext_drop_refs(path);
kfree(path);
}
return ret;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment