mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
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 <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Dave Chinner <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Ross Zwisler <[email protected]> Reported-by: kbuild test robot <[email protected]> Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Dan Williams <[email protected]>
This commit is contained in:
parent
4ebb16ca9a
commit
5a023cdba5
4 changed files with 169 additions and 8 deletions
|
|
@ -406,6 +406,62 @@ static inline int is_unrecognized_ioctl(int ret)
|
|||
ret == -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
static int blkdev_daxset(struct block_device *bdev, unsigned long argp)
|
||||
{
|
||||
unsigned long arg;
|
||||
int rc = 0;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EACCES;
|
||||
|
||||
if (get_user(arg, (int __user *)(argp)))
|
||||
return -EFAULT;
|
||||
arg = !!arg;
|
||||
if (arg == !!(bdev->bd_inode->i_flags & S_DAX))
|
||||
return 0;
|
||||
|
||||
if (arg)
|
||||
arg = S_DAX;
|
||||
|
||||
if (arg && !blkdev_dax_capable(bdev))
|
||||
return -ENOTTY;
|
||||
|
||||
mutex_lock(&bdev->bd_inode->i_mutex);
|
||||
if (bdev->bd_map_count == 0)
|
||||
inode_set_flags(bdev->bd_inode, arg, S_DAX);
|
||||
else
|
||||
rc = -EBUSY;
|
||||
mutex_unlock(&bdev->bd_inode->i_mutex);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static int blkdev_daxset(struct block_device *bdev, int arg)
|
||||
{
|
||||
if (arg)
|
||||
return -ENOTTY;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
|
||||
unsigned cmd, unsigned long arg)
|
||||
{
|
||||
|
|
@ -568,6 +624,11 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
|
|||
case BLKTRACESETUP:
|
||||
case BLKTRACETEARDOWN:
|
||||
return blk_trace_ioctl(bdev, cmd, argp);
|
||||
case BLKDAXSET:
|
||||
return blkdev_daxset(bdev, arg);
|
||||
case BLKDAXGET:
|
||||
return put_int(arg, !!(bdev->bd_inode->i_flags & S_DAX));
|
||||
break;
|
||||
case IOC_PR_REGISTER:
|
||||
return blkdev_pr_register(bdev, argp);
|
||||
case IOC_PR_RESERVE:
|
||||
|
|
|
|||
Loading…
Reference in a new issue