diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2017-08-24 18:12:50 -0400 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2017-08-31 12:31:47 -0400 |
| commit | 486aff5e04823bb1e60c4045226eb244024b8420 (patch) | |
| tree | c0cc960b998086e92873d918f203a5e737e97db6 /fs/xfs | |
| parent | 78f35473508118df5ea04b9515ac3f1aaec0a980 (diff) | |
xfs: perform dax_device lookup at mount
The ->iomap_begin() operation is a hot path, so cache the
fs_dax_get_by_host() result at mount time to avoid the incurring the
hash lookup overhead on a per-i/o basis.
Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'fs/xfs')
| -rw-r--r-- | fs/xfs/xfs_aops.c | 13 | ||||
| -rw-r--r-- | fs/xfs/xfs_aops.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf.c | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf.h | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_iomap.c | 10 | ||||
| -rw-r--r-- | fs/xfs/xfs_super.c | 25 |
6 files changed, 41 insertions, 15 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 6bf120bb1a17..78185f3b10b2 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
| @@ -80,6 +80,19 @@ xfs_find_bdev_for_inode( | |||
| 80 | return mp->m_ddev_targp->bt_bdev; | 80 | return mp->m_ddev_targp->bt_bdev; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | struct dax_device * | ||
| 84 | xfs_find_daxdev_for_inode( | ||
| 85 | struct inode *inode) | ||
| 86 | { | ||
| 87 | struct xfs_inode *ip = XFS_I(inode); | ||
| 88 | struct xfs_mount *mp = ip->i_mount; | ||
| 89 | |||
| 90 | if (XFS_IS_REALTIME_INODE(ip)) | ||
| 91 | return mp->m_rtdev_targp->bt_daxdev; | ||
| 92 | else | ||
| 93 | return mp->m_ddev_targp->bt_daxdev; | ||
| 94 | } | ||
| 95 | |||
| 83 | /* | 96 | /* |
| 84 | * We're now finished for good with this page. Update the page state via the | 97 | * We're now finished for good with this page. Update the page state via the |
| 85 | * associated buffer_heads, paying attention to the start and end offsets that | 98 | * associated buffer_heads, paying attention to the start and end offsets that |
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index cc174ec6c2fd..88c85ea63da0 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h | |||
| @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size); | |||
| 59 | 59 | ||
| 60 | extern void xfs_count_page_state(struct page *, int *, int *); | 60 | extern void xfs_count_page_state(struct page *, int *, int *); |
| 61 | extern struct block_device *xfs_find_bdev_for_inode(struct inode *); | 61 | extern struct block_device *xfs_find_bdev_for_inode(struct inode *); |
| 62 | extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *); | ||
| 62 | 63 | ||
| 63 | #endif /* __XFS_AOPS_H__ */ | 64 | #endif /* __XFS_AOPS_H__ */ |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 72f038492ba8..6deb86c845d1 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
| @@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early( | |||
| 1802 | xfs_buftarg_t * | 1802 | xfs_buftarg_t * |
| 1803 | xfs_alloc_buftarg( | 1803 | xfs_alloc_buftarg( |
| 1804 | struct xfs_mount *mp, | 1804 | struct xfs_mount *mp, |
| 1805 | struct block_device *bdev) | 1805 | struct block_device *bdev, |
| 1806 | struct dax_device *dax_dev) | ||
| 1806 | { | 1807 | { |
| 1807 | xfs_buftarg_t *btp; | 1808 | xfs_buftarg_t *btp; |
| 1808 | 1809 | ||
| @@ -1811,6 +1812,7 @@ xfs_alloc_buftarg( | |||
| 1811 | btp->bt_mount = mp; | 1812 | btp->bt_mount = mp; |
| 1812 | btp->bt_dev = bdev->bd_dev; | 1813 | btp->bt_dev = bdev->bd_dev; |
| 1813 | btp->bt_bdev = bdev; | 1814 | btp->bt_bdev = bdev; |
| 1815 | btp->bt_daxdev = dax_dev; | ||
| 1814 | 1816 | ||
| 1815 | if (xfs_setsize_buftarg_early(btp, bdev)) | 1817 | if (xfs_setsize_buftarg_early(btp, bdev)) |
| 1816 | goto error; | 1818 | goto error; |
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 20721261dae5..bf71507ddb16 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
| @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t; | |||
| 108 | typedef struct xfs_buftarg { | 108 | typedef struct xfs_buftarg { |
| 109 | dev_t bt_dev; | 109 | dev_t bt_dev; |
| 110 | struct block_device *bt_bdev; | 110 | struct block_device *bt_bdev; |
| 111 | struct dax_device *bt_daxdev; | ||
| 111 | struct xfs_mount *bt_mount; | 112 | struct xfs_mount *bt_mount; |
| 112 | unsigned int bt_meta_sectorsize; | 113 | unsigned int bt_meta_sectorsize; |
| 113 | size_t bt_meta_sectormask; | 114 | size_t bt_meta_sectormask; |
| @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset) | |||
| 385 | * Handling of buftargs. | 386 | * Handling of buftargs. |
| 386 | */ | 387 | */ |
| 387 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *, | 388 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *, |
| 388 | struct block_device *); | 389 | struct block_device *, struct dax_device *); |
| 389 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); | 390 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); |
| 390 | extern void xfs_wait_buftarg(xfs_buftarg_t *); | 391 | extern void xfs_wait_buftarg(xfs_buftarg_t *); |
| 391 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int); | 392 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int); |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 813394c62849..7c934e407332 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
| @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap( | |||
| 69 | iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff); | 69 | iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff); |
| 70 | iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount); | 70 | iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount); |
| 71 | iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip)); | 71 | iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip)); |
| 72 | iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip)); | ||
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | xfs_extlen_t | 75 | xfs_extlen_t |
| @@ -976,7 +977,6 @@ xfs_file_iomap_begin( | |||
| 976 | int nimaps = 1, error = 0; | 977 | int nimaps = 1, error = 0; |
| 977 | bool shared = false, trimmed = false; | 978 | bool shared = false, trimmed = false; |
| 978 | unsigned lockmode; | 979 | unsigned lockmode; |
| 979 | struct block_device *bdev; | ||
| 980 | 980 | ||
| 981 | if (XFS_FORCED_SHUTDOWN(mp)) | 981 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 982 | return -EIO; | 982 | return -EIO; |
| @@ -1087,13 +1087,6 @@ xfs_file_iomap_begin( | |||
| 1087 | 1087 | ||
| 1088 | xfs_bmbt_to_iomap(ip, iomap, &imap); | 1088 | xfs_bmbt_to_iomap(ip, iomap, &imap); |
| 1089 | 1089 | ||
| 1090 | /* optionally associate a dax device with the iomap bdev */ | ||
| 1091 | bdev = iomap->bdev; | ||
| 1092 | if (blk_queue_dax(bdev->bd_queue)) | ||
| 1093 | iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name); | ||
| 1094 | else | ||
| 1095 | iomap->dax_dev = NULL; | ||
| 1096 | |||
| 1097 | if (shared) | 1090 | if (shared) |
| 1098 | iomap->flags |= IOMAP_F_SHARED; | 1091 | iomap->flags |= IOMAP_F_SHARED; |
| 1099 | return 0; | 1092 | return 0; |
| @@ -1171,7 +1164,6 @@ xfs_file_iomap_end( | |||
| 1171 | unsigned flags, | 1164 | unsigned flags, |
| 1172 | struct iomap *iomap) | 1165 | struct iomap *iomap) |
| 1173 | { | 1166 | { |
| 1174 | fs_put_dax(iomap->dax_dev); | ||
| 1175 | if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC) | 1167 | if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC) |
| 1176 | return xfs_file_iomap_end_delalloc(XFS_I(inode), offset, | 1168 | return xfs_file_iomap_end_delalloc(XFS_I(inode), offset, |
| 1177 | length, written, iomap); | 1169 | length, written, iomap); |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 38aaacdbb8b3..ee4225c65f0c 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
| @@ -714,17 +714,26 @@ STATIC void | |||
| 714 | xfs_close_devices( | 714 | xfs_close_devices( |
| 715 | struct xfs_mount *mp) | 715 | struct xfs_mount *mp) |
| 716 | { | 716 | { |
| 717 | struct dax_device *dax_ddev = mp->m_ddev_targp->bt_daxdev; | ||
| 718 | |||
| 717 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 719 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
| 718 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; | 720 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; |
| 721 | struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev; | ||
| 722 | |||
| 719 | xfs_free_buftarg(mp, mp->m_logdev_targp); | 723 | xfs_free_buftarg(mp, mp->m_logdev_targp); |
| 720 | xfs_blkdev_put(logdev); | 724 | xfs_blkdev_put(logdev); |
| 725 | fs_put_dax(dax_logdev); | ||
| 721 | } | 726 | } |
| 722 | if (mp->m_rtdev_targp) { | 727 | if (mp->m_rtdev_targp) { |
| 723 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; | 728 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; |
| 729 | struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev; | ||
| 730 | |||
| 724 | xfs_free_buftarg(mp, mp->m_rtdev_targp); | 731 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
| 725 | xfs_blkdev_put(rtdev); | 732 | xfs_blkdev_put(rtdev); |
| 733 | fs_put_dax(dax_rtdev); | ||
| 726 | } | 734 | } |
| 727 | xfs_free_buftarg(mp, mp->m_ddev_targp); | 735 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
| 736 | fs_put_dax(dax_ddev); | ||
| 728 | } | 737 | } |
| 729 | 738 | ||
| 730 | /* | 739 | /* |
| @@ -742,6 +751,8 @@ xfs_open_devices( | |||
| 742 | struct xfs_mount *mp) | 751 | struct xfs_mount *mp) |
| 743 | { | 752 | { |
| 744 | struct block_device *ddev = mp->m_super->s_bdev; | 753 | struct block_device *ddev = mp->m_super->s_bdev; |
| 754 | struct dax_device *dax_ddev = fs_dax_get_by_bdev(ddev); | ||
| 755 | struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL; | ||
| 745 | struct block_device *logdev = NULL, *rtdev = NULL; | 756 | struct block_device *logdev = NULL, *rtdev = NULL; |
| 746 | int error; | 757 | int error; |
| 747 | 758 | ||
| @@ -752,6 +763,7 @@ xfs_open_devices( | |||
| 752 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); | 763 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); |
| 753 | if (error) | 764 | if (error) |
| 754 | goto out; | 765 | goto out; |
| 766 | dax_logdev = fs_dax_get_by_bdev(logdev); | ||
| 755 | } | 767 | } |
| 756 | 768 | ||
| 757 | if (mp->m_rtname) { | 769 | if (mp->m_rtname) { |
| @@ -765,24 +777,25 @@ xfs_open_devices( | |||
| 765 | error = -EINVAL; | 777 | error = -EINVAL; |
| 766 | goto out_close_rtdev; | 778 | goto out_close_rtdev; |
| 767 | } | 779 | } |
| 780 | dax_rtdev = fs_dax_get_by_bdev(rtdev); | ||
| 768 | } | 781 | } |
| 769 | 782 | ||
| 770 | /* | 783 | /* |
| 771 | * Setup xfs_mount buffer target pointers | 784 | * Setup xfs_mount buffer target pointers |
| 772 | */ | 785 | */ |
| 773 | error = -ENOMEM; | 786 | error = -ENOMEM; |
| 774 | mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev); | 787 | mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev); |
| 775 | if (!mp->m_ddev_targp) | 788 | if (!mp->m_ddev_targp) |
| 776 | goto out_close_rtdev; | 789 | goto out_close_rtdev; |
| 777 | 790 | ||
| 778 | if (rtdev) { | 791 | if (rtdev) { |
| 779 | mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev); | 792 | mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev); |
| 780 | if (!mp->m_rtdev_targp) | 793 | if (!mp->m_rtdev_targp) |
| 781 | goto out_free_ddev_targ; | 794 | goto out_free_ddev_targ; |
| 782 | } | 795 | } |
| 783 | 796 | ||
| 784 | if (logdev && logdev != ddev) { | 797 | if (logdev && logdev != ddev) { |
| 785 | mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev); | 798 | mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev); |
| 786 | if (!mp->m_logdev_targp) | 799 | if (!mp->m_logdev_targp) |
| 787 | goto out_free_rtdev_targ; | 800 | goto out_free_rtdev_targ; |
| 788 | } else { | 801 | } else { |
| @@ -798,10 +811,14 @@ xfs_open_devices( | |||
| 798 | xfs_free_buftarg(mp, mp->m_ddev_targp); | 811 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
| 799 | out_close_rtdev: | 812 | out_close_rtdev: |
| 800 | xfs_blkdev_put(rtdev); | 813 | xfs_blkdev_put(rtdev); |
| 814 | fs_put_dax(dax_rtdev); | ||
| 801 | out_close_logdev: | 815 | out_close_logdev: |
| 802 | if (logdev && logdev != ddev) | 816 | if (logdev && logdev != ddev) { |
| 803 | xfs_blkdev_put(logdev); | 817 | xfs_blkdev_put(logdev); |
| 818 | fs_put_dax(dax_logdev); | ||
| 819 | } | ||
| 804 | out: | 820 | out: |
| 821 | fs_put_dax(dax_ddev); | ||
| 805 | return error; | 822 | return error; |
| 806 | } | 823 | } |
| 807 | 824 | ||
