diff options
| author | Dmitry Monakhov <dmonakhov@openvz.org> | 2013-03-18 11:40:19 -0400 | 
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2013-03-18 11:40:19 -0400 | 
| commit | 0e401101db49959f5783f6ee9e676124b5a183ac (patch) | |
| tree | 2fb6d2f9b21c60edbda1e0827fe725e50ac16c4d | |
| parent | 4f42f80a8f08d4c3f52c4267361241885d5dee3a (diff) | |
| download | olio-linux-3.10-0e401101db49959f5783f6ee9e676124b5a183ac.tar.xz olio-linux-3.10-0e401101db49959f5783f6ee9e676124b5a183ac.zip  | |
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>
| -rw-r--r-- | fs/ext4/move_extent.c | 35 | 
1 files changed, 19 insertions, 16 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index c1f15b203e9..bbae4ed15c3 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -32,16 +32,18 @@   */  static inline int  get_ext_path(struct inode *inode, ext4_lblk_t lblock, -		struct ext4_ext_path **path) +		struct ext4_ext_path **orig_path)  {  	int ret = 0; +	struct ext4_ext_path *path; -	*path = ext4_ext_find_extent(inode, lblock, *path); -	if (IS_ERR(*path)) { -		ret = PTR_ERR(*path); -		*path = NULL; -	} else if ((*path)[ext_depth(inode)].p_ext == NULL) +	path = ext4_ext_find_extent(inode, lblock, *orig_path); +	if (IS_ERR(path)) +		ret = PTR_ERR(path); +	else if (path[ext_depth(inode)].p_ext == NULL)  		ret = -ENODATA; +	else +		*orig_path = path;  	return ret;  } @@ -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_extent *ext; +	int ret = 0;  	ext4_lblk_t last = from + count;  	while (from < last) {  		*err = get_ext_path(inode, from, &path);  		if (*err) -			return 0; +			goto out;  		ext = path[ext_depth(inode)].p_ext; -		if (!ext) { -			ext4_ext_drop_refs(path); -			return 0; -		} -		if (uninit != ext4_ext_is_uninitialized(ext)) { -			ext4_ext_drop_refs(path); -			return 0; -		} +		if (uninit != ext4_ext_is_uninitialized(ext)) +			goto out;  		from += ext4_ext_get_actual_len(ext);  		ext4_ext_drop_refs(path);  	} -	return 1; +	ret = 1; +out: +	if (path) { +		ext4_ext_drop_refs(path); +		kfree(path); +	} +	return ret;  }  /**  |