mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
device: Skip read-modify-write if replacing whole block.
This commit is contained in:
parent
e4805e4883
commit
7195df5aca
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.177 -
|
Version 2.02.177 -
|
||||||
====================================
|
====================================
|
||||||
|
Skip read-modify-write when entire block is replaced.
|
||||||
Categorise I/O with reason annotations in debug messages.
|
Categorise I/O with reason annotations in debug messages.
|
||||||
Command will lock memory only when suspending volumes.
|
Command will lock memory only when suspending volumes.
|
||||||
Merge segments when pvmove is finished.
|
Merge segments when pvmove is finished.
|
||||||
|
@ -231,6 +231,7 @@ static int _aligned_io(struct device_area *where, char *buffer,
|
|||||||
char *bounce, *bounce_buf;
|
char *bounce, *bounce_buf;
|
||||||
unsigned int physical_block_size = 0;
|
unsigned int physical_block_size = 0;
|
||||||
unsigned int block_size = 0;
|
unsigned int block_size = 0;
|
||||||
|
unsigned buffer_was_widened = 0;
|
||||||
uintptr_t mask;
|
uintptr_t mask;
|
||||||
struct device_area widened;
|
struct device_area widened;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@ -241,18 +242,19 @@ static int _aligned_io(struct device_area *where, char *buffer,
|
|||||||
|
|
||||||
if (!block_size)
|
if (!block_size)
|
||||||
block_size = lvm_getpagesize();
|
block_size = lvm_getpagesize();
|
||||||
|
mask = block_size - 1;
|
||||||
|
|
||||||
_widen_region(block_size, where, &widened);
|
_widen_region(block_size, where, &widened);
|
||||||
|
|
||||||
/* Do we need to use a bounce buffer? */
|
/* Did we widen the buffer? When writing, this means means read-modify-write. */
|
||||||
mask = block_size - 1;
|
if (where->size != widened.size || where->start != widened.start) {
|
||||||
if (!memcmp(where, &widened, sizeof(widened)) &&
|
buffer_was_widened = 1;
|
||||||
!((uintptr_t) buffer & mask))
|
log_debug_io("Widening request for %" PRIu64 " bytes at %" PRIu64 " to %" PRIu64 " bytes at %" PRIu64 " on %s (for %s)",
|
||||||
|
where->size, (uint64_t) where->start, widened.size, (uint64_t) widened.start, dev_name(where->dev), _reason_text(reason));
|
||||||
|
} else if (!((uintptr_t) buffer & mask))
|
||||||
|
/* Perform the I/O directly. */
|
||||||
return _io(where, buffer, should_write, reason);
|
return _io(where, buffer, should_write, reason);
|
||||||
|
|
||||||
log_debug_io("Widening request for %" PRIu64 " bytes at %" PRIu64 " to %" PRIu64 " bytes at %" PRIu64 " on %s (for %s)",
|
|
||||||
where->size, (uint64_t) where->start, widened.size, (uint64_t) widened.start, dev_name(where->dev), _reason_text(reason));
|
|
||||||
|
|
||||||
/* Allocate a bounce buffer with an extra block */
|
/* Allocate a bounce buffer with an extra block */
|
||||||
if (!(bounce_buf = bounce = dm_malloc((size_t) widened.size + block_size))) {
|
if (!(bounce_buf = bounce = dm_malloc((size_t) widened.size + block_size))) {
|
||||||
log_error("Bounce buffer malloc failed");
|
log_error("Bounce buffer malloc failed");
|
||||||
@ -265,10 +267,12 @@ static int _aligned_io(struct device_area *where, char *buffer,
|
|||||||
if (((uintptr_t) bounce) & mask)
|
if (((uintptr_t) bounce) & mask)
|
||||||
bounce = (char *) ((((uintptr_t) bounce) + mask) & ~mask);
|
bounce = (char *) ((((uintptr_t) bounce) + mask) & ~mask);
|
||||||
|
|
||||||
/* channel the io through the bounce buffer */
|
/* Do we need to read into the bounce buffer? */
|
||||||
if (!_io(&widened, bounce, 0, reason)) {
|
if ((!should_write || buffer_was_widened) &&
|
||||||
|
!_io(&widened, bounce, 0, reason)) {
|
||||||
if (!should_write)
|
if (!should_write)
|
||||||
goto_out;
|
goto_out;
|
||||||
|
/* FIXME Handle errors properly! */
|
||||||
/* FIXME pre-extend the file */
|
/* FIXME pre-extend the file */
|
||||||
memset(bounce, '\n', widened.size);
|
memset(bounce, '\n', widened.size);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user