From 7333022adfc7905d96e8be3b7b5a977f85a567c9 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 6 Aug 2023 01:14:44 +0300 Subject: [PATCH] Add a third I/O mode: O_DIRECT|O_SYNC, change parameters to data_io/meta_io/journal_io --- docs/config/layout-cluster.en.md | 5 +- docs/config/layout-cluster.ru.md | 5 +- docs/config/layout-osd.en.md | 4 +- docs/config/layout-osd.ru.md | 4 +- docs/config/osd.en.md | 76 ++++++++++------- docs/config/osd.ru.md | 79 +++++++++-------- docs/config/src/layout-cluster.yml | 10 ++- docs/config/src/layout-osd.yml | 8 +- docs/config/src/osd.yml | 131 +++++++++++++++++------------ src/blockstore_disk.cpp | 52 +++++++++--- src/blockstore_disk.h | 5 +- src/disk_tool.cpp | 2 +- src/disk_tool_prepare.cpp | 10 +-- src/disk_tool_resize.cpp | 2 +- 14 files changed, 236 insertions(+), 157 deletions(-) diff --git a/docs/config/layout-cluster.en.md b/docs/config/layout-cluster.en.md index ca642053..b87ee9fe 100644 --- a/docs/config/layout-cluster.en.md +++ b/docs/config/layout-cluster.en.md @@ -96,8 +96,9 @@ SSD cache or "media-cache" - for example, a lot of Seagate EXOS drives have it (they have internal SSD cache even though it's not stated in datasheets). Setting this parameter to "all" or "small" in OSD parameters requires enabling -disable_journal_fsync and disable_meta_fsync, setting it to "all" also requires -enabling disable_data_fsync. +[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and +[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to +"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync). TLDR: For optimal performance, set immediate_commit to "all" if you only use SSDs with supercapacitor-based power loss protection (nonvolatile diff --git a/docs/config/layout-cluster.ru.md b/docs/config/layout-cluster.ru.md index 2d1108dc..5a703359 100644 --- a/docs/config/layout-cluster.ru.md +++ b/docs/config/layout-cluster.ru.md @@ -103,8 +103,9 @@ HDD-дисках с внутренним SSD или "медиа" кэшем - н указано в спецификациях). Указание "all" или "small" в настройках / командной строке OSD требует -включения disable_journal_fsync и disable_meta_fsync, значение "all" также -требует включения disable_data_fsync. +включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и +[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all" +также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync). Итого, вкратце: для оптимальной производительности установите immediate_commit в значение "all", если вы используете в кластере только SSD diff --git a/docs/config/layout-osd.en.md b/docs/config/layout-osd.en.md index 72289d03..55aacfbd 100644 --- a/docs/config/layout-osd.en.md +++ b/docs/config/layout-osd.en.md @@ -213,6 +213,6 @@ Thus, recommended setups are: 3. Hybrid HDD+SSD: csum_block_size=4k + inmemory_metadata=false 4. HDD-only, faster random read: csum_block_size=32k 5. HDD-only, faster random write: csum_block_size=4k + - inmemory_metadata=false + cached_io_meta=true + inmemory_metadata=false + meta_io=cached -See also [cached_io_meta](osd.en.md#cached_io_meta). +See also [meta_io](osd.en.md#meta_io). diff --git a/docs/config/layout-osd.ru.md b/docs/config/layout-osd.ru.md index a65ea379..d8ced417 100644 --- a/docs/config/layout-osd.ru.md +++ b/docs/config/layout-osd.ru.md @@ -226,6 +226,6 @@ csum_block_size данных. 3. Гибридные HDD+SSD: csum_block_size=4k + inmemory_metadata=false 4. Только HDD, быстрее случайное чтение: csum_block_size=32k 5. Только HDD, быстрее случайная запись: csum_block_size=4k + - inmemory_metadata=false + cached_io_meta=true + inmemory_metadata=false + meta_io=cached -Смотрите также [cached_io_meta](osd.ru.md#cached_io_meta). +Смотрите также [meta_io](osd.ru.md#meta_io). diff --git a/docs/config/osd.en.md b/docs/config/osd.en.md index 6c15a59b..ddb8befe 100644 --- a/docs/config/osd.en.md +++ b/docs/config/osd.en.md @@ -31,9 +31,9 @@ them, even without restarting by updating configuration in etcd. - [max_flusher_count](#max_flusher_count) - [inmemory_metadata](#inmemory_metadata) - [inmemory_journal](#inmemory_journal) -- [cached_io_data](#cached_io_data) -- [cached_io_meta](#cached_io_meta) -- [cached_io_journal](#cached_io_journal) +- [data_io](#data_io) +- [meta_io](#meta_io) +- [journal_io](#journal_io) - [journal_sector_buffer_count](#journal_sector_buffer_count) - [journal_no_same_sector_overwrites](#journal_no_same_sector_overwrites) - [throttle_small_writes](#throttle_small_writes) @@ -258,47 +258,59 @@ is typically very small because it's sufficient to have 16-32 MB journal for SSD OSDs. However, in theory it's possible that you'll want to turn it off for hybrid (HDD+SSD) OSDs with large journals on quick devices. -## cached_io_data +## data_io -- Type: boolean -- Default: false +- Type: string +- Default: direct -Read and write *data* through Linux page cache, i.e. use a file descriptor -opened with O_SYNC, but without O_DIRECT for I/O. May improve read -performance for hot data and slower disks - HDDs and maybe SATA SSDs. -Not recommended for desktop SSDs without capacitors because O_SYNC flushes -disk cache on every write. +I/O mode for *data*. One of "direct", "cached" or "directsync". Corresponds +to O_DIRECT, O_SYNC and O_DIRECT|O_SYNC, respectively. -## cached_io_meta +Choose "cached" to use Linux page cache. This may improve read performance +for hot data and slower disks - HDDs and maybe SATA SSDs - but will slightly +decrease write performance for fast disks because page cache is an overhead +itself. -- Type: boolean -- Default: false +Choose "directsync" to use [immediate_commit](layout-cluster.ru.md#immediate_commit) +(which requires disable_data_fsync) with drives having write-back cache +which can't be turned off, for example, Intel Optane. Also note that *some* +desktop SSDs (for example, HP EX950) may ignore O_SYNC thus making +disable_data_fsync unsafe even with "directsync". -Read and write *metadata* through Linux page cache. May improve read -performance only if your drives are relatively slow (HDD, SATA SSD), and -only if checksums are enabled and [inmemory_metadata](#inmemory_metadata) -is disabled, because in this case metadata blocks are read from disk -on every read request to verify checksums and caching them may reduce this -extra read load. +## meta_io -Absolutely pointless to enable with enabled inmemory_metadata because all -metadata is kept in memory anyway, and likely pointless without checksums, -because in that case, metadata blocks are read from disk only during journal +- Type: string +- Default: direct + +I/O mode for *metadata*. One of "direct", "cached" or "directsync". + +"cached" may improve read performance, but only under the following conditions: +1. your drives are relatively slow (HDD, SATA SSD), and +2. checksums are enabled, and +3. [inmemory_metadata](#inmemory_metadata) is disabled. +Under all these conditions, metadata blocks are read from disk on every +read request to verify checksums and caching them may reduce this extra +read load. Without (3) metadata is never read from the disk after starting, +and without (2) metadata blocks are read from disk only during journal flushing. -If the same device is used for data and metadata, enabling [cached_io_data](#cached_io_data) -also enables this parameter, given that it isn't turned off explicitly. +"directsync" is the same as above. -## cached_io_journal +If the same device is used for data and metadata, meta_io by default is set +to the same value as [data_io](#data_io). -- Type: boolean -- Default: false +## journal_io -Read and write *journal* through Linux page cache. May improve read -performance if [inmemory_journal](#inmemory_journal) is turned off. +- Type: string +- Default: direct -If the same device is used for metadata and journal, enabling [cached_io_meta](#cached_io_meta) -also enables this parameter, given that it isn't turned off explicitly. +I/O mode for *journal*. One of "direct", "cached" or "directsync". + +Here, "cached" may only improve read performance for recent writes and +only if [inmemory_journal](#inmemory_journal) is turned off. + +If the same device is used for metadata and journal, journal_io by default +is set to the same value as [meta_io](#meta_io). ## journal_sector_buffer_count diff --git a/docs/config/osd.ru.md b/docs/config/osd.ru.md index 0a1e962c..9353b6ef 100644 --- a/docs/config/osd.ru.md +++ b/docs/config/osd.ru.md @@ -32,9 +32,9 @@ - [max_flusher_count](#max_flusher_count) - [inmemory_metadata](#inmemory_metadata) - [inmemory_journal](#inmemory_journal) -- [cached_io_data](#cached_io_data) -- [cached_io_meta](#cached_io_meta) -- [cached_io_journal](#cached_io_journal) +- [data_io](#data_io) +- [meta_io](#meta_io) +- [journal_io](#journal_io) - [journal_sector_buffer_count](#journal_sector_buffer_count) - [journal_no_same_sector_overwrites](#journal_no_same_sector_overwrites) - [throttle_small_writes](#throttle_small_writes) @@ -266,51 +266,62 @@ Flusher - это микро-поток (корутина), которая коп параметра может оказаться полезным для гибридных OSD (HDD+SSD) с большими журналами, расположенными на быстром по сравнению с HDD устройстве. -## cached_io_data +## data_io -- Тип: булево (да/нет) -- Значение по умолчанию: false +- Тип: строка +- Значение по умолчанию: direct -Читать и записывать *данные* через системный кэш Linux (page cache), то есть, -использовать для данных файловый дескриптор, открытый без флага O_DIRECT, но -с флагом O_SYNC. Может улучшить скорость чтения для относительно медленных -дисков - HDD и, возможно, SATA SSD. Не рекомендуется для потребительских -SSD без конденсаторов, так как O_SYNC сбрасывает кэш диска при каждой записи. +Режим ввода-вывода для *данных*. Одно из значений "direct", "cached" или +"directsync", означающих O_DIRECT, O_SYNC и O_DIRECT|O_SYNC, соответственно. -## cached_io_meta +Выберите "cached", чтобы использовать системный кэш Linux (page cache) при +чтении и записи. Это может улучшить скорость чтения горячих данных с +относительно медленных дисков - HDD и, возможно, SATA SSD - но немного +снижает производительность записи для быстрых дисков, так как кэш сам по +себе тоже добавляет накладные расходы. -- Тип: булево (да/нет) -- Значение по умолчанию: false +Выберите "directsync", если хотите задействовать +[immediate_commit](layout-cluster.ru.md#immediate_commit) (требующий +включенияd disable_data_fsync) на дисках с неотключаемым кэшем. Пример таких +дисков - Intel Optane. При этом также стоит иметь в виду, что *некоторые* +настольные SSD (например, HP EX950) игнорируют флаг O_SYNC, делая отключение +fsync небезопасным даже с режимом "directsync". -Читать и записывать *метаданные* через системный кэш Linux. Может улучшить -скорость чтения, если у вас медленные диски, и только если контрольные суммы -включены, а параметр [inmemory_metadata](#inmemory_metadata) отключён, так -как в этом случае блоки метаданных читаются с диска при каждом запросе чтения +## meta_io + +- Тип: строка +- Значение по умолчанию: direct + +Режим ввода-вывода для *метаданных*. Одно из значений "direct", "cached" или +"directsync". + +"cached" может улучшить скорость чтения, если: +1. у вас медленные диски (HDD, SATA SSD) +2. контрольные суммы включены +3. параметр [inmemory_metadata](#inmemory_metadata) отключён. +При этих условиях блоки метаданных читаются с диска при каждом запросе чтения для проверки контрольных сумм и их кэширование может снизить дополнительную -нагрузку на диск. +нагрузку на диск. Без (3) метаданные никогда не читаются с диска после +запуска OSD, а без (2) блоки метаданных читаются только при сбросе журнала. -Абсолютно бессмысленно включать данный параметр, если параметр -inmemory_metadata включён (по умолчанию это так), и также вероятно -бессмысленно включать его, если не включены контрольные суммы, так как в -этом случае блоки метаданных читаются с диска только во время сброса -журнала. +Если одно и то же устройство используется для данных и метаданных, режим +ввода-вывода метаданных по умолчанию устанавливается равным [data_io](#data_io). -Если одно и то же устройство используется для данных и метаданных, включение -[cached_io_data](#cached_io_data) также включает данный параметр, при -условии, что он не отключён явным образом. +## journal_io -## cached_io_journal +- Тип: строка +- Значение по умолчанию: direct -- Тип: булево (да/нет) -- Значение по умолчанию: false +Режим ввода-вывода для *журнала*. Одно из значений "direct", "cached" или +"directsync". -Читать и записывать *журнал* через системный кэш Linux. Может улучшить -скорость чтения, если параметр [inmemory_journal](#inmemory_journal) +Здесь "cached" может улучшить скорость чтения только недавно записанных +данных и только если параметр [inmemory_journal](#inmemory_journal) отключён. Если одно и то же устройство используется для метаданных и журнала, -включение [cached_io_meta](#cached_io_meta) также включает данный -параметр, при условии, что он не отключён явным образом. +режим ввода-вывода журнала по умолчанию устанавливается равным +[meta_io](#meta_io). ## journal_sector_buffer_count diff --git a/docs/config/src/layout-cluster.yml b/docs/config/src/layout-cluster.yml index f30ae9c5..fe12ecfd 100644 --- a/docs/config/src/layout-cluster.yml +++ b/docs/config/src/layout-cluster.yml @@ -87,8 +87,9 @@ it (they have internal SSD cache even though it's not stated in datasheets). Setting this parameter to "all" or "small" in OSD parameters requires enabling - disable_journal_fsync and disable_meta_fsync, setting it to "all" also requires - enabling disable_data_fsync. + [disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and + [disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to + "all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync). TLDR: For optimal performance, set immediate_commit to "all" if you only use SSDs with supercapacitor-based power loss protection (nonvolatile @@ -140,8 +141,9 @@ указано в спецификациях). Указание "all" или "small" в настройках / командной строке OSD требует - включения disable_journal_fsync и disable_meta_fsync, значение "all" также - требует включения disable_data_fsync. + включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и + [disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all" + также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync). Итого, вкратце: для оптимальной производительности установите immediate_commit в значение "all", если вы используете в кластере только SSD diff --git a/docs/config/src/layout-osd.yml b/docs/config/src/layout-osd.yml index cdda04a9..47bdc8ce 100644 --- a/docs/config/src/layout-osd.yml +++ b/docs/config/src/layout-osd.yml @@ -244,9 +244,9 @@ 3. Hybrid HDD+SSD: csum_block_size=4k + inmemory_metadata=false 4. HDD-only, faster random read: csum_block_size=32k 5. HDD-only, faster random write: csum_block_size=4k + - inmemory_metadata=false + cached_io_meta=true + inmemory_metadata=false + meta_io=cached - See also [cached_io_meta](osd.en.md#cached_io_meta). + See also [meta_io](osd.en.md#meta_io). info_ru: | Размер блока расчёта контрольных сумм. @@ -271,6 +271,6 @@ 3. Гибридные HDD+SSD: csum_block_size=4k + inmemory_metadata=false 4. Только HDD, быстрее случайное чтение: csum_block_size=32k 5. Только HDD, быстрее случайная запись: csum_block_size=4k + - inmemory_metadata=false + cached_io_meta=true + inmemory_metadata=false + meta_io=cached - Смотрите также [cached_io_meta](osd.ru.md#cached_io_meta). + Смотрите также [meta_io](osd.ru.md#meta_io). diff --git a/docs/config/src/osd.yml b/docs/config/src/osd.yml index 519bbedd..7ca498d2 100644 --- a/docs/config/src/osd.yml +++ b/docs/config/src/osd.yml @@ -260,73 +260,96 @@ достаточно 16- или 32-мегабайтного журнала. Однако в теории отключение параметра может оказаться полезным для гибридных OSD (HDD+SSD) с большими журналами, расположенными на быстром по сравнению с HDD устройстве. -- name: cached_io_data - type: bool - default: false +- name: data_io + type: string + default: direct info: | - Read and write *data* through Linux page cache, i.e. use a file descriptor - opened with O_SYNC, but without O_DIRECT for I/O. May improve read - performance for hot data and slower disks - HDDs and maybe SATA SSDs. - Not recommended for desktop SSDs without capacitors because O_SYNC flushes - disk cache on every write. - info_ru: | - Читать и записывать *данные* через системный кэш Linux (page cache), то есть, - использовать для данных файловый дескриптор, открытый без флага O_DIRECT, но - с флагом O_SYNC. Может улучшить скорость чтения для относительно медленных - дисков - HDD и, возможно, SATA SSD. Не рекомендуется для потребительских - SSD без конденсаторов, так как O_SYNC сбрасывает кэш диска при каждой записи. -- name: cached_io_meta - type: bool - default: false - info: | - Read and write *metadata* through Linux page cache. May improve read - performance only if your drives are relatively slow (HDD, SATA SSD), and - only if checksums are enabled and [inmemory_metadata](#inmemory_metadata) - is disabled, because in this case metadata blocks are read from disk - on every read request to verify checksums and caching them may reduce this - extra read load. + I/O mode for *data*. One of "direct", "cached" or "directsync". Corresponds + to O_DIRECT, O_SYNC and O_DIRECT|O_SYNC, respectively. - Absolutely pointless to enable with enabled inmemory_metadata because all - metadata is kept in memory anyway, and likely pointless without checksums, - because in that case, metadata blocks are read from disk only during journal + Choose "cached" to use Linux page cache. This may improve read performance + for hot data and slower disks - HDDs and maybe SATA SSDs - but will slightly + decrease write performance for fast disks because page cache is an overhead + itself. + + Choose "directsync" to use [immediate_commit](layout-cluster.ru.md#immediate_commit) + (which requires disable_data_fsync) with drives having write-back cache + which can't be turned off, for example, Intel Optane. Also note that *some* + desktop SSDs (for example, HP EX950) may ignore O_SYNC thus making + disable_data_fsync unsafe even with "directsync". + info_ru: | + Режим ввода-вывода для *данных*. Одно из значений "direct", "cached" или + "directsync", означающих O_DIRECT, O_SYNC и O_DIRECT|O_SYNC, соответственно. + + Выберите "cached", чтобы использовать системный кэш Linux (page cache) при + чтении и записи. Это может улучшить скорость чтения горячих данных с + относительно медленных дисков - HDD и, возможно, SATA SSD - но немного + снижает производительность записи для быстрых дисков, так как кэш сам по + себе тоже добавляет накладные расходы. + + Выберите "directsync", если хотите задействовать + [immediate_commit](layout-cluster.ru.md#immediate_commit) (требующий + включенияd disable_data_fsync) на дисках с неотключаемым кэшем. Пример таких + дисков - Intel Optane. При этом также стоит иметь в виду, что *некоторые* + настольные SSD (например, HP EX950) игнорируют флаг O_SYNC, делая отключение + fsync небезопасным даже с режимом "directsync". +- name: meta_io + type: string + default: direct + info: | + I/O mode for *metadata*. One of "direct", "cached" or "directsync". + + "cached" may improve read performance, but only under the following conditions: + 1. your drives are relatively slow (HDD, SATA SSD), and + 2. checksums are enabled, and + 3. [inmemory_metadata](#inmemory_metadata) is disabled. + Under all these conditions, metadata blocks are read from disk on every + read request to verify checksums and caching them may reduce this extra + read load. Without (3) metadata is never read from the disk after starting, + and without (2) metadata blocks are read from disk only during journal flushing. - If the same device is used for data and metadata, enabling [cached_io_data](#cached_io_data) - also enables this parameter, given that it isn't turned off explicitly. + "directsync" is the same as above. + + If the same device is used for data and metadata, meta_io by default is set + to the same value as [data_io](#data_io). info_ru: | - Читать и записывать *метаданные* через системный кэш Linux. Может улучшить - скорость чтения, если у вас медленные диски, и только если контрольные суммы - включены, а параметр [inmemory_metadata](#inmemory_metadata) отключён, так - как в этом случае блоки метаданных читаются с диска при каждом запросе чтения + Режим ввода-вывода для *метаданных*. Одно из значений "direct", "cached" или + "directsync". + + "cached" может улучшить скорость чтения, если: + 1. у вас медленные диски (HDD, SATA SSD) + 2. контрольные суммы включены + 3. параметр [inmemory_metadata](#inmemory_metadata) отключён. + При этих условиях блоки метаданных читаются с диска при каждом запросе чтения для проверки контрольных сумм и их кэширование может снизить дополнительную - нагрузку на диск. + нагрузку на диск. Без (3) метаданные никогда не читаются с диска после + запуска OSD, а без (2) блоки метаданных читаются только при сбросе журнала. - Абсолютно бессмысленно включать данный параметр, если параметр - inmemory_metadata включён (по умолчанию это так), и также вероятно - бессмысленно включать его, если не включены контрольные суммы, так как в - этом случае блоки метаданных читаются с диска только во время сброса - журнала. - - Если одно и то же устройство используется для данных и метаданных, включение - [cached_io_data](#cached_io_data) также включает данный параметр, при - условии, что он не отключён явным образом. -- name: cached_io_journal - type: bool - default: false + Если одно и то же устройство используется для данных и метаданных, режим + ввода-вывода метаданных по умолчанию устанавливается равным [data_io](#data_io). +- name: journal_io + type: string + default: direct info: | - Read and write *journal* through Linux page cache. May improve read - performance if [inmemory_journal](#inmemory_journal) is turned off. + I/O mode for *journal*. One of "direct", "cached" or "directsync". - If the same device is used for metadata and journal, enabling [cached_io_meta](#cached_io_meta) - also enables this parameter, given that it isn't turned off explicitly. + Here, "cached" may only improve read performance for recent writes and + only if [inmemory_journal](#inmemory_journal) is turned off. + + If the same device is used for metadata and journal, journal_io by default + is set to the same value as [meta_io](#meta_io). info_ru: | - Читать и записывать *журнал* через системный кэш Linux. Может улучшить - скорость чтения, если параметр [inmemory_journal](#inmemory_journal) + Режим ввода-вывода для *журнала*. Одно из значений "direct", "cached" или + "directsync". + + Здесь "cached" может улучшить скорость чтения только недавно записанных + данных и только если параметр [inmemory_journal](#inmemory_journal) отключён. Если одно и то же устройство используется для метаданных и журнала, - включение [cached_io_meta](#cached_io_meta) также включает данный - параметр, при условии, что он не отключён явным образом. + режим ввода-вывода журнала по умолчанию устанавливается равным + [meta_io](#meta_io). - name: journal_sector_buffer_count type: int default: 32 diff --git a/src/blockstore_disk.cpp b/src/blockstore_disk.cpp index 6711349e..07e049ab 100644 --- a/src/blockstore_disk.cpp +++ b/src/blockstore_disk.cpp @@ -45,13 +45,31 @@ void blockstore_disk_t::parse_config(std::map & config meta_block_size = parse_size(config["meta_block_size"]); bitmap_granularity = parse_size(config["bitmap_granularity"]); meta_format = stoull_full(config["meta_format"]); - cached_io_data = config["cached_io_data"] == "true" || config["cached_io_data"] == "yes" || config["cached_io_data"] == "1"; - cached_io_meta = cached_io_data && (meta_device == data_device || meta_device == "") && - config.find("cached_io_meta") == config.end() || - config["cached_io_meta"] == "true" || config["cached_io_meta"] == "yes" || config["cached_io_meta"] == "1"; - cached_io_journal = cached_io_meta && (journal_device == meta_device || journal_device == "") && - config.find("cached_io_journal") == config.end() || - config["cached_io_journal"] == "true" || config["cached_io_journal"] == "yes" || config["cached_io_journal"] == "1"; + if (config.find("data_io") == config.end() && + config.find("meta_io") == config.end() && + config.find("journal_io") == config.end()) + { + bool cached_io_data = config["cached_io_data"] == "true" || config["cached_io_data"] == "yes" || config["cached_io_data"] == "1"; + bool cached_io_meta = cached_io_data && (meta_device == data_device || meta_device == "") && + config.find("cached_io_meta") == config.end() || + config["cached_io_meta"] == "true" || config["cached_io_meta"] == "yes" || config["cached_io_meta"] == "1"; + bool cached_io_journal = cached_io_meta && (journal_device == meta_device || journal_device == "") && + config.find("cached_io_journal") == config.end() || + config["cached_io_journal"] == "true" || config["cached_io_journal"] == "yes" || config["cached_io_journal"] == "1"; + data_io = cached_io_data ? "cached" : "direct"; + meta_io = cached_io_meta ? "cached" : "direct"; + journal_io = cached_io_journal ? "cached" : "direct"; + } + else + { + data_io = config.find("data_io") != config.end() ? config["data_io"] : "direct"; + meta_io = config.find("meta_io") != config.end() + ? config["meta_io"] + : (meta_device == data_device || meta_device == "" ? data_io : "direct"); + journal_io = config.find("journal_io") != config.end() + ? config["journal_io"] + : (journal_device == meta_device || journal_device == "" ? meta_io : "direct"); + } if (config["data_csum_type"] == "crc32c") { data_csum_type = BLOCKSTORE_CSUM_CRC32C; @@ -272,9 +290,19 @@ static void check_size(int fd, uint64_t *size, uint64_t *sectsize, std::string n } } +static int bs_openmode(const std::string & mode) +{ + if (mode == "directsync") + return O_DIRECT|O_SYNC; + else if (mode == "cached") + return O_SYNC; + else + return O_DIRECT; +} + void blockstore_disk_t::open_data() { - data_fd = open(data_device.c_str(), (cached_io_data ? O_SYNC : O_DIRECT) | O_RDWR); + data_fd = open(data_device.c_str(), bs_openmode(data_io) | O_RDWR); if (data_fd == -1) { throw std::runtime_error("Failed to open data device "+data_device+": "+std::string(strerror(errno))); @@ -299,9 +327,9 @@ void blockstore_disk_t::open_data() void blockstore_disk_t::open_meta() { - if (meta_device != data_device || cached_io_meta != cached_io_data) + if (meta_device != data_device || meta_io != data_io) { - meta_fd = open(meta_device.c_str(), (cached_io_meta ? O_SYNC : O_DIRECT) | O_RDWR); + meta_fd = open(meta_device.c_str(), bs_openmode(meta_io) | O_RDWR); if (meta_fd == -1) { throw std::runtime_error("Failed to open metadata device "+meta_device+": "+std::string(strerror(errno))); @@ -337,9 +365,9 @@ void blockstore_disk_t::open_meta() void blockstore_disk_t::open_journal() { - if (journal_device != meta_device || cached_io_journal != cached_io_meta) + if (journal_device != meta_device || journal_io != meta_io) { - journal_fd = open(journal_device.c_str(), (cached_io_journal ? O_SYNC : O_DIRECT) | O_RDWR); + journal_fd = open(journal_device.c_str(), bs_openmode(journal_io) | O_RDWR); if (journal_fd == -1) { throw std::runtime_error("Failed to open journal device "+journal_device+": "+std::string(strerror(errno))); diff --git a/src/blockstore_disk.h b/src/blockstore_disk.h index 58bfb7cf..c4311c6c 100644 --- a/src/blockstore_disk.h +++ b/src/blockstore_disk.h @@ -31,8 +31,9 @@ struct blockstore_disk_t uint32_t csum_block_size = 4096; // By default, Blockstore locks all opened devices exclusively. This option can be used to disable locking bool disable_flock = false; - // Use Linux page cache for reads and writes, i.e. open FDs with O_SYNC instead of O_DIRECT - bool cached_io_data = false, cached_io_meta = false, cached_io_journal = false; + // I/O modes for data, metadata and journal: direct or "" = O_DIRECT, cached = O_SYNC, directsync = O_DIRECT|O_SYNC + // O_SYNC without O_DIRECT = use Linux page cache for reads and writes + std::string data_io, meta_io, journal_io; int meta_fd = -1, data_fd = -1, journal_fd = -1; uint64_t meta_offset, meta_device_sect, meta_device_size, meta_len, meta_format = 0; diff --git a/src/disk_tool.cpp b/src/disk_tool.cpp index 310e38ef..37dc6af7 100644 --- a/src/disk_tool.cpp +++ b/src/disk_tool.cpp @@ -74,7 +74,7 @@ static const char *help_text = " If it doesn't succeed it issues a warning in the system log.\n" " \n" " You can also pass other OSD options here as arguments and they'll be persisted\n" - " in the superblock: cached_io_data, cached_io_meta, cached_io_journal,\n" + " in the superblock: data_io, meta_io, journal_io,\n" " inmemory_metadata, inmemory_journal, max_write_iodepth,\n" " min_flusher_count, max_flusher_count, journal_sector_buffer_count,\n" " journal_no_same_sector_overwrites, throttle_small_writes, throttle_target_iops,\n" diff --git a/src/disk_tool_prepare.cpp b/src/disk_tool_prepare.cpp index 610b9737..3fccb482 100644 --- a/src/disk_tool_prepare.cpp +++ b/src/disk_tool_prepare.cpp @@ -8,9 +8,9 @@ int disk_tool_t::prepare_one(std::map options, int is_hdd) { static const char *allow_additional_params[] = { - "cached_io_data", - "cached_io_meta", - "cached_io_journal", + "data_io", + "meta_io", + "journal_io", "max_write_iodepth", "max_write_iodepth", "min_flusher_count", @@ -119,7 +119,7 @@ int disk_tool_t::prepare_one(std::map options, int is_ try { dsk.parse_config(options); - dsk.cached_io_data = dsk.cached_io_meta = dsk.cached_io_journal = false; + dsk.data_io = dsk.meta_io = dsk.journal_io = "direct"; dsk.open_data(); dsk.open_meta(); dsk.open_journal(); @@ -483,7 +483,7 @@ int disk_tool_t::get_meta_partition(std::vector & ssds, std { blockstore_disk_t dsk; dsk.parse_config(options); - dsk.cached_io_data = dsk.cached_io_meta = dsk.cached_io_journal = false; + dsk.data_io = dsk.meta_io = dsk.journal_io = "direct"; dsk.open_data(); dsk.open_meta(); dsk.open_journal(); diff --git a/src/disk_tool_resize.cpp b/src/disk_tool_resize.cpp index 9704026b..713a1a26 100644 --- a/src/disk_tool_resize.cpp +++ b/src/disk_tool_resize.cpp @@ -91,7 +91,7 @@ int disk_tool_t::resize_parse_params() try { dsk.parse_config(options); - dsk.cached_io_data = dsk.cached_io_meta = dsk.cached_io_journal = false; + dsk.data_io = dsk.meta_io = dsk.journal_io = "direct"; dsk.open_data(); dsk.open_meta(); dsk.open_journal();