dax: Move mandatory ->zero_page_range() check in alloc_dax()
authorVivek Goyal <vgoyal@redhat.com>
Wed, 1 Apr 2020 16:11:25 +0000 (12:11 -0400)
committerDan Williams <dan.j.williams@intel.com>
Fri, 3 Apr 2020 02:15:03 +0000 (19:15 -0700)
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>
drivers/dax/bus.c
drivers/dax/super.c
drivers/md/dm.c
drivers/nvdimm/pmem.c
drivers/s390/block/dcssblk.c

index 46e4604..df238c8 100644 (file)
@@ -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.
         */
        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;
+       }
 
        /* a device_dax instance is dead while the driver is not attached */
        kill_dax(dax_dev);
index e498daf..8e32345 100644 (file)
@@ -349,9 +349,6 @@ int dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
 {
        if (!dax_alive(dax_dev))
                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.
         * 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;
        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);
        if (__host && !host)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        minor = ida_simple_get(&dax_minor_ida, 0, MINORMASK+1, GFP_KERNEL);
        if (minor < 0)
@@ -596,7 +600,7 @@ struct dax_device *alloc_dax(void *private, const char *__host,
        ida_simple_remove(&dax_minor_ida, minor);
  err_minor:
        kfree(host);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL_GPL(alloc_dax);
 
index aa72d9e..6504f0a 100644 (file)
@@ -2005,7 +2005,7 @@ static struct mapped_device *alloc_dev(int minor)
        if (IS_ENABLED(CONFIG_DAX_DRIVER)) {
                md->dax_dev = alloc_dax(md, md->disk->disk_name,
                                        &dm_dax_ops, 0);
-               if (!md->dax_dev)
+               if (IS_ERR(md->dax_dev))
                        goto bad;
        }
 
index 5b774dd..715cb06 100644 (file)
@@ -487,9 +487,9 @@ static int pmem_attach_disk(struct device *dev,
        if (is_nvdimm_sync(nd_region))
                flags = DAXDEV_F_SYNC;
        dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops, flags);
-       if (!dax_dev) {
+       if (IS_ERR(dax_dev)) {
                put_disk(disk);
-               return -ENOMEM;
+               return PTR_ERR(dax_dev);
        }
        dax_write_cache(dax_dev, nvdimm_has_cache(nd_region));
        pmem->dax_dev = dax_dev;
index ab3e289..9b05cf1 100644 (file)
@@ -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,
                        &dcssblk_dax_ops, DAXDEV_F_SYNC);
-       if (!dev_info->dax_dev) {
-               rc = -ENOMEM;
+       if (IS_ERR(dev_info->dax_dev)) {
+               rc = PTR_ERR(dev_info->dax_dev);
+               dev_info->dax_dev = NULL;
                goto put_dev;
        }