From patchwork Mon Nov 2 04:30:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 7533591 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 DD6C1BEEA4 for ; Mon, 2 Nov 2015 04:36:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E3C1E205BA for ; Mon, 2 Nov 2015 04:36:38 +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 6C04020551 for ; Mon, 2 Nov 2015 04:36:37 +0000 (UTC) Received: from ml01.vlan14.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 60DA41A1F3C; Sun, 1 Nov 2015 20:36:37 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by ml01.01.org (Postfix) with ESMTP id C61921A1F38 for ; Sun, 1 Nov 2015 20:36:35 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 01 Nov 2015 20:36:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,232,1444719600"; d="scan'208";a="840331159" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.39]) by orsmga002.jf.intel.com with ESMTP; 01 Nov 2015 20:36:35 -0800 Subject: [PATCH v3 13/15] block, dax: make dax mappings opt-in by default From: Dan Williams To: axboe@fb.com Date: Sun, 01 Nov 2015 23:30:53 -0500 Message-ID: <20151102043053.6610.43948.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <20151102042941.6610.27784.stgit@dwillia2-desk3.amr.corp.intel.com> References: <20151102042941.6610.27784.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-9-g687f MIME-Version: 1.0 Cc: jack@suse.cz, linux-nvdimm@lists.01.org, david@fromorbit.com, linux-kernel@vger.kernel.org, hch@lst.de 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: , Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, T_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 Now that we have the ability to dynamically enable DAX for a raw block inode, make the behavior opt-in by default. DAX does not have feature parity with pagecache backed mappings, so applications should knowingly enable DAX semantics. Note, this is only for mappings returned to userspace. For the synchronous usages of DAX, dax_do_io(), there is no semantic difference with the bio submission path, so that path remains default enabled. Signed-off-by: Dan Williams --- block/ioctl.c | 3 +-- fs/block_dev.c | 33 +++++++++++++++++++++++---------- include/linux/fs.h | 8 ++++++++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index 205d57612fbd..c4c3a09d9ca9 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -298,13 +298,12 @@ static inline int is_unrecognized_ioctl(int ret) #ifdef CONFIG_FS_DAX static int blkdev_set_dax(struct block_device *bdev, int n) { - struct gendisk *disk = bdev->bd_disk; int rc = 0; if (n) n = S_DAX; - if (n && !disk->fops->direct_access) + if (n && !blkdev_dax_capable(bdev)) return -ENOTTY; mutex_lock(&bdev->bd_inode->i_mutex); diff --git a/fs/block_dev.c b/fs/block_dev.c index 13ce6d0ff7f6..ee34a31e6fa4 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -152,16 +152,37 @@ static struct inode *bdev_file_inode(struct file *file) return file->f_mapping->host; } +#ifdef CONFIG_FS_DAX +bool blkdev_dax_capable(struct block_device *bdev) +{ + struct gendisk *disk = bdev->bd_disk; + + if (!disk->fops->direct_access) + return false; + + /* + * If the partition is not aligned on a page boundary, we can't + * do dax I/O to it. + */ + if ((bdev->bd_part->start_sect % (PAGE_SIZE / 512)) + || (bdev->bd_part->nr_sects % (PAGE_SIZE / 512))) + return false; + + return true; +} +#endif + static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) { struct file *file = iocb->ki_filp; struct inode *inode = bdev_file_inode(file); + struct block_device *bdev = I_BDEV(inode); - if (IS_DAX(inode)) + if (blkdev_dax_capable(bdev)) return dax_do_io(iocb, inode, iter, offset, blkdev_get_block, NULL, DIO_SKIP_DIO_COUNT); - return __blockdev_direct_IO(iocb, inode, I_BDEV(inode), iter, offset, + return __blockdev_direct_IO(iocb, inode, bdev, iter, offset, blkdev_get_block, NULL, NULL, DIO_SKIP_DIO_COUNT); } @@ -1185,7 +1206,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) bdev->bd_disk = disk; bdev->bd_queue = disk->queue; bdev->bd_contains = bdev; - bdev->bd_inode->i_flags = disk->fops->direct_access ? S_DAX : 0; if (!partno) { ret = -ENXIO; bdev->bd_part = disk_get_part(disk, partno); @@ -1247,13 +1267,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) goto out_clear; } bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); - /* - * If the partition is not aligned on a page - * boundary, we can't do dax I/O to it. - */ - if ((bdev->bd_part->start_sect % (PAGE_SIZE / 512)) || - (bdev->bd_part->nr_sects % (PAGE_SIZE / 512))) - bdev->bd_inode->i_flags &= ~S_DAX; } } else { if (bdev->bd_contains == bdev) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 8fb2d4b848bf..5a9e14538f69 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2282,6 +2282,14 @@ extern struct super_block *freeze_bdev(struct block_device *); extern void emergency_thaw_all(void); extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); extern int fsync_bdev(struct block_device *); +#ifdef CONFIG_FS_DAX +extern bool blkdev_dax_capable(struct block_device *bdev); +#else +static inline bool blkdev_dax_capable(struct block_device *bdev) +{ + return false; +} +#endif extern struct super_block *blockdev_superblock;