aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2015-11-30 13:20:29 -0500
committerDan Williams <dan.j.williams@intel.com>2016-01-09 09:30:49 -0500
commit5a023cdba50c5f5f2bc351783b3131699deb3937 (patch)
treebae047e7bf8fb28e48563b33afc2881c226f4e31 /block
parent4ebb16ca9a06a54cdb2e7f2ce1e506fa4d432445 (diff)
block: enable dax for raw block devices
If an application wants exclusive access to all of the persistent memory provided by an NVDIMM namespace it can use this raw-block-dax facility to forgo establishing a filesystem. This capability is targeted primarily to hypervisors wanting to provision persistent memory for guests. It can be disabled / enabled dynamically via the new BLKDAXSET ioctl. Cc: Jeff Moyer <jmoyer@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Dave Chinner <david@fromorbit.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Reported-by: kbuild test robot <fengguang.wu@intel.com> Reviewed-by: Jan Kara <jack@suse.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'block')
-rw-r--r--block/ioctl.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/block/ioctl.c b/block/ioctl.c
index 0918aed2d847..7a964d842913 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -406,6 +406,62 @@ static inline int is_unrecognized_ioctl(int ret)
406 ret == -ENOIOCTLCMD; 406 ret == -ENOIOCTLCMD;
407} 407}
408 408
409#ifdef CONFIG_FS_DAX
410bool blkdev_dax_capable(struct block_device *bdev)
411{
412 struct gendisk *disk = bdev->bd_disk;
413
414 if (!disk->fops->direct_access)
415 return false;
416
417 /*
418 * If the partition is not aligned on a page boundary, we can't
419 * do dax I/O to it.
420 */
421 if ((bdev->bd_part->start_sect % (PAGE_SIZE / 512))
422 || (bdev->bd_part->nr_sects % (PAGE_SIZE / 512)))
423 return false;
424
425 return true;
426}
427
428static int blkdev_daxset(struct block_device *bdev, unsigned long argp)
429{
430 unsigned long arg;
431 int rc = 0;
432
433 if (!capable(CAP_SYS_ADMIN))
434 return -EACCES;
435
436 if (get_user(arg, (int __user *)(argp)))
437 return -EFAULT;
438 arg = !!arg;
439 if (arg == !!(bdev->bd_inode->i_flags & S_DAX))
440 return 0;
441
442 if (arg)
443 arg = S_DAX;
444
445 if (arg && !blkdev_dax_capable(bdev))
446 return -ENOTTY;
447
448 mutex_lock(&bdev->bd_inode->i_mutex);
449 if (bdev->bd_map_count == 0)
450 inode_set_flags(bdev->bd_inode, arg, S_DAX);
451 else
452 rc = -EBUSY;
453 mutex_unlock(&bdev->bd_inode->i_mutex);
454 return rc;
455}
456#else
457static int blkdev_daxset(struct block_device *bdev, int arg)
458{
459 if (arg)
460 return -ENOTTY;
461 return 0;
462}
463#endif
464
409static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode, 465static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
410 unsigned cmd, unsigned long arg) 466 unsigned cmd, unsigned long arg)
411{ 467{
@@ -568,6 +624,11 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
568 case BLKTRACESETUP: 624 case BLKTRACESETUP:
569 case BLKTRACETEARDOWN: 625 case BLKTRACETEARDOWN:
570 return blk_trace_ioctl(bdev, cmd, argp); 626 return blk_trace_ioctl(bdev, cmd, argp);
627 case BLKDAXSET:
628 return blkdev_daxset(bdev, arg);
629 case BLKDAXGET:
630 return put_int(arg, !!(bdev->bd_inode->i_flags & S_DAX));
631 break;
571 case IOC_PR_REGISTER: 632 case IOC_PR_REGISTER:
572 return blkdev_pr_register(bdev, argp); 633 return blkdev_pr_register(bdev, argp);
573 case IOC_PR_RESERVE: 634 case IOC_PR_RESERVE: