From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753476AbcAVOzu (ORCPT ); Fri, 22 Jan 2016 09:55:50 -0500 Received: from mx2.suse.de ([195.135.220.15]:60811 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753166AbcAVOzs (ORCPT ); Fri, 22 Jan 2016 09:55:48 -0500 Date: Fri, 22 Jan 2016 15:55:59 +0100 From: Jan Kara To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, Alexander Viro , Andrew Morton , Dan Williams , Dave Chinner , Jan Kara , Matthew Wilcox , linux-fsdevel@vger.kernel.org, linux-nvdimm@ml01.01.org Subject: Re: [PATCH v2 2/5] dax: clear TOWRITE flag after flush is complete Message-ID: <20160122145559.GK16898@quack.suse.cz> References: <1453398364-22537-1-git-send-email-ross.zwisler@linux.intel.com> <1453398364-22537-3-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1453398364-22537-3-git-send-email-ross.zwisler@linux.intel.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu 21-01-16 10:46:01, Ross Zwisler wrote: > Previously in dax_writeback_one() we cleared the PAGECACHE_TAG_TOWRITE flag > before we had actually flushed the tagged radix tree entry to media. This > is incorrect because of the following race: > > Thread 1 Thread 2 > -------- -------- > dax_writeback_mapping_range() > tag entry with PAGECACHE_TAG_TOWRITE > dax_writeback_mapping_range() > tag entry with PAGECACHE_TAG_TOWRITE > dax_writeback_one() > radix_tree_tag_clear(TOWRITE) > TOWRITE flag is no longer set, > find_get_entries_tag() finds no > entries, return > flush entry to media > > In this case thread 1 returns before the data for the dirty entry is > actually durable on media. > > Fix this by only clearing the PAGECACHE_TAG_TOWRITE flag after all flushing > is complete. > > Signed-off-by: Ross Zwisler > Reported-by: Jan Kara Looks good. You can add: Reviewed-by: Jan Kara Honza > --- > fs/dax.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/fs/dax.c b/fs/dax.c > index cee9e1b..d589113 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -407,8 +407,6 @@ static int dax_writeback_one(struct block_device *bdev, > if (!radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE)) > goto unlock; > > - radix_tree_tag_clear(page_tree, index, PAGECACHE_TAG_TOWRITE); > - > if (WARN_ON_ONCE(type != RADIX_DAX_PTE && type != RADIX_DAX_PMD)) { > ret = -EIO; > goto unlock; > @@ -432,6 +430,10 @@ static int dax_writeback_one(struct block_device *bdev, > } > > wb_cache_pmem(dax.addr, dax.size); > + > + spin_lock_irq(&mapping->tree_lock); > + radix_tree_tag_clear(page_tree, index, PAGECACHE_TAG_TOWRITE); > + spin_unlock_irq(&mapping->tree_lock); > unmap: > dax_unmap_atomic(bdev, &dax); > return ret; > -- > 2.5.0 > > -- Jan Kara SUSE Labs, CR