• Theodore Ts'o's avatar
    ext4: teach ext4_ext_find_extent() to free path on error · 705912ca
    Theodore Ts'o authored
    Right now, there are a places where it is all to easy to leak memory
    on an error path, via a usage like this:
    
    	struct ext4_ext_path *path = NULL
    
    	while (...) {
    		...
    		path = ext4_ext_find_extent(inode, block, path, 0);
    		if (IS_ERR(path)) {
    			/* oops, if path was non-NULL before the call to
    			   ext4_ext_find_extent, we've leaked it!  :-(  */
    			...
    			return PTR_ERR(path);
    		}
    		...
    	}
    
    Unfortunately, there some code paths where we are doing the following
    instead:
    
    	path = ext4_ext_find_extent(inode, block, orig_path, 0);
    
    and where it's important that we _not_ free orig_path in the case
    where ext4_ext_find_extent() returns an error.
    
    So change the function signature of ext4_ext_find_extent() so that it
    takes a struct ext4_ext_path ** for its third argument, and by
    default, on an error, it will free the struct ext4_ext_path, and then
    zero out the struct ext4_ext_path * pointer.  In order to avoid
    causing problems, we add a flag EXT4_EX_NOFREE_ON_ERR which causes
    ext4_ext_find_extent() to use the original behavior of forcing the
    caller to deal with freeing the original path pointer on the error
    case.
    
    The goal is to get rid of EXT4_EX_NOFREE_ON_ERR entirely, but this
    allows for a gentle transition and makes the patches easier to verify.
    Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    
    		
    705912ca
move_extent.c 22.8 KB