Commit f1499382 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 4db658ea 7c71ee78
...@@ -445,8 +445,8 @@ _xfs_buf_find( ...@@ -445,8 +445,8 @@ _xfs_buf_find(
numbytes = BBTOB(numblks); numbytes = BBTOB(numblks);
/* Check for IOs smaller than the sector size / not sector aligned */ /* Check for IOs smaller than the sector size / not sector aligned */
ASSERT(!(numbytes < (1 << btp->bt_sshift))); ASSERT(!(numbytes < btp->bt_meta_sectorsize));
ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_smask)); ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_meta_sectormask));
/* /*
* Corrupted block numbers can get through to here, unfortunately, so we * Corrupted block numbers can get through to here, unfortunately, so we
...@@ -1599,9 +1599,9 @@ xfs_setsize_buftarg( ...@@ -1599,9 +1599,9 @@ xfs_setsize_buftarg(
unsigned int blocksize, unsigned int blocksize,
unsigned int sectorsize) unsigned int sectorsize)
{ {
btp->bt_bsize = blocksize; /* Set up metadata sector size info */
btp->bt_sshift = ffs(sectorsize) - 1; btp->bt_meta_sectorsize = sectorsize;
btp->bt_smask = sectorsize - 1; btp->bt_meta_sectormask = sectorsize - 1;
if (set_blocksize(btp->bt_bdev, sectorsize)) { if (set_blocksize(btp->bt_bdev, sectorsize)) {
char name[BDEVNAME_SIZE]; char name[BDEVNAME_SIZE];
...@@ -1614,6 +1614,10 @@ xfs_setsize_buftarg( ...@@ -1614,6 +1614,10 @@ xfs_setsize_buftarg(
return EINVAL; return EINVAL;
} }
/* Set up device logical sector size mask */
btp->bt_logical_sectorsize = bdev_logical_block_size(btp->bt_bdev);
btp->bt_logical_sectormask = bdev_logical_block_size(btp->bt_bdev) - 1;
return 0; return 0;
} }
......
...@@ -88,14 +88,28 @@ typedef unsigned int xfs_buf_flags_t; ...@@ -88,14 +88,28 @@ typedef unsigned int xfs_buf_flags_t;
*/ */
#define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */ #define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */
/*
* The xfs_buftarg contains 2 notions of "sector size" -
*
* 1) The metadata sector size, which is the minimum unit and
* alignment of IO which will be performed by metadata operations.
* 2) The device logical sector size
*
* The first is specified at mkfs time, and is stored on-disk in the
* superblock's sb_sectsize.
*
* The latter is derived from the underlying device, and controls direct IO
* alignment constraints.
*/
typedef struct xfs_buftarg { typedef struct xfs_buftarg {
dev_t bt_dev; dev_t bt_dev;
struct block_device *bt_bdev; struct block_device *bt_bdev;
struct backing_dev_info *bt_bdi; struct backing_dev_info *bt_bdi;
struct xfs_mount *bt_mount; struct xfs_mount *bt_mount;
unsigned int bt_bsize; unsigned int bt_meta_sectorsize;
unsigned int bt_sshift; size_t bt_meta_sectormask;
size_t bt_smask; size_t bt_logical_sectorsize;
size_t bt_logical_sectormask;
/* LRU control structures */ /* LRU control structures */
struct shrinker bt_shrinker; struct shrinker bt_shrinker;
......
...@@ -261,7 +261,8 @@ xfs_file_aio_read( ...@@ -261,7 +261,8 @@ xfs_file_aio_read(
xfs_buftarg_t *target = xfs_buftarg_t *target =
XFS_IS_REALTIME_INODE(ip) ? XFS_IS_REALTIME_INODE(ip) ?
mp->m_rtdev_targp : mp->m_ddev_targp; mp->m_rtdev_targp : mp->m_ddev_targp;
if ((pos & target->bt_smask) || (size & target->bt_smask)) { /* DIO must be aligned to device logical sector size */
if ((pos | size) & target->bt_logical_sectormask) {
if (pos == i_size_read(inode)) if (pos == i_size_read(inode))
return 0; return 0;
return -XFS_ERROR(EINVAL); return -XFS_ERROR(EINVAL);
...@@ -641,9 +642,11 @@ xfs_file_dio_aio_write( ...@@ -641,9 +642,11 @@ xfs_file_dio_aio_write(
struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ?
mp->m_rtdev_targp : mp->m_ddev_targp; mp->m_rtdev_targp : mp->m_ddev_targp;
if ((pos & target->bt_smask) || (count & target->bt_smask)) /* DIO must be aligned to device logical sector size */
if ((pos | count) & target->bt_logical_sectormask)
return -XFS_ERROR(EINVAL); return -XFS_ERROR(EINVAL);
/* "unaligned" here means not aligned to a filesystem block */
if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask))
unaligned_io = 1; unaligned_io = 1;
......
...@@ -1583,7 +1583,7 @@ xfs_file_ioctl( ...@@ -1583,7 +1583,7 @@ xfs_file_ioctl(
XFS_IS_REALTIME_INODE(ip) ? XFS_IS_REALTIME_INODE(ip) ?
mp->m_rtdev_targp : mp->m_ddev_targp; mp->m_rtdev_targp : mp->m_ddev_targp;
da.d_mem = da.d_miniosz = 1 << target->bt_sshift; da.d_mem = da.d_miniosz = target->bt_logical_sectorsize;
da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
if (copy_to_user(arg, &da, sizeof(da))) if (copy_to_user(arg, &da, sizeof(da)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment