]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Nov 2017 15:23:52 +0000 (16:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Nov 2017 15:23:52 +0000 (16:23 +0100)
added patches:
ocfs2-fstrim-fix-start-offset-of-first-cluster-group-during-fstrim.patch

queue-3.18/ocfs2-fstrim-fix-start-offset-of-first-cluster-group-during-fstrim.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/ocfs2-fstrim-fix-start-offset-of-first-cluster-group-during-fstrim.patch b/queue-3.18/ocfs2-fstrim-fix-start-offset-of-first-cluster-group-during-fstrim.patch
new file mode 100644 (file)
index 0000000..6652c8c
--- /dev/null
@@ -0,0 +1,89 @@
+From 105ddc93f06ebe3e553f58563d11ed63dbcd59f0 Mon Sep 17 00:00:00 2001
+From: Ashish Samant <ashish.samant@oracle.com>
+Date: Thu, 2 Nov 2017 15:59:37 -0700
+Subject: ocfs2: fstrim: Fix start offset of first cluster group during fstrim
+
+From: Ashish Samant <ashish.samant@oracle.com>
+
+commit 105ddc93f06ebe3e553f58563d11ed63dbcd59f0 upstream.
+
+The first cluster group descriptor is not stored at the start of the
+group but at an offset from the start.  We need to take this into
+account while doing fstrim on the first cluster group.  Otherwise we
+will wrongly start fstrim a few blocks after the desired start block and
+the range can cross over into the next cluster group and zero out the
+group descriptor there.  This can cause filesytem corruption that cannot
+be fixed by fsck.
+
+Link: http://lkml.kernel.org/r/1507835579-7308-1-git-send-email-ashish.samant@oracle.com
+Signed-off-by: Ashish Samant <ashish.samant@oracle.com>
+Reviewed-by: Junxiao Bi <junxiao.bi@oracle.com>
+Reviewed-by: Joseph Qi <jiangqi903@gmail.com>
+Cc: Mark Fasheh <mfasheh@versity.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ocfs2/alloc.c |   24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+--- a/fs/ocfs2/alloc.c
++++ b/fs/ocfs2/alloc.c
+@@ -7235,13 +7235,24 @@ out:
+ static int ocfs2_trim_extent(struct super_block *sb,
+                            struct ocfs2_group_desc *gd,
+-                           u32 start, u32 count)
++                           u64 group, u32 start, u32 count)
+ {
+       u64 discard, bcount;
++      struct ocfs2_super *osb = OCFS2_SB(sb);
+       bcount = ocfs2_clusters_to_blocks(sb, count);
+-      discard = le64_to_cpu(gd->bg_blkno) +
+-                      ocfs2_clusters_to_blocks(sb, start);
++      discard = ocfs2_clusters_to_blocks(sb, start);
++
++      /*
++       * For the first cluster group, the gd->bg_blkno is not at the start
++       * of the group, but at an offset from the start. If we add it while
++       * calculating discard for first group, we will wrongly start fstrim a
++       * few blocks after the desried start block and the range can cross
++       * over into the next cluster group. So, add it only if this is not
++       * the first cluster group.
++       */
++      if (group != osb->first_cluster_group_blkno)
++              discard += le64_to_cpu(gd->bg_blkno);
+       trace_ocfs2_trim_extent(sb, (unsigned long long)discard, bcount);
+@@ -7249,7 +7260,7 @@ static int ocfs2_trim_extent(struct supe
+ }
+ static int ocfs2_trim_group(struct super_block *sb,
+-                          struct ocfs2_group_desc *gd,
++                          struct ocfs2_group_desc *gd, u64 group,
+                           u32 start, u32 max, u32 minbits)
+ {
+       int ret = 0, count = 0, next;
+@@ -7268,7 +7279,7 @@ static int ocfs2_trim_group(struct super
+               next = ocfs2_find_next_bit(bitmap, max, start);
+               if ((next - start) >= minbits) {
+-                      ret = ocfs2_trim_extent(sb, gd,
++                      ret = ocfs2_trim_extent(sb, gd, group,
+                                               start, next - start);
+                       if (ret < 0) {
+                               mlog_errno(ret);
+@@ -7366,7 +7377,8 @@ int ocfs2_trim_fs(struct super_block *sb
+               }
+               gd = (struct ocfs2_group_desc *)gd_bh->b_data;
+-              cnt = ocfs2_trim_group(sb, gd, first_bit, last_bit, minlen);
++              cnt = ocfs2_trim_group(sb, gd, group,
++                                     first_bit, last_bit, minlen);
+               brelse(gd_bh);
+               gd_bh = NULL;
+               if (cnt < 0) {
index e0724aa81a47dac6cbb5c008b7cc26fa0779881c..07c582a0576ca3637a32683ec2176986146e3638 100644 (file)
@@ -7,3 +7,4 @@ keys-fix-out-of-bounds-read-during-asn.1-parsing.patch
 asoc-adau17x1-workaround-for-noise-bug-in-adc.patch
 arm64-ensure-__dump_instr-checks-addr_limit.patch
 arm-8715-1-add-a-private-asm-unaligned.h.patch
+ocfs2-fstrim-fix-start-offset-of-first-cluster-group-during-fstrim.patch