From patchwork Thu Mar 10 19:18:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 8559631 Return-Path: X-Original-To: patchwork-linux-nvdimm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 52BCFC0555 for ; Thu, 10 Mar 2016 19:18:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 781F62037E for ; Thu, 10 Mar 2016 19:18:44 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7B77820376 for ; Thu, 10 Mar 2016 19:18:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 679DC1A1F51; Thu, 10 Mar 2016 11:18:57 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 40ECD1A1F59 for ; Thu, 10 Mar 2016 11:18:54 -0800 (PST) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 5DD3BACDF; Thu, 10 Mar 2016 19:18:36 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 41F6382527; Thu, 10 Mar 2016 20:18:57 +0100 (CET) From: Jan Kara To: linux-fsdevel@vger.kernel.org Subject: [PATCH 09/12] dax: Allow DAX code to replace exceptional entries Date: Thu, 10 Mar 2016 20:18:52 +0100 Message-Id: <1457637535-21633-10-git-send-email-jack@suse.cz> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1457637535-21633-1-git-send-email-jack@suse.cz> References: <1457637535-21633-1-git-send-email-jack@suse.cz> Cc: Jan Kara , linux-nvdimm@lists.01.org, NeilBrown , "Wilcox, Matthew R" X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently we forbid page_cache_tree_insert() to replace exceptional radix tree entries for DAX inodes. However to make DAX faults race free we will lock radix tree entries and when hole is created, we need to replace such locked radix tree entry with a hole page. So modify page_cache_tree_insert() to allow that. Signed-off-by: Jan Kara --- include/linux/dax.h | 6 ++++++ mm/filemap.c | 18 +++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/linux/dax.h b/include/linux/dax.h index 7c45ac7ea1d1..4b63923e1f8d 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -3,8 +3,14 @@ #include #include +#include #include +/* + * Since exceptional entries do not use indirect bit, we reuse it as a lock bit + */ +#define DAX_ENTRY_LOCK RADIX_TREE_INDIRECT_PTR + ssize_t dax_do_io(struct kiocb *, struct inode *, struct iov_iter *, loff_t, get_block_t, dio_iodone_t, int flags); int dax_clear_sectors(struct block_device *bdev, sector_t _sector, long _size); diff --git a/mm/filemap.c b/mm/filemap.c index 3461d97ecb30..262e6eff0b66 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -583,14 +583,18 @@ static int page_cache_tree_insert(struct address_space *mapping, if (!radix_tree_exceptional_entry(p)) return -EEXIST; - if (WARN_ON(dax_mapping(mapping))) - return -EINVAL; - - if (shadowp) - *shadowp = p; mapping->nrexceptional--; - if (node) - workingset_node_shadows_dec(node); + if (!dax_mapping(mapping)) { + if (shadowp) + *shadowp = p; + if (node) + workingset_node_shadows_dec(node); + } else { + /* DAX can replace empty locked entry with a hole */ + WARN_ON_ONCE(p != + (void *)(RADIX_TREE_EXCEPTIONAL_ENTRY | + DAX_ENTRY_LOCK)); + } } radix_tree_replace_slot(slot, page); mapping->nrpages++;