Commit 7dbae9fb authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

xfs: allow merging ioends over append boundaries

There is no real problem merging ioends that go beyond i_size into an
ioend that doesn't.  We just need to move the append transaction to the
base ioend.  Also use the opportunity to use a real error code instead
of the magic 1 to cancel the transactions, and write a comment
explaining the scheme.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 0290d9c1
...@@ -300,11 +300,28 @@ xfs_ioend_can_merge( ...@@ -300,11 +300,28 @@ xfs_ioend_can_merge(
return false; return false;
if (ioend->io_offset + ioend->io_size != next->io_offset) if (ioend->io_offset + ioend->io_size != next->io_offset)
return false; return false;
if (xfs_ioend_is_append(ioend) != xfs_ioend_is_append(next))
return false;
return true; return true;
} }
/*
* If the to be merged ioend has a preallocated transaction for file
* size updates we need to ensure the ioend it is merged into also
* has one. If it already has one we can simply cancel the transaction
* as it is guaranteed to be clean.
*/
static void
xfs_ioend_merge_append_transactions(
struct xfs_ioend *ioend,
struct xfs_ioend *next)
{
if (!ioend->io_append_trans) {
ioend->io_append_trans = next->io_append_trans;
next->io_append_trans = NULL;
} else {
xfs_setfilesize_ioend(next, -ECANCELED);
}
}
/* Try to merge adjacent completions. */ /* Try to merge adjacent completions. */
STATIC void STATIC void
xfs_ioend_try_merge( xfs_ioend_try_merge(
...@@ -313,7 +330,6 @@ xfs_ioend_try_merge( ...@@ -313,7 +330,6 @@ xfs_ioend_try_merge(
{ {
struct xfs_ioend *next_ioend; struct xfs_ioend *next_ioend;
int ioend_error; int ioend_error;
int error;
if (list_empty(more_ioends)) if (list_empty(more_ioends))
return; return;
...@@ -327,10 +343,8 @@ xfs_ioend_try_merge( ...@@ -327,10 +343,8 @@ xfs_ioend_try_merge(
break; break;
list_move_tail(&next_ioend->io_list, &ioend->io_list); list_move_tail(&next_ioend->io_list, &ioend->io_list);
ioend->io_size += next_ioend->io_size; ioend->io_size += next_ioend->io_size;
if (ioend->io_append_trans) { if (next_ioend->io_append_trans)
error = xfs_setfilesize_ioend(next_ioend, 1); xfs_ioend_merge_append_transactions(ioend, next_ioend);
ASSERT(error == 1);
}
} }
} }
......
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