Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp4466991ybx; Mon, 4 Nov 2019 13:55:15 -0800 (PST) X-Google-Smtp-Source: APXvYqzc+tfsuPeYN4oeA0BQFk9j5t42iBn5vF1kPM6G217uPSgXbJ2EHYBAkdlpiJwTGWMMtcL7 X-Received: by 2002:a50:b4e4:: with SMTP id x33mr170396edd.222.1572904515801; Mon, 04 Nov 2019 13:55:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1572904515; cv=none; d=google.com; s=arc-20160816; b=Y/hcth8TRxtYP9NMnL1t2aMybY4W/7+m/RjWUFWrudxGT0mgqzB5v9HQYVsGLHoAhh yGpK1Xv82sXXeTqmXkgyuF+Y/nR4LjQfiM4ocBath6zJI2TFuc1ALETbj3q/dcynJyi1 JWGw5eatQ69G7IDvyj0769IkvBujnhFf4qmLdJseY52E+//XcbDmKEdq8Yx7zPjfTP6H SSBjeQb3w2WP1j9ySp5G4XP+b0f1y2NsfLQZYpYH4u+DUVdqGOqxHFyW3xu0vzTSkfc3 ZpyN8BmoWqY1jwig3Mv7FeJP9TUebSQF9woh2ielft2AfjEUewh/FGzh8qRNW9vJCxah lYyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=B0Y6RF++irDzOm2pU9USv48Clwt7kXsVZ7oBvWAQBJE=; b=pd0FJM9uIK2XwVTDm08Gt0N/14oe3dOCw33f0r+cqSlgDgo7WQL/hgYglxE7rko7k9 j4GXk7pfsn7JyDO4Hwl6yG0m2V71JYGAQ3vtdwYydLqP53DaLS1tWcaxnq/RhrjLpEpN j11xUCigFFDAo8tAzrljEAd+tlj5nEILpWEk0XW+TTDHY9aRNupB3ZN68rRPFIoXmhb1 PW3QTysjJdmhrXDInrZSzUJVvXq735ZLUB3hSB85xDphKVppTfag5EWQk6q+AE7O5Av2 MGuztmwrksNFMluGqpA+ACzzwcBx384SG5qqJNJSSt6tXjWHmvzBf1XpCyTKgeK5flUq 84fQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=qi8cKb0D; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p16si107540ejb.191.2019.11.04.13.54.52; Mon, 04 Nov 2019 13:55:15 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=qi8cKb0D; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730668AbfKDVwF (ORCPT + 99 others); Mon, 4 Nov 2019 16:52:05 -0500 Received: from mail.kernel.org ([198.145.29.99]:45158 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730220AbfKDVwB (ORCPT ); Mon, 4 Nov 2019 16:52:01 -0500 Received: from localhost (6.204-14-84.ripe.coltfrance.com [84.14.204.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AF3F82053B; Mon, 4 Nov 2019 21:51:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1572904320; bh=6bX3JZ0mNSoPeAZpx5MEgdqiywAKLyT661TKt6eO82w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qi8cKb0D0ezUspQEsHit3hvrI+aatrdPtFGWxcJLu4CQL07iTfCN1Pe2KG+QiC7dG 7WDEA/zoBgwjGOm6wAohSRhBqSev8ucfTmRUspBFYrjdK23lYeFSh+5s2/dvYzABnU tRJtokSxq/WtY+l3COiz+sCR3pseVEjtLhpRvgRk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jia Guo , Yiwen Jiang , Mark Fasheh , Joel Becker , Junxiao Bi , Joseph Qi , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH 4.9 23/62] ocfs2: clear zero in unaligned direct IO Date: Mon, 4 Nov 2019 22:44:45 +0100 Message-Id: <20191104211923.705375566@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191104211901.387893698@linuxfoundation.org> References: <20191104211901.387893698@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jia Guo [ Upstream commit 7a243c82ea527cd1da47381ad9cd646844f3b693 ] Unused portion of a part-written fs-block-sized block is not set to zero in unaligned append direct write.This can lead to serious data inconsistencies. Ocfs2 manage disk with cluster size(for example, 1M), part-written in one cluster will change the cluster state from UN-WRITTEN to WRITTEN, VFS(function dio_zero_block) doesn't do the cleaning because bh's state is not set to NEW in function ocfs2_dio_wr_get_block when we write a WRITTEN cluster. For example, the cluster size is 1M, file size is 8k and we direct write from 14k to 15k, then 12k~14k and 15k~16k will contain dirty data. We have to deal with two cases: 1.The starting position of direct write is outside the file. 2.The starting position of direct write is located in the file. We need set bh's state to NEW in the first case. In the second case, we need mapped twice because bh's state of area out file should be set to NEW while area in file not. [akpm@linux-foundation.org: coding style fixes] Link: http://lkml.kernel.org/r/5292e287-8f1a-fd4a-1a14-661e555e0bed@huawei.com Signed-off-by: Jia Guo Reviewed-by: Yiwen Jiang Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Joseph Qi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- fs/ocfs2/aops.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index c26d046adaaac..7c20a23c0ed7d 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -2143,13 +2143,30 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, struct ocfs2_dio_write_ctxt *dwc = NULL; struct buffer_head *di_bh = NULL; u64 p_blkno; - loff_t pos = iblock << inode->i_sb->s_blocksize_bits; + unsigned int i_blkbits = inode->i_sb->s_blocksize_bits; + loff_t pos = iblock << i_blkbits; + sector_t endblk = (i_size_read(inode) - 1) >> i_blkbits; unsigned len, total_len = bh_result->b_size; int ret = 0, first_get_block = 0; len = osb->s_clustersize - (pos & (osb->s_clustersize - 1)); len = min(total_len, len); + /* + * bh_result->b_size is count in get_more_blocks according to write + * "pos" and "end", we need map twice to return different buffer state: + * 1. area in file size, not set NEW; + * 2. area out file size, set NEW. + * + * iblock endblk + * |--------|---------|---------|--------- + * |<-------area in file------->| + */ + + if ((iblock <= endblk) && + ((iblock + ((len - 1) >> i_blkbits)) > endblk)) + len = (endblk - iblock + 1) << i_blkbits; + mlog(0, "get block of %lu at %llu:%u req %u\n", inode->i_ino, pos, len, total_len); @@ -2233,6 +2250,9 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, if (desc->c_needs_zero) set_buffer_new(bh_result); + if (iblock > endblk) + set_buffer_new(bh_result); + /* May sleep in end_io. It should not happen in a irq context. So defer * it to dio work queue. */ set_buffer_defer_completion(bh_result); -- 2.20.1