aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c117
1 files changed, 35 insertions, 82 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 0d435c794d76..2a305c1a2d88 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -18,6 +18,7 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/blkpg.h> 19#include <linux/blkpg.h>
20#include <linux/magic.h> 20#include <linux/magic.h>
21#include <linux/dax.h>
21#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
22#include <linux/swap.h> 23#include <linux/swap.h>
23#include <linux/pagevec.h> 24#include <linux/pagevec.h>
@@ -716,50 +717,18 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
716} 717}
717EXPORT_SYMBOL_GPL(bdev_write_page); 718EXPORT_SYMBOL_GPL(bdev_write_page);
718 719
719/** 720int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
720 * bdev_direct_access() - Get the address for directly-accessibly memory 721 pgoff_t *pgoff)
721 * @bdev: The device containing the memory
722 * @dax: control and output parameters for ->direct_access
723 *
724 * If a block device is made up of directly addressable memory, this function
725 * will tell the caller the PFN and the address of the memory. The address
726 * may be directly dereferenced within the kernel without the need to call
727 * ioremap(), kmap() or similar. The PFN is suitable for inserting into
728 * page tables.
729 *
730 * Return: negative errno if an error occurs, otherwise the number of bytes
731 * accessible at this address.
732 */
733long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
734{ 722{
735 sector_t sector = dax->sector; 723 phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
736 long avail, size = dax->size;
737 const struct block_device_operations *ops = bdev->bd_disk->fops;
738 724
739 /* 725 if (pgoff)
740 * The device driver is allowed to sleep, in order to make the 726 *pgoff = PHYS_PFN(phys_off);
741 * memory directly accessible. 727 if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
742 */
743 might_sleep();
744
745 if (size < 0)
746 return size;
747 if (!blk_queue_dax(bdev_get_queue(bdev)) || !ops->direct_access)
748 return -EOPNOTSUPP;
749 if ((sector + DIV_ROUND_UP(size, 512)) >
750 part_nr_sects_read(bdev->bd_part))
751 return -ERANGE;
752 sector += get_start_sect(bdev);
753 if (sector % (PAGE_SIZE / 512))
754 return -EINVAL; 728 return -EINVAL;
755 avail = ops->direct_access(bdev, sector, &dax->addr, &dax->pfn, size); 729 return 0;
756 if (!avail)
757 return -ERANGE;
758 if (avail > 0 && avail & ~PAGE_MASK)
759 return -ENXIO;
760 return min(avail, size);
761} 730}
762EXPORT_SYMBOL_GPL(bdev_direct_access); 731EXPORT_SYMBOL(bdev_dax_pgoff);
763 732
764/** 733/**
765 * bdev_dax_supported() - Check if the device supports dax for filesystem 734 * bdev_dax_supported() - Check if the device supports dax for filesystem
@@ -773,62 +742,46 @@ EXPORT_SYMBOL_GPL(bdev_direct_access);
773 */ 742 */
774int bdev_dax_supported(struct super_block *sb, int blocksize) 743int bdev_dax_supported(struct super_block *sb, int blocksize)
775{ 744{
776 struct blk_dax_ctl dax = { 745 struct block_device *bdev = sb->s_bdev;
777 .sector = 0, 746 struct dax_device *dax_dev;
778 .size = PAGE_SIZE, 747 pgoff_t pgoff;
779 }; 748 int err, id;
780 int err; 749 void *kaddr;
750 pfn_t pfn;
751 long len;
781 752
782 if (blocksize != PAGE_SIZE) { 753 if (blocksize != PAGE_SIZE) {
783 vfs_msg(sb, KERN_ERR, "error: unsupported blocksize for dax"); 754 vfs_msg(sb, KERN_ERR, "error: unsupported blocksize for dax");
784 return -EINVAL; 755 return -EINVAL;
785 } 756 }
786 757
787 err = bdev_direct_access(sb->s_bdev, &dax); 758 err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
788 if (err < 0) { 759 if (err) {
789 switch (err) { 760 vfs_msg(sb, KERN_ERR, "error: unaligned partition for dax");
790 case -EOPNOTSUPP:
791 vfs_msg(sb, KERN_ERR,
792 "error: device does not support dax");
793 break;
794 case -EINVAL:
795 vfs_msg(sb, KERN_ERR,
796 "error: unaligned partition for dax");
797 break;
798 default:
799 vfs_msg(sb, KERN_ERR,
800 "error: dax access failed (%d)", err);
801 }
802 return err; 761 return err;
803 } 762 }
804 763
805 return 0; 764 dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
806} 765 if (!dax_dev) {
807EXPORT_SYMBOL_GPL(bdev_dax_supported); 766 vfs_msg(sb, KERN_ERR, "error: device does not support dax");
808 767 return -EOPNOTSUPP;
809/** 768 }
810 * bdev_dax_capable() - Return if the raw device is capable for dax
811 * @bdev: The device for raw block device access
812 */
813bool bdev_dax_capable(struct block_device *bdev)
814{
815 struct blk_dax_ctl dax = {
816 .size = PAGE_SIZE,
817 };
818 769
819 if (!IS_ENABLED(CONFIG_FS_DAX)) 770 id = dax_read_lock();
820 return false; 771 len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
772 dax_read_unlock(id);
821 773
822 dax.sector = 0; 774 put_dax(dax_dev);
823 if (bdev_direct_access(bdev, &dax) < 0)
824 return false;
825 775
826 dax.sector = bdev->bd_part->nr_sects - (PAGE_SIZE / 512); 776 if (len < 1) {
827 if (bdev_direct_access(bdev, &dax) < 0) 777 vfs_msg(sb, KERN_ERR,
828 return false; 778 "error: dax access failed (%ld)", len);
779 return len < 0 ? len : -EIO;
780 }
829 781
830 return true; 782 return 0;
831} 783}
784EXPORT_SYMBOL_GPL(bdev_dax_supported);
832 785
833/* 786/*
834 * pseudo-fs 787 * pseudo-fs