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: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
committed by
Darrick J. Wong
parent
0290d9c1e5
commit
7dbae9fbde
@@ -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(
|
|||||||
{
|
{
|
||||||
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(
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user