diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
| commit | 7731b8bc94e599c9a79e428f3359ff2c34b7576a (patch) | |
| tree | 879f18ccbe274122f2d4f095b43cbc7f953e0ada /drivers/dax/super.c | |
| parent | 48e315618dc4dc8904182cd221e3d395d5d97005 (diff) | |
| parent | 9ffc59d57228d74809700be6f7ecb1db10292f05 (diff) | |
Merge branch 'linus' into x86/urgent
Required to queue a dependent fix.
Diffstat (limited to 'drivers/dax/super.c')
| -rw-r--r-- | drivers/dax/super.c | 71 | 
1 files changed, 43 insertions, 28 deletions
diff --git a/drivers/dax/super.c b/drivers/dax/super.c index 2b2332b605e4..903d9c473749 100644 --- a/drivers/dax/super.c +++ b/drivers/dax/super.c @@ -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; @@ -282,11 +287,21 @@ size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,  }  EXPORT_SYMBOL_GPL(dax_copy_from_iter); +size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, +		size_t bytes, struct iov_iter *i) +{ +	if (!dax_alive(dax_dev)) +		return 0; + +	return dax_dev->ops->copy_to_iter(dax_dev, pgoff, addr, bytes, i); +} +EXPORT_SYMBOL_GPL(dax_copy_to_iter); +  #ifdef CONFIG_ARCH_HAS_PMEM_API  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);  | 
