/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 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
bhv_desc_t *bdp;
vnode_t *vp = LINVFS_GET_VP(inode);
loff_t isize = i_size_read(inode);
- loff_t offset = page->index << PAGE_CACHE_SHIFT;
+ loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
int delalloc = -1, unmapped = -1, unwritten = -1;
if (page_has_buffers(page))
{
ASSERT(!private || inode == (struct inode *)private);
- /* private indicates an unwritten extent lay beneath this IO,
- * see linvfs_get_block_core.
- */
+ /* private indicates an unwritten extent lay beneath this IO */
if (private && size > 0) {
vnode_t *vp = LINVFS_GET_VP(inode);
int error;
pgoff_t end_index, last_index, tlast;
int len, err, i, cnt = 0, uptodate = 1;
int flags = startio ? 0 : BMAPI_TRYLOCK;
- int page_dirty = 1;
- int delalloc = 0;
-
+ int page_dirty, delalloc = 0;
- /* Are we off the end of the file ? */
+ /* Is this page beyond the end of the file? */
offset = i_size_read(inode);
end_index = offset >> PAGE_CACHE_SHIFT;
last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
bh = head = page_buffers(page);
iomp = NULL;
+ /*
+ * page_dirty is initially a count of buffers on the page and
+ * is decrememted as we move each into a cleanable state.
+ */
len = bh->b_size;
+ page_dirty = PAGE_CACHE_SIZE / len;
+
do {
if (offset >= end_offset)
break;
}
BUG_ON(!buffer_locked(bh));
bh_arr[cnt++] = bh;
- page_dirty = 0;
+ page_dirty--;
}
/*
* Second case, allocate space for a delalloc buffer.
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
- page_dirty = 0;
+ page_dirty--;
}
} else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
(unmapped || startio)) {
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
- page_dirty = 0;
+ page_dirty--;
}
} else if (startio) {
if (buffer_uptodate(bh) &&
!test_and_set_bit(BH_Lock, &bh->b_state)) {
bh_arr[cnt++] = bh;
- page_dirty = 0;
+ page_dirty--;
}
}
}
}
STATIC int
-linvfs_get_block_core(
+__linvfs_get_block(
struct inode *inode,
sector_t iblock,
unsigned long blocks,
if (iomap.iomap_flags & IOMAP_DELAY) {
BUG_ON(direct);
if (create) {
- set_buffer_mapped(bh_result);
set_buffer_uptodate(bh_result);
+ set_buffer_mapped(bh_result);
+ set_buffer_delay(bh_result);
}
- set_buffer_delay(bh_result);
}
if (blocks) {
struct buffer_head *bh_result,
int create)
{
- return linvfs_get_block_core(inode, iblock, 0, bh_result,
+ return __linvfs_get_block(inode, iblock, 0, bh_result,
create, 0, BMAPI_WRITE);
}
struct buffer_head *bh_result,
int create)
{
- return linvfs_get_block_core(inode, iblock, max_blocks, bh_result,
+ return __linvfs_get_block(inode, iblock, max_blocks, bh_result,
create, 1, BMAPI_WRITE|BMAPI_DIRECT);
}