[PATCH v3 13/15] block, dax: make dax mappings opt-in by default

From: Dan Williams
Date: Sun Nov 01 2015 - 23:36:43 EST


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 <dan.j.williams@xxxxxxxxx>
---
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;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/