aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c91
1 files changed, 34 insertions, 57 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 64c909e5c1e5..98d26c8e0565 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -806,7 +806,8 @@ xfs_page_state_convert(
unsigned int type;
__uint64_t end_offset;
pgoff_t end_index, last_index, tlast;
- int flags, len, err, iomap_valid = 0, uptodate = 1;
+ ssize_t size, len;
+ int flags, err, iomap_valid = 0, uptodate = 1;
int page_dirty, count = 0, trylock_flag = 0;
/* wait for other IO threads? */
@@ -875,21 +876,36 @@ xfs_page_state_convert(
*
* Second case, allocate space for a delalloc buffer.
* We can return EAGAIN here in the release page case.
- */
- if (buffer_unwritten(bh) || buffer_delay(bh)) {
+ *
+ * Third case, an unmapped buffer was found, and we are
+ * in a path where we need to write the whole page out.
+ */
+ if (buffer_unwritten(bh) || buffer_delay(bh) ||
+ ((buffer_uptodate(bh) || PageUptodate(page)) &&
+ !buffer_mapped(bh) && (unmapped || startio))) {
if (buffer_unwritten(bh)) {
type = IOMAP_UNWRITTEN;
flags = BMAPI_WRITE|BMAPI_IGNSTATE;
- } else {
+ } else if (buffer_delay(bh)) {
type = IOMAP_DELAY;
flags = BMAPI_ALLOCATE;
if (!startio)
flags |= trylock_flag;
+ } else {
+ type = 0;
+ flags = BMAPI_WRITE|BMAPI_MMAP;
}
if (!iomap_valid) {
- err = xfs_map_blocks(inode, offset, len, &iomap,
- flags);
+ if (type == 0) {
+ size = xfs_probe_unmapped_cluster(inode,
+ page, bh, head);
+ } else {
+ size = len;
+ }
+
+ err = xfs_map_blocks(inode, offset, size,
+ &iomap, flags);
if (err)
goto error;
iomap_valid = xfs_iomap_valid(&iomap, offset);
@@ -909,61 +925,22 @@ xfs_page_state_convert(
page_dirty--;
count++;
}
- } else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
- (unmapped || startio)) {
-
+ } else if (buffer_uptodate(bh) && startio) {
type = 0;
- if (!buffer_mapped(bh)) {
-
- /*
- * Getting here implies an unmapped buffer
- * was found, and we are in a path where we
- * need to write the whole page out.
- */
- if (!iomap_valid) {
- int size;
-
- size = xfs_probe_unmapped_cluster(
- inode, page, bh, head);
- err = xfs_map_blocks(inode, offset,
- size, &iomap,
- BMAPI_WRITE|BMAPI_MMAP);
- if (err)
- goto error;
- iomap_valid = xfs_iomap_valid(&iomap,
- offset);
- }
- if (iomap_valid) {
- xfs_map_at_offset(bh, offset,
- inode->i_blkbits,
- &iomap);
- if (startio) {
- xfs_add_to_ioend(inode,
- bh, p_offset, type,
- &ioend, !iomap_valid);
- } else {
- set_buffer_dirty(bh);
- unlock_buffer(bh);
- mark_buffer_dirty(bh);
- }
- page_dirty--;
- count++;
- }
- } else if (startio) {
- if (buffer_uptodate(bh) &&
- !test_and_set_bit(BH_Lock, &bh->b_state)) {
- ASSERT(buffer_mapped(bh));
- xfs_add_to_ioend(inode,
- bh, p_offset, type,
- &ioend, !iomap_valid);
- page_dirty--;
- count++;
- } else {
- iomap_valid = 0;
- }
+
+ if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
+ ASSERT(buffer_mapped(bh));
+ xfs_add_to_ioend(inode,
+ bh, p_offset, type,
+ &ioend, !iomap_valid);
+ page_dirty--;
+ count++;
} else {
iomap_valid = 0;
}
+ } else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
+ (unmapped || startio)) {
+ iomap_valid = 0;
}
if (!iohead)