Skip to content

Commit fa312b4

Browse files
Ashish Samantgregkh
authored andcommitted
ocfs2: fstrim: Fix start offset of first cluster group during fstrim
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>
1 parent cc7d993 commit fa312b4

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

fs/ocfs2/alloc.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7270,21 +7270,32 @@ int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh,
72707270

72717271
static int ocfs2_trim_extent(struct super_block *sb,
72727272
struct ocfs2_group_desc *gd,
7273-
u32 start, u32 count)
7273+
u64 group, u32 start, u32 count)
72747274
{
72757275
u64 discard, bcount;
7276+
struct ocfs2_super *osb = OCFS2_SB(sb);
72767277

72777278
bcount = ocfs2_clusters_to_blocks(sb, count);
7278-
discard = le64_to_cpu(gd->bg_blkno) +
7279-
ocfs2_clusters_to_blocks(sb, start);
7279+
discard = ocfs2_clusters_to_blocks(sb, start);
7280+
7281+
/*
7282+
* For the first cluster group, the gd->bg_blkno is not at the start
7283+
* of the group, but at an offset from the start. If we add it while
7284+
* calculating discard for first group, we will wrongly start fstrim a
7285+
* few blocks after the desried start block and the range can cross
7286+
* over into the next cluster group. So, add it only if this is not
7287+
* the first cluster group.
7288+
*/
7289+
if (group != osb->first_cluster_group_blkno)
7290+
discard += le64_to_cpu(gd->bg_blkno);
72807291

72817292
trace_ocfs2_trim_extent(sb, (unsigned long long)discard, bcount);
72827293

72837294
return sb_issue_discard(sb, discard, bcount, GFP_NOFS, 0);
72847295
}
72857296

72867297
static int ocfs2_trim_group(struct super_block *sb,
7287-
struct ocfs2_group_desc *gd,
7298+
struct ocfs2_group_desc *gd, u64 group,
72887299
u32 start, u32 max, u32 minbits)
72897300
{
72907301
int ret = 0, count = 0, next;
@@ -7303,7 +7314,7 @@ static int ocfs2_trim_group(struct super_block *sb,
73037314
next = ocfs2_find_next_bit(bitmap, max, start);
73047315

73057316
if ((next - start) >= minbits) {
7306-
ret = ocfs2_trim_extent(sb, gd,
7317+
ret = ocfs2_trim_extent(sb, gd, group,
73077318
start, next - start);
73087319
if (ret < 0) {
73097320
mlog_errno(ret);
@@ -7401,7 +7412,8 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range)
74017412
}
74027413

74037414
gd = (struct ocfs2_group_desc *)gd_bh->b_data;
7404-
cnt = ocfs2_trim_group(sb, gd, first_bit, last_bit, minlen);
7415+
cnt = ocfs2_trim_group(sb, gd, group,
7416+
first_bit, last_bit, minlen);
74057417
brelse(gd_bh);
74067418
gd_bh = NULL;
74077419
if (cnt < 0) {

0 commit comments

Comments
 (0)