Skip to contentSkip to conversation

ext4: fix end of region partial cluster handling

PATCH In review Eric Whitney 2 participants 3 messages Nov 21, 2014 – Nov 23, 2014 ext4 file system

lore
Share & tools
lore
#0 lore raw

PATCH 4/4 ext4: fix end of region partial cluster handling

ext4_ext_remove_space() can incorrectly free a partial_cluster if EAGAIN is encountered while truncating or punching. Extent removal should be retried in this case.

It also fails to free a partial cluster when the punched region begins at the start of a file on that unaligned cluster and where the entire file has not been punched. Remove the requirement that all blocks in the file must have been freed in order to free the partial cluster.

---
 fs/ext4/extents.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
fs/ext4/extents.c +2 -4
index 841adf0..9eae2f4 100644
@@ -3009,16 +3009,18 @@ again:
 	trace_ext4_ext_remove_space_done(inode, start, end, depth,
 			partial_cluster, path->p_hdr->eh_entries);
 
-	/* If we still have something in the partial cluster and we have removed
+	/*
+	 * If we still have something in the partial cluster and we have removed
 	 * even the first extent, then we should free the blocks in the partial
-	 * cluster as well. */
-	if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) {
-		int flags = get_default_free_blocks_flags(inode);
maintainer
#1 lore raw
Quoted 3 lines · Eric Whitney

ext4_ext_remove_space() can incorrectly free a partial_cluster if EAGAIN is encountered while truncating or punching. Extent removal should be retried in this case.

I don't see anything in the patch below which retries the extent removal; am I missing something?

Thanks,

- Ted

#2 lore raw

The retry occurs at the end of ext4_ext_remove_space where the code loops back to the top of the function if err == -EAGAIN, leading to another call to ext4_ext_rm_leaf. Nothing new needs to be added - we simply want to avoid using invalid state to decide whether to free a partial cluster (on occurrence of -EAGAIN), and the existing retry loop will eventually get us valid state.

(I actually saw this in testing, but it takes a lot of runs to get there.)

Sorry if I edited down my comment a little too far - I'd be happy to beef that up if desired.

Thanks,
Eric

* Theodore Ts'o <[email protected]>:

Quoted 11 lines · Eric Whitney
Quoted 3 lines

ext4_ext_remove_space() can incorrectly free a partial_cluster if EAGAIN is encountered while truncating or punching. Extent removal should be retried in this case.

I don't see anything in the patch below which retries the extent removal; am I missing something?

Thanks,

- Ted