dax: Move mandatory ->zero_page_range() check in alloc_dax()
zero_page_range() dax operation is mandatory for dax devices. Right now that check happens in dax_zero_page_range() function. Dan thinks that's too late and its better to do the check earlier in alloc_dax(). I also modified alloc_dax() to return pointer with error code in it in case of failure. Right now it returns NULL and caller assumes failure happened due to -ENOMEM. But with this ->zero_page_range() check, I need to return -EINVAL instead. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Link: https://lore.kernel.org/r/20200401161125.GB9398@redhat.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
4f3b4f161d
commit
4e4ced9379
@ -421,8 +421,10 @@ struct dev_dax *__devm_create_dev_dax(struct dax_region *dax_region, int id,
|
|||||||
* device outside of mmap of the resulting character device.
|
* device outside of mmap of the resulting character device.
|
||||||
*/
|
*/
|
||||||
dax_dev = alloc_dax(dev_dax, NULL, NULL, DAXDEV_F_SYNC);
|
dax_dev = alloc_dax(dev_dax, NULL, NULL, DAXDEV_F_SYNC);
|
||||||
if (!dax_dev)
|
if (IS_ERR(dax_dev)) {
|
||||||
|
rc = PTR_ERR(dax_dev);
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* a device_dax instance is dead while the driver is not attached */
|
/* a device_dax instance is dead while the driver is not attached */
|
||||||
kill_dax(dax_dev);
|
kill_dax(dax_dev);
|
||||||
|
@ -349,9 +349,6 @@ int dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
|
|||||||
{
|
{
|
||||||
if (!dax_alive(dax_dev))
|
if (!dax_alive(dax_dev))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
if (!dax_dev->ops->zero_page_range)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
/*
|
/*
|
||||||
* There are no callers that want to zero more than one page as of now.
|
* There are no callers that want to zero more than one page as of now.
|
||||||
* Once users are there, this check can be removed after the
|
* Once users are there, this check can be removed after the
|
||||||
@ -571,9 +568,16 @@ struct dax_device *alloc_dax(void *private, const char *__host,
|
|||||||
dev_t devt;
|
dev_t devt;
|
||||||
int minor;
|
int minor;
|
||||||
|
|
||||||
|
if (ops && !ops->zero_page_range) {
|
||||||
|
pr_debug("%s: error: device does not provide dax"
|
||||||
|
" operation zero_page_range()\n",
|
||||||
|
__host ? __host : "Unknown");
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
host = kstrdup(__host, GFP_KERNEL);
|
host = kstrdup(__host, GFP_KERNEL);
|
||||||
if (__host && !host)
|
if (__host && !host)
|
||||||
return NULL;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
minor = ida_simple_get(&dax_minor_ida, 0, MINORMASK+1, GFP_KERNEL);
|
minor = ida_simple_get(&dax_minor_ida, 0, MINORMASK+1, GFP_KERNEL);
|
||||||
if (minor < 0)
|
if (minor < 0)
|
||||||
@ -596,7 +600,7 @@ struct dax_device *alloc_dax(void *private, const char *__host,
|
|||||||
ida_simple_remove(&dax_minor_ida, minor);
|
ida_simple_remove(&dax_minor_ida, minor);
|
||||||
err_minor:
|
err_minor:
|
||||||
kfree(host);
|
kfree(host);
|
||||||
return NULL;
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(alloc_dax);
|
EXPORT_SYMBOL_GPL(alloc_dax);
|
||||||
|
|
||||||
|
@ -2005,7 +2005,7 @@ static struct mapped_device *alloc_dev(int minor)
|
|||||||
if (IS_ENABLED(CONFIG_DAX_DRIVER)) {
|
if (IS_ENABLED(CONFIG_DAX_DRIVER)) {
|
||||||
md->dax_dev = alloc_dax(md, md->disk->disk_name,
|
md->dax_dev = alloc_dax(md, md->disk->disk_name,
|
||||||
&dm_dax_ops, 0);
|
&dm_dax_ops, 0);
|
||||||
if (!md->dax_dev)
|
if (IS_ERR(md->dax_dev))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,9 +487,9 @@ static int pmem_attach_disk(struct device *dev,
|
|||||||
if (is_nvdimm_sync(nd_region))
|
if (is_nvdimm_sync(nd_region))
|
||||||
flags = DAXDEV_F_SYNC;
|
flags = DAXDEV_F_SYNC;
|
||||||
dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops, flags);
|
dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops, flags);
|
||||||
if (!dax_dev) {
|
if (IS_ERR(dax_dev)) {
|
||||||
put_disk(disk);
|
put_disk(disk);
|
||||||
return -ENOMEM;
|
return PTR_ERR(dax_dev);
|
||||||
}
|
}
|
||||||
dax_write_cache(dax_dev, nvdimm_has_cache(nd_region));
|
dax_write_cache(dax_dev, nvdimm_has_cache(nd_region));
|
||||||
pmem->dax_dev = dax_dev;
|
pmem->dax_dev = dax_dev;
|
||||||
|
@ -695,8 +695,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
|
|||||||
|
|
||||||
dev_info->dax_dev = alloc_dax(dev_info, dev_info->gd->disk_name,
|
dev_info->dax_dev = alloc_dax(dev_info, dev_info->gd->disk_name,
|
||||||
&dcssblk_dax_ops, DAXDEV_F_SYNC);
|
&dcssblk_dax_ops, DAXDEV_F_SYNC);
|
||||||
if (!dev_info->dax_dev) {
|
if (IS_ERR(dev_info->dax_dev)) {
|
||||||
rc = -ENOMEM;
|
rc = PTR_ERR(dev_info->dax_dev);
|
||||||
|
dev_info->dax_dev = NULL;
|
||||||
goto put_dev;
|
goto put_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user