Commit ee1aaacd authored by Dave Kleikamp's avatar Dave Kleikamp

Proper implementation of jfs_get_blocks

jfs_get_blocks should return up to the number of blocks in the
extent rather than limiting itself to one block, as the initial,
trivial implementation did.  This greatly reduces the overhead of
O_DIRECT reads and writes.

Submitted by Badari Pulavarty (pbadari@us.ibm.com)
parent 68067d0e
...@@ -165,8 +165,9 @@ void jfs_dirty_inode(struct inode *inode) ...@@ -165,8 +165,9 @@ void jfs_dirty_inode(struct inode *inode)
set_cflag(COMMIT_Dirty, inode); set_cflag(COMMIT_Dirty, inode);
} }
static int jfs_get_block(struct inode *ip, sector_t lblock, static int
struct buffer_head *bh_result, int create) jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
struct buffer_head *bh_result, int create)
{ {
s64 lblock64 = lblock; s64 lblock64 = lblock;
int no_size_check = 0; int no_size_check = 0;
...@@ -202,7 +203,7 @@ static int jfs_get_block(struct inode *ip, sector_t lblock, ...@@ -202,7 +203,7 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
if ((no_size_check || if ((no_size_check ||
((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) && ((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) &&
(xtLookup(ip, lblock64, 1, &xflag, &xaddr, &xlen, no_size_check) (xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, no_size_check)
== 0) && xlen) { == 0) && xlen) {
if (xflag & XAD_NOTRECORDED) { if (xflag & XAD_NOTRECORDED) {
if (!create) if (!create)
...@@ -230,6 +231,7 @@ static int jfs_get_block(struct inode *ip, sector_t lblock, ...@@ -230,6 +231,7 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
} }
map_bh(bh_result, ip->i_sb, xaddr); map_bh(bh_result, ip->i_sb, xaddr);
bh_result->b_size = xlen << ip->i_blkbits;
goto unlock; goto unlock;
} }
if (!create) if (!create)
...@@ -241,12 +243,13 @@ static int jfs_get_block(struct inode *ip, sector_t lblock, ...@@ -241,12 +243,13 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
#ifdef _JFS_4K #ifdef _JFS_4K
if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
goto unlock; goto unlock;
rc = extAlloc(ip, 1, lblock64, &xad, FALSE); rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE);
if (rc) if (rc)
goto unlock; goto unlock;
set_buffer_new(bh_result); set_buffer_new(bh_result);
map_bh(bh_result, ip->i_sb, addressXAD(&xad)); map_bh(bh_result, ip->i_sb, addressXAD(&xad));
bh_result->b_size = lengthXAD(&xad) << ip->i_blkbits;
#else /* _JFS_4K */ #else /* _JFS_4K */
/* /*
...@@ -269,6 +272,12 @@ static int jfs_get_block(struct inode *ip, sector_t lblock, ...@@ -269,6 +272,12 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
return -rc; return -rc;
} }
static int jfs_get_block(struct inode *ip, sector_t lblock,
struct buffer_head *bh_result, int create)
{
return jfs_get_blocks(ip, lblock, 1, bh_result, create);
}
static int jfs_writepage(struct page *page) static int jfs_writepage(struct page *page)
{ {
return block_write_full_page(page, jfs_get_block); return block_write_full_page(page, jfs_get_block);
...@@ -301,18 +310,6 @@ static int jfs_bmap(struct address_space *mapping, long block) ...@@ -301,18 +310,6 @@ static int jfs_bmap(struct address_space *mapping, long block)
return generic_block_bmap(mapping, block, jfs_get_block); return generic_block_bmap(mapping, block, jfs_get_block);
} }
static int
jfs_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
struct buffer_head *bh_result, int create)
{
int ret;
ret = jfs_get_block(inode, iblock, bh_result, create);
if (ret == 0)
bh_result->b_size = (1 << inode->i_blkbits);
return ret;
}
static int jfs_direct_IO(int rw, struct inode *inode, char *buf, static int jfs_direct_IO(int rw, struct inode *inode, char *buf,
loff_t offset, size_t count) loff_t offset, size_t count)
{ {
......
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