mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
device: Remove some data copying between buffers.
Callers that read larger amounts of data now get a pointer to read-only data directly without copying it through an intermediate buffer. This data is owned by the device layer so the callers no longer free it.
This commit is contained in:
parent
4d568b709c
commit
dcb2a5a611
@ -534,9 +534,6 @@ static void _process_config_file_buffer(int failed, void *context, void *data)
|
||||
}
|
||||
|
||||
out:
|
||||
if (!failed && !pcfp->use_mmap)
|
||||
dm_free(data);
|
||||
|
||||
if (pcfp->config_file_read_fd_callback)
|
||||
pcfp->config_file_read_fd_callback(!pcfp->ret, pcfp->config_file_read_fd_context, NULL);
|
||||
}
|
||||
@ -612,6 +609,7 @@ int config_file_read_fd(struct dm_pool *mem, struct dm_config_tree *cft, struct
|
||||
if (!(buf = dev_read_circular(dev, (uint64_t) offset, size, (uint64_t) offset2, size2, reason)))
|
||||
goto_out;
|
||||
_process_config_file_buffer(0, pcfp, buf);
|
||||
dm_free(buf);
|
||||
} else if (!dev_read_callback(dev, (uint64_t) offset, size, reason, _process_config_file_buffer, pcfp))
|
||||
goto_out;
|
||||
r = pcfp->ret;
|
||||
|
@ -284,7 +284,7 @@ static int _aligned_io(struct device_area *where, char *buffer,
|
||||
where->size, (uint64_t) where->start, widened.size, (uint64_t) widened.start, dev_name(where->dev), _reason_text(reason));
|
||||
}
|
||||
|
||||
if (!buffer_was_widened && !((uintptr_t) buffer & mask))
|
||||
if (should_write && !buffer_was_widened && !((uintptr_t) buffer & mask))
|
||||
/* Perform the I/O directly. */
|
||||
bounce = buffer;
|
||||
#ifndef DEBUG_MEM
|
||||
@ -308,7 +308,7 @@ static int _aligned_io(struct device_area *where, char *buffer,
|
||||
}
|
||||
#endif
|
||||
|
||||
devbuf = EXTRA_IO(reason) ? &where->dev->last_extra_devbuf : &where->dev->last_devbuf;
|
||||
devbuf = DEV_DEVBUF(where->dev, reason);
|
||||
_release_devbuf(devbuf);
|
||||
devbuf->malloc_address = bounce_buf;
|
||||
devbuf->buf = bounce;
|
||||
@ -345,9 +345,6 @@ static int _aligned_io(struct device_area *where, char *buffer,
|
||||
}
|
||||
|
||||
/* read */
|
||||
if (bounce_buf)
|
||||
memcpy(buffer, bounce + (where->start - widened.start),
|
||||
(size_t) where->size);
|
||||
|
||||
/* We store what we just read as it often also satisfies the next request */
|
||||
devbuf->data = bounce + (where->start - widened.start);
|
||||
@ -782,7 +779,10 @@ static void _dev_inc_error_count(struct device *dev)
|
||||
dev->max_error_count, dev_name(dev));
|
||||
}
|
||||
|
||||
static int _dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason, char *buf)
|
||||
/*
|
||||
* Data is returned (read-only) at dev->last_[extra_]devbuf->data
|
||||
*/
|
||||
static int _dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason)
|
||||
{
|
||||
struct device_area where;
|
||||
int ret;
|
||||
@ -797,7 +797,7 @@ static int _dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_rea
|
||||
where.start = offset;
|
||||
where.size = len;
|
||||
|
||||
ret = _aligned_io(&where, buf, 0, reason);
|
||||
ret = _aligned_io(&where, NULL, 0, reason);
|
||||
if (!ret)
|
||||
_dev_inc_error_count(dev);
|
||||
|
||||
@ -814,30 +814,24 @@ char *dev_read(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_dev_read(dev, offset, len, reason, buf)) {
|
||||
if (!_dev_read(dev, offset, len, reason)) {
|
||||
log_error("Read from %s failed", dev_name(dev));
|
||||
dm_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(buf, DEV_DEVBUF(dev, reason)->data, len);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Callback fn is responsible for dm_free */
|
||||
int dev_read_callback(struct device *dev, uint64_t offset, size_t len, dev_io_reason_t reason,
|
||||
lvm_callback_fn_t dev_read_callback_fn, void *callback_context)
|
||||
{
|
||||
char *buf;
|
||||
int r = 0;
|
||||
|
||||
if (!(buf = dm_malloc(len))) {
|
||||
log_error("Buffer allocation failed for device read.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!_dev_read(dev, offset, len, reason, buf)) {
|
||||
if (!_dev_read(dev, offset, len, reason)) {
|
||||
log_error("Read from %s failed", dev_name(dev));
|
||||
dm_free(buf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -845,7 +839,7 @@ int dev_read_callback(struct device *dev, uint64_t offset, size_t len, dev_io_re
|
||||
|
||||
out:
|
||||
if (dev_read_callback_fn)
|
||||
dev_read_callback_fn(!r, callback_context, buf);
|
||||
dev_read_callback_fn(!r, callback_context, DEV_DEVBUF(dev, reason)->data);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -879,18 +873,22 @@ char *dev_read_circular(struct device *dev, uint64_t offset, size_t len,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_dev_read(dev, offset, len, reason, buf)) {
|
||||
if (!_dev_read(dev, offset, len, reason)) {
|
||||
log_error("Read from %s failed", dev_name(dev));
|
||||
dm_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_dev_read(dev, offset2, len2, reason, buf + len)) {
|
||||
memcpy(buf, DEV_DEVBUF(dev, reason)->data, len);
|
||||
|
||||
if (!_dev_read(dev, offset2, len2, reason)) {
|
||||
log_error("Circular read from %s failed", dev_name(dev));
|
||||
dm_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(buf + len, DEV_DEVBUF(dev, reason)->data, len2);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -124,6 +124,7 @@ typedef enum dev_io_reason {
|
||||
* Is this I/O for a device's extra metadata area?
|
||||
*/
|
||||
#define EXTRA_IO(reason) ((reason) == DEV_IO_MDA_EXTRA_HEADER || (reason) == DEV_IO_MDA_EXTRA_CONTENT)
|
||||
#define DEV_DEVBUF(dev, reason) (EXTRA_IO((reason)) ? &(dev)->last_extra_devbuf : &(dev)->last_devbuf)
|
||||
|
||||
struct device_list {
|
||||
struct dm_list list;
|
||||
|
@ -385,9 +385,6 @@ static void _process_raw_mda_header(int failed, void *context, void *data)
|
||||
bad:
|
||||
prmp->ret = 0;
|
||||
out:
|
||||
if (!failed)
|
||||
dm_free(data);
|
||||
|
||||
if (prmp->ret && prmp->mdah_callback_fn)
|
||||
prmp->mdah_callback_fn(0, prmp->mdah_callback_context, mdah);
|
||||
}
|
||||
@ -1474,8 +1471,7 @@ static void _vgname_from_mda_validate(int failed, void *context, void *data)
|
||||
}
|
||||
|
||||
out:
|
||||
if (!failed)
|
||||
dm_free(data);
|
||||
;
|
||||
}
|
||||
|
||||
int vgname_from_mda(const struct format_type *fmt,
|
||||
|
@ -226,8 +226,6 @@ static void _find_labeller(int failed, void *context, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
dm_free(readbuf);
|
||||
|
||||
if (!l) {
|
||||
if ((info = lvmcache_info_from_pvid(dev->pvid, dev, 0)))
|
||||
_update_lvmcache_orphan(info);
|
||||
|
Loading…
Reference in New Issue
Block a user