Commit 4e4ced93 authored by Vivek Goyal's avatar Vivek Goyal Committed by Dan Williams

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: default avatarVivek Goyal <vgoyal@redhat.com>
Link: https://lore.kernel.org/r/20200401161125.GB9398@redhat.comSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 4f3b4f16
...@@ -421,8 +421,10 @@ struct dev_dax *__devm_create_dev_dax(struct dax_region *dax_region, int id, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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 ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment