Merge tag 'libnvdimm-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdim...
[linux-2.6-microblaze.git] / drivers / dax / super.c
index 31b8391..903d9c4 100644 (file)
@@ -74,42 +74,43 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
 
 /**
  * __bdev_dax_supported() - Check if the device supports dax for filesystem
- * @sb: The superblock of the device
+ * @bdev: block device to check
  * @blocksize: The block size of the device
  *
  * This is a library function for filesystems to check if the block device
  * can be mounted with dax option.
  *
- * Return: negative errno if unsupported, 0 if supported.
+ * Return: true if supported, false if unsupported
  */
-int __bdev_dax_supported(struct super_block *sb, int blocksize)
+bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
 {
-       struct block_device *bdev = sb->s_bdev;
        struct dax_device *dax_dev;
+       bool dax_enabled = false;
        pgoff_t pgoff;
        int err, id;
        void *kaddr;
        pfn_t pfn;
        long len;
+       char buf[BDEVNAME_SIZE];
 
        if (blocksize != PAGE_SIZE) {
-               pr_debug("VFS (%s): error: unsupported blocksize for dax\n",
-                               sb->s_id);
-               return -EINVAL;
+               pr_debug("%s: error: unsupported blocksize for dax\n",
+                               bdevname(bdev, buf));
+               return false;
        }
 
        err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
        if (err) {
-               pr_debug("VFS (%s): error: unaligned partition for dax\n",
-                               sb->s_id);
-               return err;
+               pr_debug("%s: error: unaligned partition for dax\n",
+                               bdevname(bdev, buf));
+               return false;
        }
 
        dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
        if (!dax_dev) {
-               pr_debug("VFS (%s): error: device does not support dax\n",
-                               sb->s_id);
-               return -EOPNOTSUPP;
+               pr_debug("%s: error: device does not support dax\n",
+                               bdevname(bdev, buf));
+               return false;
        }
 
        id = dax_read_lock();
@@ -119,9 +120,9 @@ int __bdev_dax_supported(struct super_block *sb, int blocksize)
        put_dax(dax_dev);
 
        if (len < 1) {
-               pr_debug("VFS (%s): error: dax access failed (%ld)\n",
-                               sb->s_id, len);
-               return len < 0 ? len : -EIO;
+               pr_debug("%s: error: dax access failed (%ld)\n",
+                               bdevname(bdev, buf), len);
+               return false;
        }
 
        if (IS_ENABLED(CONFIG_FS_DAX_LIMITED) && pfn_t_special(pfn)) {
@@ -134,15 +135,22 @@ int __bdev_dax_supported(struct super_block *sb, int blocksize)
                 * on being able to do (page_address(pfn_to_page())).
                 */
                WARN_ON(IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API));
+               dax_enabled = true;
        } else if (pfn_t_devmap(pfn)) {
-               /* pass */;
-       } else {
-               pr_debug("VFS (%s): error: dax support not enabled\n",
-                               sb->s_id);
-               return -EOPNOTSUPP;
+               struct dev_pagemap *pgmap;
+
+               pgmap = get_dev_pagemap(pfn_t_to_pfn(pfn), NULL);
+               if (pgmap && pgmap->type == MEMORY_DEVICE_FS_DAX)
+                       dax_enabled = true;
+               put_dev_pagemap(pgmap);
        }
 
-       return 0;
+       if (!dax_enabled) {
+               pr_debug("%s: error: dax support not enabled\n",
+                               bdevname(bdev, buf));
+               return false;
+       }
+       return true;
 }
 EXPORT_SYMBOL_GPL(__bdev_dax_supported);
 #endif
@@ -182,8 +190,7 @@ static ssize_t write_cache_show(struct device *dev,
        if (!dax_dev)
                return -ENXIO;
 
-       rc = sprintf(buf, "%d\n", !!test_bit(DAXDEV_WRITE_CACHE,
-                               &dax_dev->flags));
+       rc = sprintf(buf, "%d\n", !!dax_write_cache_enabled(dax_dev));
        put_dax(dax_dev);
        return rc;
 }
@@ -201,10 +208,8 @@ static ssize_t write_cache_store(struct device *dev,
 
        if (rc)
                len = rc;
-       else if (write_cache)
-               set_bit(DAXDEV_WRITE_CACHE, &dax_dev->flags);
        else
-               clear_bit(DAXDEV_WRITE_CACHE, &dax_dev->flags);
+               dax_write_cache(dax_dev, write_cache);
 
        put_dax(dax_dev);
        return len;
@@ -296,7 +301,7 @@ EXPORT_SYMBOL_GPL(dax_copy_to_iter);
 void arch_wb_cache_pmem(void *addr, size_t size);
 void dax_flush(struct dax_device *dax_dev, void *addr, size_t size)
 {
-       if (unlikely(!test_bit(DAXDEV_WRITE_CACHE, &dax_dev->flags)))
+       if (unlikely(!dax_write_cache_enabled(dax_dev)))
                return;
 
        arch_wb_cache_pmem(addr, size);