diff options
Diffstat (limited to 'drivers/dax/device.c')
-rw-r--r-- | drivers/dax/device.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/dax/device.c b/drivers/dax/device.c index 006e657dfcb9..e9f3b3e4bbf4 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -499,6 +499,7 @@ static int dax_open(struct inode *inode, struct file *filp) inode->i_mapping = __dax_inode->i_mapping; inode->i_mapping->host = __dax_inode; filp->f_mapping = inode->i_mapping; + filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping); filp->private_data = dev_dax; inode->i_flags = S_DAX; @@ -528,7 +529,8 @@ static void dev_dax_release(struct device *dev) struct dax_region *dax_region = dev_dax->region; struct dax_device *dax_dev = dev_dax->dax_dev; - ida_simple_remove(&dax_region->ida, dev_dax->id); + if (dev_dax->id >= 0) + ida_simple_remove(&dax_region->ida, dev_dax->id); dax_region_put(dax_region); put_dax(dax_dev); kfree(dev_dax); @@ -558,7 +560,7 @@ static void unregister_dev_dax(void *dev) } struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, - struct resource *res, int count) + int id, struct resource *res, int count) { struct device *parent = dax_region->dev; struct dax_device *dax_dev; @@ -566,7 +568,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, struct inode *inode; struct device *dev; struct cdev *cdev; - int rc = 0, i; + int rc, i; + + if (!count) + return ERR_PTR(-EINVAL); dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL); if (!dev_dax) @@ -586,10 +591,16 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, if (i < count) goto err_id; - dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL); - if (dev_dax->id < 0) { - rc = dev_dax->id; - goto err_id; + if (id < 0) { + id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL); + dev_dax->id = id; + if (id < 0) { + rc = id; + goto err_id; + } + } else { + /* region provider owns @id lifetime */ + dev_dax->id = -1; } /* @@ -597,8 +608,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, * device outside of mmap of the resulting character device. */ dax_dev = alloc_dax(dev_dax, NULL, NULL); - if (!dax_dev) + if (!dax_dev) { + rc = -ENOMEM; goto err_dax; + } /* from here on we're committed to teardown via dax_dev_release() */ dev = &dev_dax->dev; @@ -619,7 +632,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, dev->parent = parent; dev->groups = dax_attribute_groups; dev->release = dev_dax_release; - dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id); + dev_set_name(dev, "dax%d.%d", dax_region->id, id); rc = cdev_device_add(cdev, dev); if (rc) { @@ -635,7 +648,8 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, return dev_dax; err_dax: - ida_simple_remove(&dax_region->ida, dev_dax->id); + if (dev_dax->id >= 0) + ida_simple_remove(&dax_region->ida, dev_dax->id); err_id: kfree(dev_dax); |