Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp1346168rwb; Thu, 1 Dec 2022 16:17:50 -0800 (PST) X-Google-Smtp-Source: AA0mqf74nnCx2z1uo5zPIYuiDanRLTqnvfk504nBuF8eZryhmWoy8HwLw70dRfVk7QqBKsfoDJyT X-Received: by 2002:a17:90a:4b81:b0:213:5a4d:8138 with SMTP id i1-20020a17090a4b8100b002135a4d8138mr71558331pjh.17.1669940270059; Thu, 01 Dec 2022 16:17:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669940270; cv=none; d=google.com; s=arc-20160816; b=HN97+SrII7BtR1RaxbLtEUkRTbxrdUselJeVZfDInLMgd0/m3IfNTCXi40keptJPME bxHYJz5vzfoU9ZBSYChrDe5FRBFnmskNhkcuaAyO/ZPut5ZEgrLTCPB3vvGxhWVVA5tQ De4HXKjcojdlLgFaWv2b07+b3nKzMW1js8LXHCZtXH48TBaFauxFUhPo9Harqc2yyNNl 6tBtuwYXvw6DEhiA0zFkFufXgU5YLxRtAoOgdOmWVs2nnbIF9rJWspSOpEthUk37vAvy eLcSdw/TbnQBSJSUk4ZKQ33ezJS3H3B5OVcPKaTpp+duXls7ahp5LSbik5JI3djcrxtG bGNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=zRBnr4WDguf/957W8F4LWwxswOB2fw9JEYTwunrtZvE=; b=nsVfaO/Vse1IM9zBiNGJDLDEAoCpxP+3FMgSsbIKYxO5r3oGSElUVdr4KkC+7iIB9e AJIOWlnqBGaIEl1spwVmLYDi7sernTKdk3X17msCFnNuYP3YZ4HgxaGqU0+eeJveIQ2J ZuAedKvRHxN2HfqHTvmzfX+oGIZ47wiTKbxu3rvWfdWGbFdeOUVLXgguysTUF5QAx2tU fl1JoLmeRm4tJW7Wnv3d2LJSsWTA2pusXPpFBOvXpfhq2SQqBnd5t4RJdZq5oy+JYvSA tMwlH+smUhIfS6RpC0Ltj6ZLxcbshDCrsoqIAKHYpl59nDw9MKyzELTOMazD9G1x1lXa FJww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MhniUVuX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a11-20020a1709027e4b00b00179f72a057esi5251593pln.417.2022.12.01.16.17.38; Thu, 01 Dec 2022 16:17:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MhniUVuX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231319AbiLAX62 (ORCPT + 81 others); Thu, 1 Dec 2022 18:58:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231923AbiLAX6N (ORCPT ); Thu, 1 Dec 2022 18:58:13 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C667DBFCFE; Thu, 1 Dec 2022 15:58:12 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6BF3C6178A; Thu, 1 Dec 2022 23:58:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C27F0C433C1; Thu, 1 Dec 2022 23:58:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1669939091; bh=zPyaMFVNtJz39yxuPqF88oHgpJ3uncDzubuWa5rwGJc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=MhniUVuXFz96YDbTNmKxsR23Xfn0Bw5dVPYyb3Pfrt+WgCyOOL59YbJchYz1ZXNmG xmSoWIvChXKlmhedoutyUiutSWeBHfRvrQmMUs/vAaYxpZyN5p1gAQz38l8uu77Cqm h2LPjjYUEdL48kiIp7MBEnmE/U4C4o+QDl5sR1M2OHjHSackl/pvXF8Mbf0tDH5eLX CsPgJlVUgOGDbo/kXPbKH1AP/RCFUpj+ikg+Fc4damulzHfFWu0l+NZpt+EPI/lmrD 3WPFQb2PbmnVCbJAV0j3Bo8+fBP1CtAeVzudaQu8BsV/14FamWbu/kGV7emLyjr7Ip vxKs0XuvavxOA== Date: Thu, 1 Dec 2022 15:58:11 -0800 From: "Darrick J. Wong" To: Shiyang Ruan Cc: linux-kernel@vger.kernel.org, linux-xfs@vger.kernel.org, nvdimm@lists.linux.dev, linux-fsdevel@vger.kernel.org, david@fromorbit.com, dan.j.williams@intel.com, akpm@linux-foundation.org Subject: Re: [PATCH v2 3/8] fsdax: zero the edges if source is HOLE or UNWRITTEN Message-ID: References: <1669908538-55-1-git-send-email-ruansy.fnst@fujitsu.com> <1669908538-55-4-git-send-email-ruansy.fnst@fujitsu.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1669908538-55-4-git-send-email-ruansy.fnst@fujitsu.com> X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Dec 01, 2022 at 03:28:53PM +0000, Shiyang Ruan wrote: > If srcmap contains invalid data, such as HOLE and UNWRITTEN, the dest > page should be zeroed. Otherwise, since it's a pmem, old data may > remains on the dest page, the result of CoW will be incorrect. > > The function name is also not easy to understand, rename it to > "dax_iomap_copy_around()", which means it copys data around the range. > > Signed-off-by: Shiyang Ruan > --- > fs/dax.c | 78 ++++++++++++++++++++++++++++++++++---------------------- > 1 file changed, 48 insertions(+), 30 deletions(-) > > diff --git a/fs/dax.c b/fs/dax.c > index 482dda85ccaf..6b6e07ad8d80 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -1092,7 +1092,7 @@ static int dax_iomap_direct_access(const struct iomap *iomap, loff_t pos, > } > > /** > - * dax_iomap_cow_copy - Copy the data from source to destination before write > + * dax_iomap_copy_around - Copy the data from source to destination before write * dax_iomap_copy_around - Prepare for an unaligned write to a * shared/cow page by copying the data before and after the range to be * written. Other than that, this make sense, Reviewed-by: Darrick J. Wong --D > * @pos: address to do copy from. > * @length: size of copy operation. > * @align_size: aligned w.r.t align_size (either PMD_SIZE or PAGE_SIZE) > @@ -1101,35 +1101,50 @@ static int dax_iomap_direct_access(const struct iomap *iomap, loff_t pos, > * > * This can be called from two places. Either during DAX write fault (page > * aligned), to copy the length size data to daddr. Or, while doing normal DAX > - * write operation, dax_iomap_actor() might call this to do the copy of either > + * write operation, dax_iomap_iter() might call this to do the copy of either > * start or end unaligned address. In the latter case the rest of the copy of > - * aligned ranges is taken care by dax_iomap_actor() itself. > + * aligned ranges is taken care by dax_iomap_iter() itself. > + * If the srcmap contains invalid data, such as HOLE and UNWRITTEN, zero the > + * area to make sure no old data remains. > */ > -static int dax_iomap_cow_copy(loff_t pos, uint64_t length, size_t align_size, > +static int dax_iomap_copy_around(loff_t pos, uint64_t length, size_t align_size, > const struct iomap *srcmap, void *daddr) > { > loff_t head_off = pos & (align_size - 1); > size_t size = ALIGN(head_off + length, align_size); > loff_t end = pos + length; > loff_t pg_end = round_up(end, align_size); > + /* copy_all is usually in page fault case */ > bool copy_all = head_off == 0 && end == pg_end; > + /* zero the edges if srcmap is a HOLE or IOMAP_UNWRITTEN */ > + bool zero_edge = srcmap->flags & IOMAP_F_SHARED || > + srcmap->type == IOMAP_UNWRITTEN; > void *saddr = 0; > int ret = 0; > > - ret = dax_iomap_direct_access(srcmap, pos, size, &saddr, NULL); > - if (ret) > - return ret; > + if (!zero_edge) { > + ret = dax_iomap_direct_access(srcmap, pos, size, &saddr, NULL); > + if (ret) > + return ret; > + } > > if (copy_all) { > - ret = copy_mc_to_kernel(daddr, saddr, length); > - return ret ? -EIO : 0; > + if (zero_edge) > + memset(daddr, 0, size); > + else > + ret = copy_mc_to_kernel(daddr, saddr, length); > + goto out; > } > > /* Copy the head part of the range */ > if (head_off) { > - ret = copy_mc_to_kernel(daddr, saddr, head_off); > - if (ret) > - return -EIO; > + if (zero_edge) > + memset(daddr, 0, head_off); > + else { > + ret = copy_mc_to_kernel(daddr, saddr, head_off); > + if (ret) > + return -EIO; > + } > } > > /* Copy the tail part of the range */ > @@ -1137,12 +1152,19 @@ static int dax_iomap_cow_copy(loff_t pos, uint64_t length, size_t align_size, > loff_t tail_off = head_off + length; > loff_t tail_len = pg_end - end; > > - ret = copy_mc_to_kernel(daddr + tail_off, saddr + tail_off, > - tail_len); > - if (ret) > - return -EIO; > + if (zero_edge) > + memset(daddr + tail_off, 0, tail_len); > + else { > + ret = copy_mc_to_kernel(daddr + tail_off, > + saddr + tail_off, tail_len); > + if (ret) > + return -EIO; > + } > } > - return 0; > +out: > + if (zero_edge) > + dax_flush(srcmap->dax_dev, daddr, size); > + return ret ? -EIO : 0; > } > > /* > @@ -1241,13 +1263,10 @@ static int dax_memzero(struct iomap_iter *iter, loff_t pos, size_t size) > if (ret < 0) > return ret; > memset(kaddr + offset, 0, size); > - if (srcmap->addr != iomap->addr) { > - ret = dax_iomap_cow_copy(pos, size, PAGE_SIZE, srcmap, > - kaddr); > - if (ret < 0) > - return ret; > - dax_flush(iomap->dax_dev, kaddr, PAGE_SIZE); > - } else > + if (iomap->flags & IOMAP_F_SHARED) > + ret = dax_iomap_copy_around(pos, size, PAGE_SIZE, srcmap, > + kaddr); > + else > dax_flush(iomap->dax_dev, kaddr + offset, size); > return ret; > } > @@ -1401,8 +1420,8 @@ static loff_t dax_iomap_iter(const struct iomap_iter *iomi, > } > > if (cow) { > - ret = dax_iomap_cow_copy(pos, length, PAGE_SIZE, srcmap, > - kaddr); > + ret = dax_iomap_copy_around(pos, length, PAGE_SIZE, > + srcmap, kaddr); > if (ret) > break; > } > @@ -1547,7 +1566,7 @@ static vm_fault_t dax_fault_iter(struct vm_fault *vmf, > struct xa_state *xas, void **entry, bool pmd) > { > const struct iomap *iomap = &iter->iomap; > - const struct iomap *srcmap = &iter->srcmap; > + const struct iomap *srcmap = iomap_iter_srcmap(iter); > size_t size = pmd ? PMD_SIZE : PAGE_SIZE; > loff_t pos = (loff_t)xas->xa_index << PAGE_SHIFT; > bool write = iter->flags & IOMAP_WRITE; > @@ -1578,9 +1597,8 @@ static vm_fault_t dax_fault_iter(struct vm_fault *vmf, > > *entry = dax_insert_entry(xas, vmf, iter, *entry, pfn, entry_flags); > > - if (write && > - srcmap->type != IOMAP_HOLE && srcmap->addr != iomap->addr) { > - err = dax_iomap_cow_copy(pos, size, size, srcmap, kaddr); > + if (write && iomap->flags & IOMAP_F_SHARED) { > + err = dax_iomap_copy_around(pos, size, size, srcmap, kaddr); > if (err) > return dax_fault_return(err); > } > -- > 2.38.1 >