Commit 6e50b0f1 authored by Stephen Lord's avatar Stephen Lord Committed by Stephen Lord

Change XFS to support sector aligned O_DIRECT rather than filesystem block

alignment.
parent c4293751
......@@ -903,7 +903,7 @@ linvfs_get_block_core(
*/
if (create &&
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
(offset >= inode->i_size))) {
(offset >= inode->i_size) || (pbmap.pbm_flags & PBMF_NEW))) {
set_buffer_new(bh_result);
}
......@@ -968,10 +968,18 @@ linvfs_direct_IO(
loff_t offset,
unsigned long nr_segs)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
page_buf_bmap_t pbmap;
int maps = 1;
int error;
VOP_BMAP(vp, offset, 0, BMAP_DEVICE, &pbmap, &maps, error);
if (error)
return -error;
return blockdev_direct_IO(rw, iocb, inode, NULL,
return blockdev_direct_IO(rw, iocb, inode, pbmap.pbm_target->pbr_bdev,
iov, offset, nr_segs,
linvfs_get_blocks_direct,
linvfs_unwritten_convert_direct);
......
......@@ -624,15 +624,11 @@ xfs_ioctl(
case XFS_IOC_DIOINFO: {
struct dioattr da;
pb_target_t *target =
(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
/*
* this only really needs to be BBSIZE.
* it is set to the file system block size to
* avoid having to do block zeroing on short writes.
*/
da.d_miniosz = mp->m_sb.sb_blocksize;
da.d_mem = mp->m_sb.sb_blocksize;
da.d_mem = da.d_miniosz = 1 << target->pbr_sshift;
/* The size dio will do in one go */
da.d_maxiosz = 64 * PAGE_CACHE_SIZE;
......
......@@ -77,6 +77,7 @@ STATIC int
_xfs_imap_to_bmap(
xfs_iocore_t *io,
xfs_off_t offset,
int new,
xfs_bmbt_irec_t *imap,
page_buf_bmap_t *pbmapp,
int imaps, /* Number of imap entries */
......@@ -117,6 +118,9 @@ _xfs_imap_to_bmap(
pbmapp->pbm_flags |= PBMF_EOF;
}
if (new)
pbmapp->pbm_flags |= PBMF_NEW;
offset += pbmapp->pbm_bsize - pbmapp->pbm_delta;
}
return pbm; /* Return the number filled */
......@@ -134,16 +138,18 @@ xfs_iomap(
xfs_mount_t *mp = io->io_mount;
xfs_fileoff_t offset_fsb, end_fsb;
int error = 0;
int new = 0;
int lockmode = 0;
xfs_bmbt_irec_t imap;
int nimaps = 1;
int bmap_flags = 0;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
return -XFS_ERROR(EIO);
switch (flags &
(BMAP_READ|BMAP_WRITE|BMAP_ALLOCATE|BMAP_UNWRITTEN)) {
(BMAP_READ | BMAP_WRITE | BMAP_ALLOCATE |
BMAP_UNWRITTEN | BMAP_DEVICE)) {
case BMAP_READ:
lockmode = XFS_LCK_MAP_SHARED(mp, io);
bmap_flags = XFS_BMAPI_ENTIRE;
......@@ -168,6 +174,13 @@ xfs_iomap(
break;
case BMAP_UNWRITTEN:
goto phase2;
case BMAP_DEVICE:
lockmode = XFS_LCK_MAP_SHARED(mp, io);
pbmapp->pbm_target = io->io_flags & XFS_IOCORE_RT ?
mp->m_rtdev_targp : mp->m_ddev_targp;
error = 0;
*npbmaps = 1;
goto out;
default:
BUG();
}
......@@ -200,6 +213,7 @@ xfs_iomap(
error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count,
flags, &imap, &nimaps);
}
new = 1;
break;
case BMAP_ALLOCATE:
/* If we found an extent, return it */
......@@ -219,8 +233,8 @@ xfs_iomap(
}
if (nimaps) {
*npbmaps = _xfs_imap_to_bmap(io, offset, &imap,
pbmapp, nimaps, *npbmaps);
*npbmaps = _xfs_imap_to_bmap(io, offset, new, &imap,
pbmapp, nimaps, *npbmaps);
} else if (npbmaps) {
*npbmaps = 0;
}
......
......@@ -184,8 +184,11 @@ xfs_read(
/* END copy & waste from filemap.c */
if (direct) {
if ((*offset & mp->m_blockmask) ||
(size & mp->m_blockmask)) {
pb_target_t *target =
(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
if ((*offset & target->pbr_smask) ||
(size & target->pbr_smask)) {
if (*offset == ip->i_d.di_size) {
return (0);
}
......@@ -566,8 +569,12 @@ xfs_write(
}
if (direct) {
if ((*offset & mp->m_blockmask) ||
(size & mp->m_blockmask)) {
pb_target_t *target =
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
if ((*offset & target->pbr_smask) ||
(size & target->pbr_smask)) {
return XFS_ERROR(-EINVAL);
}
iolock = XFS_IOLOCK_SHARED;
......
......@@ -79,8 +79,9 @@ typedef enum { /* pbm_flags values */
PBMF_EOF = 0x01, /* mapping contains EOF */
PBMF_HOLE = 0x02, /* mapping covers a hole */
PBMF_DELAY = 0x04, /* mapping covers delalloc region */
PBMF_UNWRITTEN = 0x20 /* mapping covers allocated */
PBMF_UNWRITTEN = 0x20, /* mapping covers allocated */
/* but uninitialized file data */
PBMF_NEW = 0x40 /* just allocated */
} bmap_flags_t;
typedef enum {
......@@ -95,6 +96,7 @@ typedef enum {
BMAP_MMAP = (1 << 6), /* allocate for mmap write */
BMAP_SYNC = (1 << 7), /* sync write */
BMAP_TRYLOCK = (1 << 8), /* non-blocking request */
BMAP_DEVICE = (1 << 9), /* we only want to know the device */
} bmapi_flags_t;
typedef enum page_buf_flags_e { /* pb_flags values */
......
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