1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

io: use sync io if aio fails

io_setup() for aio may fail if a system has reached the
aio request limit.  In this case, fall back to using
sync io.  Also, lvm use of aio can be disabled entirely
with config setting global/use_aio=0.

The system limit for aio requests can be seen from
  /proc/sys/fs/aio-max-nr

The current usage of aio requests can be seen from
  /proc/sys/fs/aio-nr

The system limit for aio requests can be increased by
setting fs.aio-max-nr using sysctl.

Also add last-byte limit to the sync io code.
This commit is contained in:
David Teigland 2018-11-16 12:21:20 -06:00
parent b1e9fe9505
commit ca66d52032
7 changed files with 74 additions and 4 deletions

View File

@ -331,6 +331,8 @@ static void _init_logging(struct cmd_context *cmd)
find_config_tree_bool(cmd, global_test_CFG, NULL); find_config_tree_bool(cmd, global_test_CFG, NULL);
init_test(cmd->default_settings.test); init_test(cmd->default_settings.test);
init_use_aio(find_config_tree_bool(cmd, global_use_aio_CFG, NULL));
/* Settings for logging to file */ /* Settings for logging to file */
if (find_config_tree_bool(cmd, log_overwrite_CFG, NULL)) if (find_config_tree_bool(cmd, log_overwrite_CFG, NULL))
append = 0; append = 0;

View File

@ -1003,6 +1003,9 @@ cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL,
cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 151), NULL, vsn(3, 0, 0), NULL, cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 151), NULL, vsn(3, 0, 0), NULL,
"This setting is no longer used.\n") "This setting is no longer used.\n")
cfg(global_use_aio_CFG, "use_aio", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_AIO, vsn(2, 2, 183), NULL, 0, NULL,
"Use async I/O when reading and writing devices.\n")
cfg(global_use_lvmlockd_CFG, "use_lvmlockd", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 124), NULL, 0, NULL, cfg(global_use_lvmlockd_CFG, "use_lvmlockd", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 124), NULL, 0, NULL,
"Use lvmlockd for locking among hosts using LVM on shared storage.\n" "Use lvmlockd for locking among hosts using LVM on shared storage.\n"
"Applicable only if LVM is compiled with lockd support in which\n" "Applicable only if LVM is compiled with lockd support in which\n"

View File

@ -60,6 +60,7 @@
#define DEFAULT_METADATA_READ_ONLY 0 #define DEFAULT_METADATA_READ_ONLY 0
#define DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH 0 #define DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH 0
#define DEFAULT_UNKNOWN_DEVICE_NAME "[unknown]" #define DEFAULT_UNKNOWN_DEVICE_NAME "[unknown]"
#define DEFAULT_USE_AIO 1
#define DEFAULT_SANLOCK_LV_EXTEND_MB 256 #define DEFAULT_SANLOCK_LV_EXTEND_MB 256

View File

@ -389,6 +389,48 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
return false; return false;
} }
/*
* If bcache block goes past where lvm wants to write, then clamp it.
*/
if ((d == DIR_WRITE) && _last_byte_offset && (fd == _last_byte_fd)) {
uint64_t offset = where;
uint64_t nbytes = len;
sector_t limit_nbytes = 0;
sector_t extra_nbytes = 0;
if (offset > _last_byte_offset) {
log_error("Limit write at %llu len %llu beyond last byte %llu",
(unsigned long long)offset,
(unsigned long long)nbytes,
(unsigned long long)_last_byte_offset);
return false;
}
if (offset + nbytes > _last_byte_offset) {
limit_nbytes = _last_byte_offset - offset;
if (limit_nbytes % _last_byte_sector_size)
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size);
if (extra_nbytes) {
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu",
(unsigned long long)offset,
(unsigned long long)nbytes,
(unsigned long long)limit_nbytes,
(unsigned long long)(limit_nbytes + extra_nbytes));
nbytes = limit_nbytes + extra_nbytes;
} else {
log_debug("Limit write at %llu len %llu to len %llu",
(unsigned long long)offset,
(unsigned long long)nbytes,
(unsigned long long)limit_nbytes);
nbytes = limit_nbytes;
}
}
where = offset;
len = nbytes;
}
while (len) { while (len) {
do { do {
if (d == DIR_READ) if (d == DIR_READ)

View File

@ -799,7 +799,7 @@ out:
static int _setup_bcache(int cache_blocks) static int _setup_bcache(int cache_blocks)
{ {
struct io_engine *ioe; struct io_engine *ioe = NULL;
if (cache_blocks < MIN_BCACHE_BLOCKS) if (cache_blocks < MIN_BCACHE_BLOCKS)
cache_blocks = MIN_BCACHE_BLOCKS; cache_blocks = MIN_BCACHE_BLOCKS;
@ -807,9 +807,18 @@ static int _setup_bcache(int cache_blocks)
if (cache_blocks > MAX_BCACHE_BLOCKS) if (cache_blocks > MAX_BCACHE_BLOCKS)
cache_blocks = MAX_BCACHE_BLOCKS; cache_blocks = MAX_BCACHE_BLOCKS;
if (!(ioe = create_async_io_engine())) { if (use_aio()) {
log_error("Failed to create bcache io engine."); if (!(ioe = create_async_io_engine())) {
return 0; log_warn("Failed to set up async io, using sync io.");
init_use_aio(0);
}
}
if (!ioe) {
if (!(ioe = create_sync_io_engine())) {
log_error("Failed to set up sync io.");
return 0;
}
} }
if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) { if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) {

View File

@ -24,6 +24,7 @@
static int _verbose_level = VERBOSE_BASE_LEVEL; static int _verbose_level = VERBOSE_BASE_LEVEL;
static int _silent = 0; static int _silent = 0;
static int _test = 0; static int _test = 0;
static int _use_aio = 0;
static int _md_filtering = 0; static int _md_filtering = 0;
static int _internal_filtering = 0; static int _internal_filtering = 0;
static int _fwraid_filtering = 0; static int _fwraid_filtering = 0;
@ -69,6 +70,11 @@ void init_test(int level)
_test = level; _test = level;
} }
void init_use_aio(int use_aio)
{
_use_aio = use_aio;
}
void init_md_filtering(int level) void init_md_filtering(int level)
{ {
_md_filtering = level; _md_filtering = level;
@ -215,6 +221,11 @@ int test_mode(void)
return _test; return _test;
} }
int use_aio(void)
{
return _use_aio;
}
int md_filtering(void) int md_filtering(void)
{ {
return _md_filtering; return _md_filtering;

View File

@ -25,6 +25,7 @@ enum dev_ext_e;
void init_verbose(int level); void init_verbose(int level);
void init_silent(int silent); void init_silent(int silent);
void init_test(int level); void init_test(int level);
void init_use_aio(int use_aio);
void init_md_filtering(int level); void init_md_filtering(int level);
void init_internal_filtering(int level); void init_internal_filtering(int level);
void init_fwraid_filtering(int level); void init_fwraid_filtering(int level);
@ -55,6 +56,7 @@ const char *get_cmd_name(void);
void set_sysfs_dir_path(const char *path); void set_sysfs_dir_path(const char *path);
int test_mode(void); int test_mode(void);
int use_aio(void);
int md_filtering(void); int md_filtering(void);
int internal_filtering(void); int internal_filtering(void);
int fwraid_filtering(void); int fwraid_filtering(void);