diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-28 21:21:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-28 21:21:22 -0500 |
commit | f1499382f114231cbd1e3dee7e656b50ce9d8236 (patch) | |
tree | 0304f857428b3f5f4eac6dd9ebaa4ceef2b28d91 | |
parent | 4db658ea0ca2312b5d168230476ec7729385aefe (diff) | |
parent | 7c71ee78031c248dca13fc94dea9a4cc217db6cf (diff) |
Merge tag 'xfs-for-linus-v3.14-rc1-2' of git://oss.sgi.com/xfs/xfs
Pull second xfs update from Ben Myers:
"Allow logical sector sized direct io on 'advanced format' 4k/512 disk"
* tag 'xfs-for-linus-v3.14-rc1-2' of git://oss.sgi.com/xfs/xfs:
xfs: allow logical-sector sized O_DIRECT
xfs: rename xfs_buftarg structure members
xfs: clean up xfs_buftarg
-rw-r--r-- | fs/xfs/xfs_buf.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.h | 20 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 2 |
4 files changed, 32 insertions, 11 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 9fccfb594291..51757113a822 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -445,8 +445,8 @@ _xfs_buf_find( | |||
445 | numbytes = BBTOB(numblks); | 445 | numbytes = BBTOB(numblks); |
446 | 446 | ||
447 | /* Check for IOs smaller than the sector size / not sector aligned */ | 447 | /* Check for IOs smaller than the sector size / not sector aligned */ |
448 | ASSERT(!(numbytes < (1 << btp->bt_sshift))); | 448 | ASSERT(!(numbytes < btp->bt_meta_sectorsize)); |
449 | ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_smask)); | 449 | ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_meta_sectormask)); |
450 | 450 | ||
451 | /* | 451 | /* |
452 | * Corrupted block numbers can get through to here, unfortunately, so we | 452 | * Corrupted block numbers can get through to here, unfortunately, so we |
@@ -1599,9 +1599,9 @@ xfs_setsize_buftarg( | |||
1599 | unsigned int blocksize, | 1599 | unsigned int blocksize, |
1600 | unsigned int sectorsize) | 1600 | unsigned int sectorsize) |
1601 | { | 1601 | { |
1602 | btp->bt_bsize = blocksize; | 1602 | /* Set up metadata sector size info */ |
1603 | btp->bt_sshift = ffs(sectorsize) - 1; | 1603 | btp->bt_meta_sectorsize = sectorsize; |
1604 | btp->bt_smask = sectorsize - 1; | 1604 | btp->bt_meta_sectormask = sectorsize - 1; |
1605 | 1605 | ||
1606 | if (set_blocksize(btp->bt_bdev, sectorsize)) { | 1606 | if (set_blocksize(btp->bt_bdev, sectorsize)) { |
1607 | char name[BDEVNAME_SIZE]; | 1607 | char name[BDEVNAME_SIZE]; |
@@ -1614,6 +1614,10 @@ xfs_setsize_buftarg( | |||
1614 | return EINVAL; | 1614 | return EINVAL; |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | /* Set up device logical sector size mask */ | ||
1618 | btp->bt_logical_sectorsize = bdev_logical_block_size(btp->bt_bdev); | ||
1619 | btp->bt_logical_sectormask = bdev_logical_block_size(btp->bt_bdev) - 1; | ||
1620 | |||
1617 | return 0; | 1621 | return 0; |
1618 | } | 1622 | } |
1619 | 1623 | ||
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 1cf21a4a9f22..995339534db6 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
@@ -88,14 +88,28 @@ typedef unsigned int xfs_buf_flags_t; | |||
88 | */ | 88 | */ |
89 | #define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */ | 89 | #define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */ |
90 | 90 | ||
91 | /* | ||
92 | * The xfs_buftarg contains 2 notions of "sector size" - | ||
93 | * | ||
94 | * 1) The metadata sector size, which is the minimum unit and | ||
95 | * alignment of IO which will be performed by metadata operations. | ||
96 | * 2) The device logical sector size | ||
97 | * | ||
98 | * The first is specified at mkfs time, and is stored on-disk in the | ||
99 | * superblock's sb_sectsize. | ||
100 | * | ||
101 | * The latter is derived from the underlying device, and controls direct IO | ||
102 | * alignment constraints. | ||
103 | */ | ||
91 | typedef struct xfs_buftarg { | 104 | typedef struct xfs_buftarg { |
92 | dev_t bt_dev; | 105 | dev_t bt_dev; |
93 | struct block_device *bt_bdev; | 106 | struct block_device *bt_bdev; |
94 | struct backing_dev_info *bt_bdi; | 107 | struct backing_dev_info *bt_bdi; |
95 | struct xfs_mount *bt_mount; | 108 | struct xfs_mount *bt_mount; |
96 | unsigned int bt_bsize; | 109 | unsigned int bt_meta_sectorsize; |
97 | unsigned int bt_sshift; | 110 | size_t bt_meta_sectormask; |
98 | size_t bt_smask; | 111 | size_t bt_logical_sectorsize; |
112 | size_t bt_logical_sectormask; | ||
99 | 113 | ||
100 | /* LRU control structures */ | 114 | /* LRU control structures */ |
101 | struct shrinker bt_shrinker; | 115 | struct shrinker bt_shrinker; |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e00121592632..2e7989e3a2d6 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -261,7 +261,8 @@ xfs_file_aio_read( | |||
261 | xfs_buftarg_t *target = | 261 | xfs_buftarg_t *target = |
262 | XFS_IS_REALTIME_INODE(ip) ? | 262 | XFS_IS_REALTIME_INODE(ip) ? |
263 | mp->m_rtdev_targp : mp->m_ddev_targp; | 263 | mp->m_rtdev_targp : mp->m_ddev_targp; |
264 | if ((pos & target->bt_smask) || (size & target->bt_smask)) { | 264 | /* DIO must be aligned to device logical sector size */ |
265 | if ((pos | size) & target->bt_logical_sectormask) { | ||
265 | if (pos == i_size_read(inode)) | 266 | if (pos == i_size_read(inode)) |
266 | return 0; | 267 | return 0; |
267 | return -XFS_ERROR(EINVAL); | 268 | return -XFS_ERROR(EINVAL); |
@@ -641,9 +642,11 @@ xfs_file_dio_aio_write( | |||
641 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? | 642 | struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? |
642 | mp->m_rtdev_targp : mp->m_ddev_targp; | 643 | mp->m_rtdev_targp : mp->m_ddev_targp; |
643 | 644 | ||
644 | if ((pos & target->bt_smask) || (count & target->bt_smask)) | 645 | /* DIO must be aligned to device logical sector size */ |
646 | if ((pos | count) & target->bt_logical_sectormask) | ||
645 | return -XFS_ERROR(EINVAL); | 647 | return -XFS_ERROR(EINVAL); |
646 | 648 | ||
649 | /* "unaligned" here means not aligned to a filesystem block */ | ||
647 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) | 650 | if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) |
648 | unaligned_io = 1; | 651 | unaligned_io = 1; |
649 | 652 | ||
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 518aa56b8f2e..bcfe61202115 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -1583,7 +1583,7 @@ xfs_file_ioctl( | |||
1583 | XFS_IS_REALTIME_INODE(ip) ? | 1583 | XFS_IS_REALTIME_INODE(ip) ? |
1584 | mp->m_rtdev_targp : mp->m_ddev_targp; | 1584 | mp->m_rtdev_targp : mp->m_ddev_targp; |
1585 | 1585 | ||
1586 | da.d_mem = da.d_miniosz = 1 << target->bt_sshift; | 1586 | da.d_mem = da.d_miniosz = target->bt_logical_sectorsize; |
1587 | da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); | 1587 | da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); |
1588 | 1588 | ||
1589 | if (copy_to_user(arg, &da, sizeof(da))) | 1589 | if (copy_to_user(arg, &da, sizeof(da))) |