mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
On 'buffer full' condition, double buffer size and repeat ioctl. [Untested]
This commit is contained in:
parent
68366c99b2
commit
4e16b1e7ad
@ -1,5 +1,6 @@
|
|||||||
Version 1.01.05 -
|
Version 1.01.05 -
|
||||||
=============================
|
=============================
|
||||||
|
On 'buffer full' condition, double buffer size and repeat ioctl.
|
||||||
Fix termination of getopt_long() option array.
|
Fix termination of getopt_long() option array.
|
||||||
Report 'buffer full' condition with v4 ioctl as well as with v1.
|
Report 'buffer full' condition with v4 ioctl as well as with v1.
|
||||||
|
|
||||||
|
@ -1026,7 +1026,7 @@ static void *_add_target(struct target *t, void *out, void *end)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dm_ioctl *_flatten(struct dm_task *dmt)
|
static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
|
||||||
{
|
{
|
||||||
const size_t min_size = 16 * 1024;
|
const size_t min_size = 16 * 1024;
|
||||||
const int (*version)[3];
|
const int (*version)[3];
|
||||||
@ -1077,6 +1077,10 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt)
|
|||||||
if (len < min_size)
|
if (len < min_size)
|
||||||
len = min_size;
|
len = min_size;
|
||||||
|
|
||||||
|
/* Increase buffer size if repeating because buffer was too small */
|
||||||
|
while (repeat_count--)
|
||||||
|
len *= 2;
|
||||||
|
|
||||||
if (!(dmi = malloc(len)))
|
if (!(dmi = malloc(len)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1276,40 +1280,14 @@ static int _create_and_load_v4(struct dm_task *dmt)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_task_run(struct dm_task *dmt)
|
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned repeat_count)
|
||||||
{
|
{
|
||||||
struct dm_ioctl *dmi = NULL;
|
struct dm_ioctl *dmi;
|
||||||
unsigned int command;
|
|
||||||
|
|
||||||
#ifdef DM_COMPAT
|
dmi = _flatten(dmt, repeat_count);
|
||||||
if (_dm_version == 1)
|
|
||||||
return _dm_task_run_v1(dmt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((unsigned) dmt->type >=
|
|
||||||
(sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) {
|
|
||||||
log_error("Internal error: unknown device-mapper task %d",
|
|
||||||
dmt->type);
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
command = _cmd_data_v4[dmt->type].cmd;
|
|
||||||
|
|
||||||
/* Old-style creation had a table supplied */
|
|
||||||
if (dmt->type == DM_DEVICE_CREATE && dmt->head)
|
|
||||||
return _create_and_load_v4(dmt);
|
|
||||||
|
|
||||||
if (dmt->type == DM_DEVICE_MKNODES && !dmt->dev_name &&
|
|
||||||
!dmt->uuid && dmt->major <= 0)
|
|
||||||
return _mknodes_v4(dmt);
|
|
||||||
|
|
||||||
if (!_open_control())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dmi = _flatten(dmt);
|
|
||||||
if (!dmi) {
|
if (!dmi) {
|
||||||
log_error("Couldn't create ioctl argument");
|
log_error("Couldn't create ioctl argument");
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dmt->type == DM_DEVICE_TABLE)
|
if (dmt->type == DM_DEVICE_TABLE)
|
||||||
@ -1338,15 +1316,65 @@ int dm_task_run(struct dm_task *dmt)
|
|||||||
log_error("device-mapper ioctl "
|
log_error("device-mapper ioctl "
|
||||||
"cmd %d failed: %s",
|
"cmd %d failed: %s",
|
||||||
_IOC_NR(command), strerror(errno));
|
_IOC_NR(command), strerror(errno));
|
||||||
goto bad;
|
free(dmi);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* Userspace alternative for testing */
|
#else /* Userspace alternative for testing */
|
||||||
#endif
|
#endif
|
||||||
|
return dmi;
|
||||||
|
}
|
||||||
|
|
||||||
if (dmi->flags & DM_BUFFER_FULL_FLAG)
|
int dm_task_run(struct dm_task *dmt)
|
||||||
/* FIXME Increase buffer size and retry operation (if query) */
|
{
|
||||||
log_error("Warning: libdevmapper buffer too small for data");
|
struct dm_ioctl *dmi;
|
||||||
|
unsigned command;
|
||||||
|
unsigned repeat_count = 0;
|
||||||
|
|
||||||
|
#ifdef DM_COMPAT
|
||||||
|
if (_dm_version == 1)
|
||||||
|
return _dm_task_run_v1(dmt);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((unsigned) dmt->type >=
|
||||||
|
(sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) {
|
||||||
|
log_error("Internal error: unknown device-mapper task %d",
|
||||||
|
dmt->type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = _cmd_data_v4[dmt->type].cmd;
|
||||||
|
|
||||||
|
/* Old-style creation had a table supplied */
|
||||||
|
if (dmt->type == DM_DEVICE_CREATE && dmt->head)
|
||||||
|
return _create_and_load_v4(dmt);
|
||||||
|
|
||||||
|
if (dmt->type == DM_DEVICE_MKNODES && !dmt->dev_name &&
|
||||||
|
!dmt->uuid && dmt->major <= 0)
|
||||||
|
return _mknodes_v4(dmt);
|
||||||
|
|
||||||
|
if (!_open_control())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
repeat_ioctl:
|
||||||
|
if (!(dmi = _do_dm_ioctl(dmt, repeat_count)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dmi->flags & DM_BUFFER_FULL_FLAG) {
|
||||||
|
switch (dmt->type) {
|
||||||
|
case DM_DEVICE_LIST_VERSIONS:
|
||||||
|
case DM_DEVICE_LIST:
|
||||||
|
case DM_DEVICE_DEPS:
|
||||||
|
case DM_DEVICE_STATUS:
|
||||||
|
case DM_DEVICE_TABLE:
|
||||||
|
case DM_DEVICE_WAITEVENT:
|
||||||
|
repeat_count++;
|
||||||
|
free(dmi);
|
||||||
|
goto repeat_ioctl;
|
||||||
|
default:
|
||||||
|
log_error("Warning: libdevmapper buffer too small for data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (dmt->type) {
|
switch (dmt->type) {
|
||||||
case DM_DEVICE_CREATE:
|
case DM_DEVICE_CREATE:
|
||||||
|
Loading…
Reference in New Issue
Block a user