diff options
Diffstat (limited to 'fs/ext4/extents_status.c')
| -rw-r--r-- | fs/ext4/extents_status.c | 44 | 
1 files changed, 30 insertions, 14 deletions
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 9b5b8951afb4..6f7de14c0fa8 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -878,23 +878,29 @@ retry:  	err1 = __es_remove_extent(inode, lblk, end, NULL, es1);  	if (err1 != 0)  		goto error; +	/* Free preallocated extent if it didn't get used. */ +	if (es1) { +		if (!es1->es_len) +			__es_free_extent(es1); +		es1 = NULL; +	}  	err2 = __es_insert_extent(inode, &newes, es2);  	if (err2 == -ENOMEM && !ext4_es_must_keep(&newes))  		err2 = 0;  	if (err2 != 0)  		goto error; +	/* Free preallocated extent if it didn't get used. */ +	if (es2) { +		if (!es2->es_len) +			__es_free_extent(es2); +		es2 = NULL; +	}  	if (sbi->s_cluster_ratio > 1 && test_opt(inode->i_sb, DELALLOC) &&  	    (status & EXTENT_STATUS_WRITTEN ||  	     status & EXTENT_STATUS_UNWRITTEN))  		__revise_pending(inode, lblk, len); - -	/* es is pre-allocated but not used, free it. */ -	if (es1 && !es1->es_len) -		__es_free_extent(es1); -	if (es2 && !es2->es_len) -		__es_free_extent(es2);  error:  	write_unlock(&EXT4_I(inode)->i_es_lock);  	if (err1 || err2) @@ -1491,8 +1497,12 @@ retry:  	 */  	write_lock(&EXT4_I(inode)->i_es_lock);  	err = __es_remove_extent(inode, lblk, end, &reserved, es); -	if (es && !es->es_len) -		__es_free_extent(es); +	/* Free preallocated extent if it didn't get used. */ +	if (es) { +		if (!es->es_len) +			__es_free_extent(es); +		es = NULL; +	}  	write_unlock(&EXT4_I(inode)->i_es_lock);  	if (err)  		goto retry; @@ -2047,19 +2057,25 @@ retry:  	err1 = __es_remove_extent(inode, lblk, lblk, NULL, es1);  	if (err1 != 0)  		goto error; +	/* Free preallocated extent if it didn't get used. */ +	if (es1) { +		if (!es1->es_len) +			__es_free_extent(es1); +		es1 = NULL; +	}  	err2 = __es_insert_extent(inode, &newes, es2);  	if (err2 != 0)  		goto error; +	/* Free preallocated extent if it didn't get used. */ +	if (es2) { +		if (!es2->es_len) +			__es_free_extent(es2); +		es2 = NULL; +	}  	if (allocated)  		__insert_pending(inode, lblk); - -	/* es is pre-allocated but not used, free it. */ -	if (es1 && !es1->es_len) -		__es_free_extent(es1); -	if (es2 && !es2->es_len) -		__es_free_extent(es2);  error:  	write_unlock(&EXT4_I(inode)->i_es_lock);  	if (err1 || err2)  |