[3.8.y.z extended stable] Patch "ext4: fix premature freeing of partial clusters split across leaf blocks" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Fri Apr 18 17:23:27 UTC 2014
On Thu, 2014-04-17 at 16:30 -0700, Kamal Mostafa wrote:
> This is a note to let you know that I have just added a patch titled
>
> ext4: fix premature freeing of partial clusters split across leaf blocks
>
> to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree
This patch won't cleanly apply to 3.8 without a prerequisite that has
now been dropped from the queue (ext4: make punch hole code path work
with bigalloc).
So this patch (ext4: fix premature freeing) will also be dropped from
the 3.8-stable queue, unless one of the ext4 folks would like to provide
a backport which applies to 3.8-stable's fs/ext4/extents.c[0], or advice
about what that "if partial_cluster" line should look like when all is
said and done.
Thanks,
-Kamal
[0] http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=blob;f=fs/ext4/extents.c;h=8b5c2646786fbe10cb559d8636544350cad9274c;hb=refs/heads/linux-3.8.y-queue#l2614
> which can be found at:
>
> http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue
>
> This patch is scheduled to be released in version 3.8.13.22.
>
> If you, or anyone else, feels it should not be added to this tree, please
> reply to this email.
>
> For more information about the 3.8.y.z tree, see
> https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
>
> Thanks.
> -Kamal
>
> ------
>
> From bbc128e90ae5c1af34a25d40cdda91038fde3468 Mon Sep 17 00:00:00 2001
> From: Eric Whitney <enwlinux at gmail.com>
> Date: Tue, 1 Apr 2014 19:49:30 -0400
> Subject: ext4: fix premature freeing of partial clusters split across leaf
> blocks
>
> commit ad6599ab3ac98a4474544086e048ce86ec15a4d1 upstream.
>
> Xfstests generic/311 and shared/298 fail when run on a bigalloc file
> system. Kernel error messages produced during the tests report that
> blocks to be freed are already on the to-be-freed list. When e2fsck
> is run at the end of the tests, it typically reports bad i_blocks and
> bad free blocks counts.
>
> The bug that causes these failures is located in ext4_ext_rm_leaf().
> Code at the end of the function frees a partial cluster if it's not
> shared with an extent remaining in the leaf. However, if all the
> extents in the leaf have been removed, the code dereferences an
> invalid extent pointer (off the front of the leaf) when the check for
> sharing is made. This generally has the effect of unconditionally
> freeing the partial cluster, which leads to the observed failures
> when the partial cluster is shared with the last extent in the next
> leaf.
>
> Fix this by attempting to free the cluster only if extents remain in
> the leaf. Any remaining partial cluster will be freed if possible
> when the next leaf is processed or when leaf removal is complete.
>
> Signed-off-by: Eric Whitney <enwlinux at gmail.com>
> Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
> Signed-off-by: Kamal Mostafa <kamal at canonical.com>
> ---
> fs/ext4/extents.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
> index 7b22105..37f6849 100644
> --- a/fs/ext4/extents.c
> +++ b/fs/ext4/extents.c
> @@ -2646,10 +2646,15 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
> err = ext4_ext_correct_indexes(handle, inode, path);
>
> /*
> - * Free the partial cluster only if the current extent does not
> - * reference it. Otherwise we might free used cluster.
> + * If there's a partial cluster and at least one extent remains in
> + * the leaf, free the partial cluster if it isn't shared with the
> + * current extent. If there's a partial cluster and no extents
> + * remain in the leaf, it can't be freed here. It can only be
> + * freed when it's possible to determine if it's not shared with
> + * any other extent - when the next leaf is processed or when space
> + * removal is complete.
> */
> - if (*partial_cluster > 0 &&
> + if (*partial_cluster > 0 && eh->eh_entries &&
> (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) !=
> *partial_cluster)) {
> int flags = EXT4_FREE_BLOCKS_FORGET;
> --
> 1.9.1
>
More information about the kernel-team
mailing list