aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 21:21:22 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 21:21:22 -0500
commitf1499382f114231cbd1e3dee7e656b50ce9d8236 (patch)
tree0304f857428b3f5f4eac6dd9ebaa4ceef2b28d91
parent4db658ea0ca2312b5d168230476ec7729385aefe (diff)
parent7c71ee78031c248dca13fc94dea9a4cc217db6cf (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.c14
-rw-r--r--fs/xfs/xfs_buf.h20
-rw-r--r--fs/xfs/xfs_file.c7
-rw-r--r--fs/xfs/xfs_ioctl.c2
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 */
91typedef struct xfs_buftarg { 104typedef 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)))