Skip to content

Commit

Permalink
[XFS] cluster rewrites We can cluster mapped pages aswell, this improves
Browse files Browse the repository at this point in the history
performances on rewrites since we can reduce the number of allocator
calls.

SGI-PV: 947118
SGI-Modid: xfs-linux-melb:xfs-kern:203829a

Signed-off-by: Christoph Hellwig <hch@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
  • Loading branch information
Christoph Hellwig authored and Nathan Scott committed Jan 11, 2006
1 parent 7336cea commit 6c4fe19
Showing 1 changed file with 47 additions and 16 deletions.
63 changes: 47 additions & 16 deletions fs/xfs/linux-2.6/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,13 @@ xfs_map_at_offset(
}

/*
* Look for a page at index which is unlocked and not mapped
* yet - clustering for mmap write case.
* Look for a page at index that is suitable for clustering.
*/
STATIC unsigned int
xfs_probe_unmapped_page(
xfs_probe_page(
struct page *page,
unsigned int pg_offset)
unsigned int pg_offset,
int mapped)
{
int ret = 0;

Expand All @@ -489,25 +489,28 @@ xfs_probe_unmapped_page(

bh = head = page_buffers(page);
do {
if (buffer_mapped(bh) || !buffer_uptodate(bh))
if (!buffer_uptodate(bh))
break;
if (mapped != buffer_mapped(bh))
break;
ret += bh->b_size;
if (ret >= pg_offset)
break;
} while ((bh = bh->b_this_page) != head);
} else
ret = PAGE_CACHE_SIZE;
ret = mapped ? 0 : PAGE_CACHE_SIZE;
}

return ret;
}

STATIC size_t
xfs_probe_unmapped_cluster(
xfs_probe_cluster(
struct inode *inode,
struct page *startpage,
struct buffer_head *bh,
struct buffer_head *head)
struct buffer_head *head,
int mapped)
{
struct pagevec pvec;
pgoff_t tindex, tlast, tloff;
Expand All @@ -516,7 +519,7 @@ xfs_probe_unmapped_cluster(

/* First sum forwards in this page */
do {
if (buffer_mapped(bh))
if (mapped != buffer_mapped(bh))
return total;
total += bh->b_size;
} while ((bh = bh->b_this_page) != head);
Expand Down Expand Up @@ -550,7 +553,7 @@ xfs_probe_unmapped_cluster(
pg_offset = PAGE_CACHE_SIZE;

if (page->index == tindex && !TestSetPageLocked(page)) {
len = xfs_probe_unmapped_page(page, pg_offset);
len = xfs_probe_page(page, pg_offset, mapped);
unlock_page(page);
}

Expand Down Expand Up @@ -592,6 +595,8 @@ xfs_is_delayed_page(
acceptable = (type == IOMAP_UNWRITTEN);
else if (buffer_delay(bh))
acceptable = (type == IOMAP_DELAY);
else if (buffer_mapped(bh))
acceptable = (type == 0);
else
break;
} while ((bh = bh->b_this_page) != head);
Expand Down Expand Up @@ -804,6 +809,7 @@ xfs_page_state_convert(
ssize_t size, len;
int flags, err, iomap_valid = 0, uptodate = 1;
int page_dirty, count = 0, trylock_flag = 0;
int all_bh = unmapped;

/* wait for other IO threads? */
if (startio && wbc->sync_mode != WB_SYNC_NONE)
Expand Down Expand Up @@ -845,6 +851,8 @@ xfs_page_state_convert(

bh = head = page_buffers(page);
offset = page_offset(page);
flags = -1;
type = 0;

/* TODO: cleanup count and page_dirty */

Expand Down Expand Up @@ -878,6 +886,12 @@ xfs_page_state_convert(
if (buffer_unwritten(bh) || buffer_delay(bh) ||
((buffer_uptodate(bh) || PageUptodate(page)) &&
!buffer_mapped(bh) && (unmapped || startio))) {
/*
* Make sure we don't use a read-only iomap
*/
if (flags == BMAPI_READ)
iomap_valid = 0;

if (buffer_unwritten(bh)) {
type = IOMAP_UNWRITTEN;
flags = BMAPI_WRITE|BMAPI_IGNSTATE;
Expand All @@ -887,14 +901,14 @@ xfs_page_state_convert(
if (!startio)
flags |= trylock_flag;
} else {
type = 0;
type = IOMAP_NEW;
flags = BMAPI_WRITE|BMAPI_MMAP;
}

if (!iomap_valid) {
if (type == 0) {
size = xfs_probe_unmapped_cluster(inode,
page, bh, head);
if (type == IOMAP_NEW) {
size = xfs_probe_cluster(inode,
page, bh, head, 0);
} else {
size = len;
}
Expand All @@ -921,10 +935,27 @@ xfs_page_state_convert(
count++;
}
} else if (buffer_uptodate(bh) && startio) {
type = 0;
/*
* we got here because the buffer is already mapped.
* That means it must already have extents allocated
* underneath it. Map the extent by reading it.
*/
if (!iomap_valid || type != 0) {
flags = BMAPI_READ;
size = xfs_probe_cluster(inode, page, bh,
head, 1);
err = xfs_map_blocks(inode, offset, size,
&iomap, flags);
if (err)
goto error;
iomap_valid = xfs_iomap_valid(&iomap, offset);
}

type = 0;
if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
ASSERT(buffer_mapped(bh));
if (iomap_valid)
all_bh = 1;
xfs_add_to_ioend(inode, bh, offset, type,
&ioend, !iomap_valid);
page_dirty--;
Expand Down Expand Up @@ -953,7 +984,7 @@ xfs_page_state_convert(
PAGE_CACHE_SHIFT;
tlast = min_t(pgoff_t, offset, last_index);
xfs_cluster_write(inode, page->index + 1, &iomap, &ioend,
wbc, startio, unmapped, tlast);
wbc, startio, all_bh, tlast);
}

if (iohead)
Expand Down

0 comments on commit 6c4fe19

Please sign in to comment.