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