Commit 8a5d8dd8 authored by Russell Cattelan's avatar Russell Cattelan Committed by Nathan Scott

[XFS] move the iomap data structures out of pagebuf

SGI Modid: 2.5.x-xfs:slinx:162048a
parent db46361e
......@@ -51,10 +51,11 @@
#include "xfs_inode.h"
#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_iomap.h"
#include <linux/mpage.h>
STATIC void convert_page(struct inode *, struct page *,
page_buf_bmap_t *, void *, int, int);
xfs_iomap_t *, void *, int, int);
void
linvfs_unwritten_done(
......@@ -87,7 +88,7 @@ linvfs_unwritten_convert(
BUG_ON(atomic_read(&bp->pb_hold) < 1);
VOP_BMAP(vp, XFS_BUF_OFFSET(bp), XFS_BUF_SIZE(bp),
BMAP_UNWRITTEN, NULL, NULL, error);
BMAPI_UNWRITTEN, NULL, NULL, error);
XFS_BUF_SET_FSPRIVATE(bp, NULL);
XFS_BUF_CLR_IODONE_FUNC(bp);
XFS_BUF_UNDATAIO(bp);
......@@ -115,7 +116,7 @@ linvfs_unwritten_convert_direct(
vnode_t *vp = LINVFS_GET_VP(inode);
int error;
VOP_BMAP(vp, offset, size, BMAP_UNWRITTEN, NULL, NULL, error);
VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);
}
}
......@@ -124,26 +125,26 @@ map_blocks(
struct inode *inode,
loff_t offset,
ssize_t count,
page_buf_bmap_t *pbmapp,
xfs_iomap_t *iomapp,
int flags)
{
vnode_t *vp = LINVFS_GET_VP(inode);
int error, nmaps = 1;
int error, niomaps = 1;
if (((flags & (BMAP_DIRECT|BMAP_SYNC)) == BMAP_DIRECT) &&
if (((flags & (BMAPI_DIRECT|BMAPI_SYNC)) == BMAPI_DIRECT) &&
(offset >= i_size_read(inode)))
count = max_t(ssize_t, count, XFS_WRITE_IO_LOG);
retry:
VOP_BMAP(vp, offset, count, flags, pbmapp, &nmaps, error);
VOP_BMAP(vp, offset, count, flags, iomapp, &niomaps, error);
if ((error == EAGAIN) || (error == EIO))
return -error;
if (unlikely((flags & (BMAP_WRITE|BMAP_DIRECT)) ==
(BMAP_WRITE|BMAP_DIRECT) && nmaps &&
(pbmapp->pbm_flags & PBMF_DELAY))) {
flags = BMAP_ALLOCATE;
if (unlikely((flags & (BMAPI_WRITE|BMAPI_DIRECT)) ==
(BMAPI_WRITE|BMAPI_DIRECT) && niomaps &&
(iomapp->iomap_flags & IOMAP_DELAY))) {
flags = BMAPI_ALLOCATE;
goto retry;
}
if (flags & (BMAP_WRITE|BMAP_ALLOCATE)) {
if (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) {
VMODIFY(vp);
}
return -error;
......@@ -154,10 +155,10 @@ map_blocks(
* Finds the corresponding mapping in block @map array of the
* given @offset within a @page.
*/
STATIC page_buf_bmap_t *
STATIC xfs_iomap_t *
match_offset_to_mapping(
struct page *page,
page_buf_bmap_t *map,
xfs_iomap_t *iomapp,
unsigned long offset)
{
loff_t full_offset; /* offset from start of file */
......@@ -168,10 +169,10 @@ match_offset_to_mapping(
full_offset <<= PAGE_CACHE_SHIFT; /* offset from file start */
full_offset += offset; /* offset from page start */
if (full_offset < map->pbm_offset)
if (full_offset < iomapp->iomap_offset)
return NULL;
if (map->pbm_offset + map->pbm_bsize > full_offset)
return map;
if (iomapp->iomap_offset + iomapp->iomap_bsize > full_offset)
return iomapp;
return NULL;
}
......@@ -181,30 +182,30 @@ map_buffer_at_offset(
struct buffer_head *bh,
unsigned long offset,
int block_bits,
page_buf_bmap_t *mp)
xfs_iomap_t *iomapp)
{
page_buf_daddr_t bn;
loff_t delta;
int sector_shift;
ASSERT(!(mp->pbm_flags & PBMF_HOLE));
ASSERT(!(mp->pbm_flags & PBMF_DELAY));
ASSERT(mp->pbm_bn != PAGE_BUF_DADDR_NULL);
ASSERT(!(iomapp->iomap_flags & IOMAP_HOLE));
ASSERT(!(iomapp->iomap_flags & IOMAP_DELAY));
ASSERT(iomapp->iomap_bn != PAGE_BUF_DADDR_NULL);
delta = page->index;
delta <<= PAGE_CACHE_SHIFT;
delta += offset;
delta -= mp->pbm_offset;
delta -= iomapp->iomap_offset;
delta >>= block_bits;
sector_shift = block_bits - BBSHIFT;
bn = mp->pbm_bn >> sector_shift;
bn = iomapp->iomap_bn >> sector_shift;
bn += delta;
ASSERT((bn << sector_shift) >= mp->pbm_bn);
ASSERT((bn << sector_shift) >= iomapp->iomap_bn);
lock_buffer(bh);
bh->b_blocknr = bn;
bh->b_bdev = mp->pbm_target->pbr_bdev;
bh->b_bdev = iomapp->iomap_target->pbr_bdev;
set_buffer_mapped(bh);
clear_buffer_delay(bh);
}
......@@ -220,7 +221,7 @@ STATIC struct page *
probe_unwritten_page(
struct address_space *mapping,
unsigned long index,
page_buf_bmap_t *mp,
xfs_iomap_t *iomapp,
page_buf_t *pb,
unsigned long max_offset,
unsigned long *fsbs,
......@@ -243,11 +244,11 @@ probe_unwritten_page(
do {
if (!buffer_unwritten(bh))
break;
if (!match_offset_to_mapping(page, mp, p_offset))
if (!match_offset_to_mapping(page, iomapp, p_offset))
break;
if (p_offset >= max_offset)
break;
map_buffer_at_offset(page, bh, p_offset, bbits, mp);
map_buffer_at_offset(page, bh, p_offset, bbits, iomapp);
set_buffer_unwritten_io(bh);
bh->b_private = pb;
p_offset += bh->b_size;
......@@ -392,11 +393,11 @@ map_unwritten(
struct buffer_head *curr,
unsigned long p_offset,
int block_bits,
page_buf_bmap_t *mp,
xfs_iomap_t *iomapp,
int all_bh)
{
struct buffer_head *bh = curr;
page_buf_bmap_t *tmp;
xfs_iomap_t *tmp;
page_buf_t *pb;
loff_t offset, size;
unsigned long nblocks = 0;
......@@ -405,8 +406,8 @@ map_unwritten(
offset <<= PAGE_CACHE_SHIFT;
offset += p_offset;
pb = pagebuf_lookup(mp->pbm_target,
mp->pbm_offset, mp->pbm_bsize, 0);
pb = pagebuf_lookup(iomapp->iomap_target,
iomapp->iomap_offset, iomapp->iomap_bsize, 0);
if (!pb)
return -EAGAIN;
......@@ -431,10 +432,10 @@ map_unwritten(
do {
if (!buffer_unwritten(bh))
break;
tmp = match_offset_to_mapping(start_page, mp, p_offset);
tmp = match_offset_to_mapping(start_page, iomapp, p_offset);
if (!tmp)
break;
map_buffer_at_offset(start_page, bh, p_offset, block_bits, mp);
map_buffer_at_offset(start_page, bh, p_offset, block_bits, iomapp);
set_buffer_unwritten_io(bh);
bh->b_private = pb;
p_offset += bh->b_size;
......@@ -442,8 +443,8 @@ map_unwritten(
} while ((bh = bh->b_this_page) != head);
if (unlikely(nblocks == 0)) {
printk("XFS: bad unwritten extent map: bh=0x%p, mp=0x%p\n",
curr, mp);
printk("XFS: bad unwritten extent map: bh=0x%p, iomapp=0x%p\n",
curr, iomapp);
BUG();
}
......@@ -459,26 +460,26 @@ map_unwritten(
struct page *page;
tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT;
tloff = (mp->pbm_offset + mp->pbm_bsize) >> PAGE_CACHE_SHIFT;
tloff = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
tloff = min(tlast, tloff);
for (tindex = start_page->index + 1; tindex < tloff; tindex++) {
page = probe_unwritten_page(mapping, tindex, mp, pb,
page = probe_unwritten_page(mapping, tindex, iomapp, pb,
PAGE_CACHE_SIZE, &bs, bbits);
if (!page)
break;
nblocks += bs;
atomic_add(bs, &pb->pb_io_remaining);
convert_page(inode, page, mp, pb, 1, all_bh);
convert_page(inode, page, iomapp, pb, 1, all_bh);
}
if (tindex == tlast &&
(tloff = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)))) {
page = probe_unwritten_page(mapping, tindex, mp, pb,
page = probe_unwritten_page(mapping, tindex, iomapp, pb,
tloff, &bs, bbits);
if (page) {
nblocks += bs;
atomic_add(bs, &pb->pb_io_remaining);
convert_page(inode, page, mp, pb, 1, all_bh);
convert_page(inode, page, iomapp, pb, 1, all_bh);
}
}
}
......@@ -540,13 +541,13 @@ STATIC void
convert_page(
struct inode *inode,
struct page *page,
page_buf_bmap_t *maps,
xfs_iomap_t *iomapp,
void *private,
int startio,
int all_bh)
{
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
page_buf_bmap_t *mp = maps, *tmp;
xfs_iomap_t *mp = iomapp, *tmp;
unsigned long end, offset, end_index;
int i = 0, index = 0;
int bbits = inode->i_blkbits;
......@@ -573,15 +574,15 @@ convert_page(
tmp = match_offset_to_mapping(page, mp, offset);
if (!tmp)
continue;
ASSERT(!(tmp->pbm_flags & PBMF_HOLE));
ASSERT(!(tmp->pbm_flags & PBMF_DELAY));
ASSERT(!(tmp->iomap_flags & IOMAP_HOLE));
ASSERT(!(tmp->iomap_flags & IOMAP_DELAY));
/* If this is a new unwritten extent buffer (i.e. one
* that we haven't passed in private data for, we must
* now map this buffer too.
*/
if (buffer_unwritten(bh) && !bh->b_end_io) {
ASSERT(tmp->pbm_flags & PBMF_UNWRITTEN);
ASSERT(tmp->iomap_flags & IOMAP_UNWRITTEN);
map_unwritten(inode, page, head, bh,
offset, bbits, tmp, all_bh);
} else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {
......@@ -616,19 +617,19 @@ STATIC void
cluster_write(
struct inode *inode,
unsigned long tindex,
page_buf_bmap_t *mp,
xfs_iomap_t *iomapp,
int startio,
int all_bh)
{
unsigned long tlast;
struct page *page;
tlast = (mp->pbm_offset + mp->pbm_bsize) >> PAGE_CACHE_SHIFT;
tlast = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
for (; tindex < tlast; tindex++) {
page = probe_delalloc_page(inode, tindex);
if (!page)
break;
convert_page(inode, page, mp, NULL, startio, all_bh);
convert_page(inode, page, iomapp, NULL, startio, all_bh);
}
}
......@@ -659,11 +660,11 @@ page_state_convert(
int unmapped) /* also implies page uptodate */
{
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
page_buf_bmap_t *mp, map;
xfs_iomap_t *iomp, iomap;
unsigned long p_offset = 0, end_index;
loff_t offset, end_offset;
int len, err, i, cnt = 0, uptodate = 1;
int flags = startio ? 0 : BMAP_TRYLOCK;
int flags = startio ? 0 : BMAPI_TRYLOCK;
int page_dirty = 1;
......@@ -683,7 +684,7 @@ page_state_convert(
end_offset = i_size_read(inode);
bh = head = page_buffers(page);
mp = NULL;
iomp = NULL;
len = bh->b_size;
do {
......@@ -694,8 +695,8 @@ page_state_convert(
if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio)
continue;
if (mp) {
mp = match_offset_to_mapping(page, &map, p_offset);
if (iomp) {
iomp = match_offset_to_mapping(page, &iomap, p_offset);
}
/*
......@@ -703,21 +704,21 @@ page_state_convert(
* extent state conversion transaction on completion.
*/
if (buffer_unwritten(bh)) {
if (!mp) {
err = map_blocks(inode, offset, len, &map,
BMAP_READ|BMAP_IGNSTATE);
if (!iomp) {
err = map_blocks(inode, offset, len, &iomap,
BMAPI_READ|BMAPI_IGNSTATE);
if (err) {
goto error;
}
mp = match_offset_to_mapping(page, &map,
iomp = match_offset_to_mapping(page, &iomap,
p_offset);
}
if (mp) {
if (iomp) {
if (!bh->b_end_io) {
err = map_unwritten(inode, page,
head, bh, p_offset,
inode->i_blkbits,
mp, unmapped);
iomp, unmapped);
if (err) {
goto error;
}
......@@ -736,18 +737,18 @@ page_state_convert(
* We can return EAGAIN here in the release page case.
*/
} else if (buffer_delay(bh)) {
if (!mp) {
err = map_blocks(inode, offset, len, &map,
BMAP_ALLOCATE | flags);
if (!iomp) {
err = map_blocks(inode, offset, len, &iomap,
BMAPI_ALLOCATE | flags);
if (err) {
goto error;
}
mp = match_offset_to_mapping(page, &map,
iomp = match_offset_to_mapping(page, &iomap,
p_offset);
}
if (mp) {
if (iomp) {
map_buffer_at_offset(page, bh, p_offset,
inode->i_blkbits, mp);
inode->i_blkbits, iomp);
if (startio) {
bh_arr[cnt++] = bh;
} else {
......@@ -768,22 +769,22 @@ page_state_convert(
* was found, and we are in a path where we
* need to write the whole page out.
*/
if (!mp) {
if (!iomp) {
size = probe_unmapped_cluster(
inode, page, bh, head);
err = map_blocks(inode, offset,
size, &map,
BMAP_WRITE | BMAP_MMAP);
size, &iomap,
BMAPI_WRITE | BMAPI_MMAP);
if (err) {
goto error;
}
mp = match_offset_to_mapping(page, &map,
iomp = match_offset_to_mapping(page, &iomap,
p_offset);
}
if (mp) {
if (iomp) {
map_buffer_at_offset(page,
bh, p_offset,
inode->i_blkbits, mp);
inode->i_blkbits, iomp);
if (startio) {
bh_arr[cnt++] = bh;
} else {
......@@ -810,8 +811,8 @@ page_state_convert(
if (startio)
submit_page(page, bh_arr, cnt);
if (mp)
cluster_write(inode, page->index + 1, mp, startio, unmapped);
if (iomp)
cluster_write(inode, page->index + 1, iomp, startio, unmapped);
return page_dirty;
......@@ -845,7 +846,7 @@ linvfs_get_block_core(
bmapi_flags_t flags)
{
vnode_t *vp = LINVFS_GET_VP(inode);
page_buf_bmap_t pbmap;
xfs_iomap_t iomap;
int retpbbm = 1;
int error;
ssize_t size;
......@@ -862,32 +863,32 @@ linvfs_get_block_core(
size = 1 << inode->i_blkbits;
VOP_BMAP(vp, offset, size,
create ? flags : BMAP_READ, &pbmap, &retpbbm, error);
create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
if (error)
return -error;
if (retpbbm == 0)
return 0;
if (pbmap.pbm_bn != PAGE_BUF_DADDR_NULL) {
if (iomap.iomap_bn != PAGE_BUF_DADDR_NULL) {
page_buf_daddr_t bn;
loff_t delta;
/* For unwritten extents do not report a disk address on
* the read case.
*/
if (create || ((pbmap.pbm_flags & PBMF_UNWRITTEN) == 0)) {
delta = offset - pbmap.pbm_offset;
if (create || ((iomap.iomap_flags & IOMAP_UNWRITTEN) == 0)) {
delta = offset - iomap.iomap_offset;
delta >>= inode->i_blkbits;
bn = pbmap.pbm_bn >> (inode->i_blkbits - BBSHIFT);
bn = iomap.iomap_bn >> (inode->i_blkbits - BBSHIFT);
bn += delta;
bh_result->b_blocknr = bn;
bh_result->b_bdev = pbmap.pbm_target->pbr_bdev;
bh_result->b_bdev = iomap.iomap_target->pbr_bdev;
set_buffer_mapped(bh_result);
}
if (pbmap.pbm_flags & PBMF_UNWRITTEN) {
if (iomap.iomap_flags & IOMAP_UNWRITTEN) {
if (create) {
if (direct)
bh_result->b_private = inode;
......@@ -904,23 +905,23 @@ linvfs_get_block_core(
*/
if (create &&
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
(offset >= i_size_read(inode)) || (pbmap.pbm_flags & PBMF_NEW))) {
(offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW))) {
set_buffer_new(bh_result);
}
if (pbmap.pbm_flags & PBMF_DELAY) {
if (iomap.iomap_flags & IOMAP_DELAY) {
if (unlikely(direct))
BUG();
if (create) {
set_buffer_mapped(bh_result);
set_buffer_uptodate(bh_result);
}
bh_result->b_bdev = pbmap.pbm_target->pbr_bdev;
bh_result->b_bdev = iomap.iomap_target->pbr_bdev;
set_buffer_delay(bh_result);
}
if (blocks) {
size = (pbmap.pbm_bsize - pbmap.pbm_delta);
size = (iomap.iomap_bsize - iomap.iomap_delta);
bh_result->b_size = min_t(ssize_t, size, blocks << inode->i_blkbits);
}
......@@ -935,7 +936,7 @@ linvfs_get_block(
int create)
{
return linvfs_get_block_core(inode, iblock, 0, bh_result,
create, 0, BMAP_WRITE);
create, 0, BMAPI_WRITE);
}
STATIC int
......@@ -946,7 +947,7 @@ linvfs_get_block_sync(
int create)
{
return linvfs_get_block_core(inode, iblock, 0, bh_result,
create, 0, BMAP_SYNC|BMAP_WRITE);
create, 0, BMAPI_SYNC|BMAPI_WRITE);
}
STATIC int
......@@ -958,7 +959,7 @@ linvfs_get_blocks_direct(
int create)
{
return linvfs_get_block_core(inode, iblock, max_blocks, bh_result,
create, 1, BMAP_WRITE|BMAP_DIRECT);
create, 1, BMAPI_WRITE|BMAPI_DIRECT);
}
STATIC int
......@@ -972,15 +973,15 @@ linvfs_direct_IO(
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;
xfs_iomap_t iomap;
int maps = 1;
int error;
VOP_BMAP(vp, offset, 0, BMAP_DEVICE, &pbmap, &maps, error);
VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error);
if (error)
return -error;
return blockdev_direct_IO(rw, iocb, inode, pbmap.pbm_target->pbr_bdev,
return blockdev_direct_IO(rw, iocb, inode, iomap.iomap_target->pbr_bdev,
iov, offset, nr_segs,
linvfs_get_blocks_direct,
linvfs_unwritten_convert_direct);
......
......@@ -67,6 +67,7 @@
#include "xfs_buf_item.h"
#include "xfs_trans_space.h"
#include "xfs_utils.h"
#include "xfs_iomap.h"
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
<< mp->m_writeio_log)
......@@ -78,9 +79,9 @@ xfs_imap_to_bmap(
xfs_iocore_t *io,
xfs_off_t offset,
xfs_bmbt_irec_t *imap,
page_buf_bmap_t *pbmapp,
xfs_iomap_t *iomapp,
int imaps, /* Number of imap entries */
int bmaps, /* Number of bmap entries */
int iomaps, /* Number of iomap entries */
int flags)
{
xfs_mount_t *mp;
......@@ -93,32 +94,32 @@ xfs_imap_to_bmap(
if (io->io_new_size > nisize)
nisize = io->io_new_size;
for (pbm = 0; imaps && pbm < bmaps; imaps--, pbmapp++, imap++, pbm++) {
pbmapp->pbm_target = io->io_flags & XFS_IOCORE_RT ?
for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) {
iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ?
mp->m_rtdev_targp : mp->m_ddev_targp;
pbmapp->pbm_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
pbmapp->pbm_delta = offset - pbmapp->pbm_offset;
pbmapp->pbm_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount);
pbmapp->pbm_flags = flags;
iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
iomapp->iomap_delta = offset - iomapp->iomap_offset;
iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount);
iomapp->iomap_flags = flags;
start_block = imap->br_startblock;
if (start_block == HOLESTARTBLOCK) {
pbmapp->pbm_bn = PAGE_BUF_DADDR_NULL;
pbmapp->pbm_flags = PBMF_HOLE;
iomapp->iomap_bn = IOMAP_DADDR_NULL;
iomapp->iomap_flags = IOMAP_HOLE;
} else if (start_block == DELAYSTARTBLOCK) {
pbmapp->pbm_bn = PAGE_BUF_DADDR_NULL;
pbmapp->pbm_flags = PBMF_DELAY;
iomapp->iomap_bn = IOMAP_DADDR_NULL;
iomapp->iomap_flags = IOMAP_DELAY;
} else {
pbmapp->pbm_bn = XFS_FSB_TO_DB_IO(io, start_block);
iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block);
if (ISUNWRITTEN(imap))
pbmapp->pbm_flags |= PBMF_UNWRITTEN;
iomapp->iomap_flags |= IOMAP_UNWRITTEN;
}
if ((pbmapp->pbm_offset + pbmapp->pbm_bsize) >= nisize) {
pbmapp->pbm_flags |= PBMF_EOF;
if ((iomapp->iomap_offset + iomapp->iomap_bsize) >= nisize) {
iomapp->iomap_flags |= IOMAP_EOF;
}
offset += pbmapp->pbm_bsize - pbmapp->pbm_delta;
offset += iomapp->iomap_bsize - iomapp->iomap_delta;
}
return pbm; /* Return the number filled */
}
......@@ -129,8 +130,8 @@ xfs_iomap(
xfs_off_t offset,
ssize_t count,
int flags,
page_buf_bmap_t *pbmapp,
int *npbmaps)
xfs_iomap_t *iomapp,
int *niomaps)
{
xfs_mount_t *mp = io->io_mount;
xfs_fileoff_t offset_fsb, end_fsb;
......@@ -139,44 +140,44 @@ xfs_iomap(
xfs_bmbt_irec_t imap;
int nimaps = 1;
int bmapi_flags = 0;
int bmapv_flags = 0;
int iomap_flags = 0;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
switch (flags &
(BMAP_READ | BMAP_WRITE | BMAP_ALLOCATE |
BMAP_UNWRITTEN | BMAP_DEVICE)) {
case BMAP_READ:
(BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE |
BMAPI_UNWRITTEN | BMAPI_DEVICE)) {
case BMAPI_READ:
lockmode = XFS_LCK_MAP_SHARED(mp, io);
bmapi_flags = XFS_BMAPI_ENTIRE;
if (flags & BMAP_IGNSTATE)
if (flags & BMAPI_IGNSTATE)
bmapi_flags |= XFS_BMAPI_IGSTATE;
break;
case BMAP_WRITE:
case BMAPI_WRITE:
lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR;
bmapi_flags = 0;
XFS_ILOCK(mp, io, lockmode);
break;
case BMAP_ALLOCATE:
case BMAPI_ALLOCATE:
lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD;
bmapi_flags = XFS_BMAPI_ENTIRE;
/* Attempt non-blocking lock */
if (flags & BMAP_TRYLOCK) {
if (flags & BMAPI_TRYLOCK) {
if (!XFS_ILOCK_NOWAIT(mp, io, lockmode))
return XFS_ERROR(EAGAIN);
} else {
XFS_ILOCK(mp, io, lockmode);
}
break;
case BMAP_UNWRITTEN:
case BMAPI_UNWRITTEN:
goto phase2;
case BMAP_DEVICE:
case BMAPI_DEVICE:
lockmode = XFS_LCK_MAP_SHARED(mp, io);
pbmapp->pbm_target = io->io_flags & XFS_IOCORE_RT ?
iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ?
mp->m_rtdev_targp : mp->m_ddev_targp;
error = 0;
*npbmaps = 1;
*niomaps = 1;
goto out;
default:
BUG();
......@@ -197,22 +198,22 @@ xfs_iomap(
goto out;
phase2:
switch (flags & (BMAP_WRITE|BMAP_ALLOCATE|BMAP_UNWRITTEN)) {
case BMAP_WRITE:
switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
case BMAPI_WRITE:
/* If we found an extent, return it */
if (nimaps && (imap.br_startblock != HOLESTARTBLOCK))
break;
if (flags & (BMAP_DIRECT|BMAP_MMAP)) {
if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) {
error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset,
count, flags, &imap, &nimaps, nimaps);
} else {
error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count,
flags, &imap, &nimaps);
}
bmapv_flags = PBMF_NEW;
iomap_flags = IOMAP_NEW;
break;
case BMAP_ALLOCATE:
case BMAPI_ALLOCATE:
/* If we found an extent, return it */
XFS_IUNLOCK(mp, io, lockmode);
lockmode = 0;
......@@ -222,7 +223,7 @@ xfs_iomap(
error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps);
break;
case BMAP_UNWRITTEN:
case BMAPI_UNWRITTEN:
lockmode = 0;
error = XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count);
nimaps = 0;
......@@ -230,10 +231,10 @@ xfs_iomap(
}
if (nimaps) {
*npbmaps = xfs_imap_to_bmap(io, offset, &imap,
pbmapp, nimaps, *npbmaps, bmapv_flags);
} else if (npbmaps) {
*npbmaps = 0;
*niomaps = xfs_imap_to_bmap(io, offset, &imap,
iomapp, nimaps, *niomaps, iomap_flags);
} else if (niomaps) {
*niomaps = 0;
}
out:
......@@ -256,13 +257,13 @@ xfs_flush_space(
xfs_ilock(ip, XFS_ILOCK_EXCL);
*fsynced = 1;
} else {
*ioflags |= BMAP_SYNC;
*ioflags |= BMAPI_SYNC;
*fsynced = 2;
}
return 0;
case 1:
*fsynced = 2;
*ioflags |= BMAP_SYNC;
*ioflags |= BMAPI_SYNC;
return 0;
case 2:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
......@@ -393,7 +394,7 @@ xfs_iomap_write_direct(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
if (!(flags & BMAP_MMAP) && (offset < ip->i_d.di_size || rt))
if (!(flags & BMAPI_MMAP) && (offset < ip->i_d.di_size || rt))
bmapi_flag |= XFS_BMAPI_PREALLOC;
/*
......@@ -492,7 +493,7 @@ xfs_iomap_write_delay(
* We don't bother with this for sync writes, because we need
* to minimize the amount we write for good performance.
*/
if (!(ioflag & BMAP_SYNC) && ((offset + count) > ip->i_d.di_size)) {
if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) {
xfs_off_t aligned_offset;
unsigned int iosize;
xfs_fileoff_t ioalign;
......
......@@ -71,6 +71,7 @@
#include "xfs_inode_item.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
#include "xfs_iomap.h"
#include <linux/capability.h>
......@@ -967,8 +968,8 @@ xfs_bmap(bhv_desc_t *bdp,
xfs_off_t offset,
ssize_t count,
int flags,
page_buf_bmap_t *pbmapp,
int *npbmaps)
xfs_iomap_t *iomapp,
int *niomaps)
{
xfs_inode_t *ip = XFS_BHVTOI(bdp);
xfs_iocore_t *io = &ip->i_iocore;
......@@ -977,7 +978,7 @@ xfs_bmap(bhv_desc_t *bdp,
ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
return xfs_iomap(io, offset, count, flags, pbmapp, npbmaps);
return xfs_iomap(io, offset, count, flags, iomapp, niomaps);
}
/*
......
......@@ -39,7 +39,7 @@ struct xfs_iocore;
struct xfs_inode;
struct xfs_bmbt_irec;
struct page_buf_s;
struct page_buf_bmap_s;
struct xfs_iomap;
#if defined(XFS_RW_TRACE)
/*
......@@ -84,7 +84,7 @@ extern void xfs_inval_cached_trace(struct xfs_iocore *,
#define XFS_MAX_RW_NBMAPS 4
extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
struct page_buf_bmap_s *, int *);
struct xfs_iomap *, int *);
extern int xfsbdstrat(struct xfs_mount *, struct page_buf_s *);
extern int xfs_bdstrat_cb(struct page_buf_s *);
......@@ -102,16 +102,6 @@ extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
loff_t *, int, size_t, read_actor_t,
void *, struct cred *);
extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
struct page_buf_bmap_s *, int *);
extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t,
int, struct xfs_bmbt_irec *, int *, int);
extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t,
int, struct xfs_bmbt_irec *, int *);
extern int xfs_iomap_write_allocate(struct xfs_inode *,
struct xfs_bmbt_irec *, int *);
extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
#define XFS_FSB_TO_DB_IO(io,fsb) \
......
......@@ -62,7 +62,7 @@
struct uio;
struct file;
struct vattr;
struct page_buf_bmap_s;
struct xfs_iomap;
struct attrlist_cursor_kern;
/*
......@@ -226,7 +226,7 @@ typedef int (*vop_release_t)(bhv_desc_t *);
typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t);
typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
struct page_buf_bmap_s *, int *);
struct xfs_iomap *, int *);
typedef int (*vop_reclaim_t)(bhv_desc_t *);
typedef int (*vop_attr_get_t)(bhv_desc_t *, char *, char *, int *, int,
struct cred *);
......
......@@ -67,29 +67,6 @@ typedef enum page_buf_rw_e {
PBRW_ZERO = 3 /* Zero target memory */
} page_buf_rw_t;
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 */
/* but uninitialized file data */
PBMF_NEW = 0x40 /* just allocated */
} bmap_flags_t;
typedef enum {
/* base extent manipulation calls */
BMAP_READ = (1 << 0), /* read extents */
BMAP_WRITE = (1 << 1), /* create extents */
BMAP_ALLOCATE = (1 << 2), /* delayed allocate to real extents */
BMAP_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */
/* modifiers */
BMAP_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
BMAP_DIRECT = (1 << 5), /* direct instead of buffered write */
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 */
PBF_READ = (1 << 0), /* buffer intended for reading from device */
......@@ -138,36 +115,6 @@ typedef struct pb_target {
size_t pbr_smask;
} pb_target_t;
/*
* page_buf_bmap_t: File system I/O map
*
* The pbm_bn, pbm_offset and pbm_length fields are expressed in disk blocks.
* The pbm_length field specifies the size of the underlying backing store
* for the particular mapping.
*
* The pbm_bsize, pbm_size and pbm_delta fields are in bytes and indicate
* the size of the mapping, the number of bytes that are valid to access
* (read or write), and the offset into the mapping, given the offset
* supplied to the file I/O map routine. pbm_delta is the offset of the
* desired data from the beginning of the mapping.
*
* When a request is made to read beyond the logical end of the object,
* pbm_size may be set to 0, but pbm_offset and pbm_length should be set to
* the actual amount of underlying storage that has been allocated, if any.
*/
typedef struct page_buf_bmap_s {
page_buf_daddr_t pbm_bn; /* block number in file system */
pb_target_t *pbm_target; /* device to do I/O to */
loff_t pbm_offset; /* byte offset of mapping in file */
size_t pbm_delta; /* offset of request into bmap */
size_t pbm_bsize; /* size of this mapping in bytes */
bmap_flags_t pbm_flags; /* options flags for mapping */
} page_buf_bmap_t;
typedef page_buf_bmap_t pb_bmap_t;
/*
* page_buf_t: Buffer structure for page cache-based buffers
*
......
......@@ -61,6 +61,7 @@
#include "xfs_rw.h"
#include "xfs_quota.h"
#include "xfs_trans_space.h"
#include "xfs_iomap.h"
STATIC xfs_fsize_t
......
/*
* Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_IOMAP_H__
#define __XFS_IOMAP_H__
#define IOMAP_DADDR_NULL ((xfs_daddr_t) (-1LL))
typedef enum { /* iomap_flags values */
IOMAP_EOF = 0x01, /* mapping contains EOF */
IOMAP_HOLE = 0x02, /* mapping covers a hole */
IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
IOMAP_UNWRITTEN = 0x20, /* mapping covers allocated */
/* but uninitialized file data */
IOMAP_NEW = 0x40 /* just allocate */
} iomap_flags_t;
typedef enum {
/* base extent manipulation calls */
BMAPI_READ = (1 << 0), /* read extents */
BMAPI_WRITE = (1 << 1), /* create extents */
BMAPI_ALLOCATE = (1 << 2), /* delayed allocate to real extents */
BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */
/* modifiers */
BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
BMAPI_SYNC = (1 << 7), /* sync write */
BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
BMAPI_DEVICE = (1 << 9), /* we only want to know the device */
} bmapi_flags_t;
/*
* xfs_iomap_t: File system I/O map
*
* The iomap_bn, iomap_offset and iomap_length fields are expressed in disk blocks.
* The iomap_length field specifies the size of the underlying backing store
* for the particular mapping.
*
* The iomap_bsize, iomap_size and iomap_delta fields are in bytes and indicate
* the size of the mapping, the number of bytes that are valid to access
* (read or write), and the offset into the mapping, given the offset
* supplied to the file I/O map routine. iomap_delta is the offset of the
* desired data from the beginning of the mapping.
*
* When a request is made to read beyond the logical end of the object,
* iomap_size may be set to 0, but iomap_offset and iomap_length should be set to
* the actual amount of underlying storage that has been allocated, if any.
*/
typedef struct xfs_iomap {
xfs_daddr_t iomap_bn;
xfs_buftarg_t *iomap_target;
loff_t iomap_offset;
size_t iomap_delta;
size_t iomap_bsize;
iomap_flags_t iomap_flags;
} xfs_iomap_t;
struct xfs_iocore;
struct xfs_inode;
struct xfs_bmbt_irec;
extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
struct xfs_iomap *, int *);
extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t,
int, struct xfs_bmbt_irec *, int *, int);
extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int,
struct xfs_bmbt_irec *, int *);
extern int xfs_iomap_write_allocate(struct xfs_inode *,
struct xfs_bmbt_irec *, int *);
extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
#endif /* __XFS_IOMAP_H__*/
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