aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfanquake <fanquake@gmail.com>2023-04-03 14:20:35 +0100
committerfanquake <fanquake@gmail.com>2023-04-03 14:41:22 +0100
commit369d4c03b7084de967576759545ba36a17fc18bb (patch)
treecb7bb80bbf2f3d56a0cc38deb93e4e0276b0d7f7
parent5150e280103dd41c8a438ce72359b0f25ff23a2f (diff)
parent00e9b97f37e0bdf4c647236838c10b68b7ad5be3 (diff)
downloadbitcoin-369d4c03b7084de967576759545ba36a17fc18bb.tar.xz
Merge bitcoin/bitcoin#27254: refactor: Extract util/fs from util/system
00e9b97f37e0bdf4c647236838c10b68b7ad5be3 refactor: Move fs.* to util/fs.* (TheCharlatan) 106b46d9d25b5228ef009fbbe6f9a7ae35090d15 Add missing fs.h includes (TheCharlatan) b202b3dd6393b415fa68e18dc49c9431dc6b58b2 Add missing cstddef include in assumptions.h (TheCharlatan) 18fb36367a28819bd5ab402344802796a1248979 refactor: Extract util/fs_helpers from util/system (Ben Woosley) Pull request description: This pull request is part of the `libbitcoinkernel` project https://github.com/bitcoin/bitcoin/issues/24303 https://github.com/bitcoin/bitcoin/projects/18 and more specifically its "Step 2: Decouple most non-consensus code from libbitcoinkernel". This commit was originally authored by empact and is taken from its parent PR #25152. #### Context There is an ongoing effort to decouple the `ArgsManager` used for command line parsing user-provided arguments from the libbitcoinkernel library (https://github.com/bitcoin/bitcoin/pull/25290, https://github.com/bitcoin/bitcoin/pull/25487, https://github.com/bitcoin/bitcoin/pull/25527, https://github.com/bitcoin/bitcoin/pull/25862, https://github.com/bitcoin/bitcoin/pull/26177, and https://github.com/bitcoin/bitcoin/pull/27125). The `ArgsManager` is defined in `system.h`. A similar pull request extracting functionality from `system.h` has been merged in https://github.com/bitcoin/bitcoin/pull/27238. #### Changes Next to providing better code organization, this PR removes some reliance of the tree of libbitcoinkernel header includes on `system.h` (and thus the `ArgsManager` definition) by moving filesystem related functions out of the `system.*` files. There is already a pair of `fs.h` / `fs.cpp` in the top-level `src/` directory. They were not combined with the files introduced here, to keep the patch cleaner and more importantly because they are often included without the utility functions. The new files are therefore named `fs_helpers` and the existing `fs` files are moved into the util directory. Further commits splitting more functionality out of `system.h` are still in #25152 and will be submitted in separate PRs once this PR has been processed. ACKs for top commit: hebasto: ACK 00e9b97f37e0bdf4c647236838c10b68b7ad5be3 Tree-SHA512: 31422f148d14ba3c843b99b1550a6fd77c77f350905ca324f93d4f97b652246bc58fa9696c64d1201979cf88733e40be02d262739bb7d417cf22bf506fdb7666
-rw-r--r--src/Makefile.am9
-rw-r--r--src/addrdb.cpp3
-rw-r--r--src/addrdb.h2
-rw-r--r--src/banman.h2
-rw-r--r--src/bench/bench.cpp2
-rw-r--r--src/bench/bench.h2
-rw-r--r--src/bench/bench_bitcoin.cpp2
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/common/init.cpp4
-rw-r--r--src/compat/assumptions.h1
-rw-r--r--src/dbwrapper.cpp4
-rw-r--r--src/dbwrapper.h2
-rw-r--r--src/flatfile.cpp2
-rw-r--r--src/flatfile.h2
-rw-r--r--src/i2p.cpp2
-rw-r--r--src/i2p.h2
-rw-r--r--src/index/blockfilterindex.cpp1
-rw-r--r--src/init.cpp3
-rw-r--r--src/init/common.cpp3
-rw-r--r--src/interfaces/wallet.h2
-rw-r--r--src/ipc/interfaces.cpp2
-rw-r--r--src/ipc/process.cpp2
-rw-r--r--src/ipc/process.h2
-rw-r--r--src/kernel/mempool_persist.cpp4
-rw-r--r--src/kernel/mempool_persist.h2
-rw-r--r--src/logging.cpp2
-rw-r--r--src/logging.h2
-rw-r--r--src/net.cpp2
-rw-r--r--src/node/blockstorage.cpp2
-rw-r--r--src/node/blockstorage.h2
-rw-r--r--src/node/chainstate.cpp1
-rw-r--r--src/node/mempool_persist_args.cpp2
-rw-r--r--src/node/mempool_persist_args.h2
-rw-r--r--src/node/utxo_snapshot.cpp2
-rw-r--r--src/node/utxo_snapshot.h2
-rw-r--r--src/policy/fees.cpp2
-rw-r--r--src/policy/fees.h2
-rw-r--r--src/policy/fees_args.h2
-rw-r--r--src/qt/guiutil.cpp3
-rw-r--r--src/qt/guiutil.h2
-rw-r--r--src/qt/intro.cpp3
-rw-r--r--src/qt/psbtoperationsdialog.cpp2
-rw-r--r--src/qt/walletframe.cpp4
-rw-r--r--src/rpc/blockchain.cpp2
-rw-r--r--src/rpc/blockchain.h2
-rw-r--r--src/rpc/mempool.cpp2
-rw-r--r--src/rpc/request.cpp5
-rw-r--r--src/test/argsman_tests.cpp6
-rw-r--r--src/test/fs_tests.cpp4
-rw-r--r--src/test/fuzz/banman.cpp2
-rw-r--r--src/test/fuzz/fuzz.cpp2
-rw-r--r--src/test/fuzz/utxo_snapshot.cpp2
-rw-r--r--src/test/script_tests.cpp2
-rw-r--r--src/test/settings_tests.cpp2
-rw-r--r--src/test/streams_tests.cpp2
-rw-r--r--src/test/util/chainstate.h2
-rw-r--r--src/test/util/setup_common.h2
-rw-r--r--src/test/util_tests.cpp7
-rw-r--r--src/torcontrol.h2
-rw-r--r--src/txdb.h2
-rw-r--r--src/util/asmap.cpp2
-rw-r--r--src/util/asmap.h2
-rw-r--r--src/util/fs.cpp (renamed from src/fs.cpp)2
-rw-r--r--src/util/fs.h (renamed from src/fs.h)6
-rw-r--r--src/util/fs_helpers.cpp295
-rw-r--r--src/util/fs_helpers.h63
-rw-r--r--src/util/getuniquepath.cpp2
-rw-r--r--src/util/getuniquepath.h2
-rw-r--r--src/util/readwritefile.cpp2
-rw-r--r--src/util/readwritefile.h2
-rw-r--r--src/util/settings.cpp2
-rw-r--r--src/util/settings.h2
-rw-r--r--src/util/system.cpp264
-rw-r--r--src/util/system.h50
-rw-r--r--src/validation.cpp3
-rw-r--r--src/validation.h2
-rw-r--r--src/wallet/bdb.cpp3
-rw-r--r--src/wallet/bdb.h2
-rw-r--r--src/wallet/db.cpp2
-rw-r--r--src/wallet/db.h2
-rw-r--r--src/wallet/dump.cpp2
-rw-r--r--src/wallet/dump.h2
-rw-r--r--src/wallet/load.cpp2
-rw-r--r--src/wallet/rpc/backup.cpp2
-rw-r--r--src/wallet/salvage.cpp2
-rw-r--r--src/wallet/salvage.h2
-rw-r--r--src/wallet/sqlite.cpp2
-rw-r--r--src/wallet/test/db_tests.cpp2
-rw-r--r--src/wallet/test/init_test_fixture.cpp2
-rw-r--r--src/wallet/wallet.cpp5
-rw-r--r--src/wallet/wallet.h2
-rw-r--r--src/wallet/walletdb.cpp2
-rw-r--r--src/wallet/wallettool.cpp2
-rw-r--r--src/wallet/walletutil.h2
94 files changed, 480 insertions, 412 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 53c809c901..444480f824 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -154,7 +154,6 @@ BITCOIN_CORE_H = \
deploymentstatus.h \
external_signer.h \
flatfile.h \
- fs.h \
headerssync.h \
httprpc.h \
httpserver.h \
@@ -285,6 +284,8 @@ BITCOIN_CORE_H = \
util/exception.h \
util/fastrange.h \
util/fees.h \
+ util/fs.h \
+ util/fs_helpers.h \
util/getuniquepath.h \
util/golombrice.h \
util/hash_type.h \
@@ -694,7 +695,6 @@ libbitcoin_util_a_SOURCES = \
support/lockedpool.cpp \
chainparamsbase.cpp \
clientversion.cpp \
- fs.cpp \
logging.cpp \
random.cpp \
randomenv.cpp \
@@ -707,6 +707,8 @@ libbitcoin_util_a_SOURCES = \
util/error.cpp \
util/exception.cpp \
util/fees.cpp \
+ util/fs.cpp \
+ util/fs_helpers.cpp \
util/getuniquepath.cpp \
util/hasher.cpp \
util/sock.cpp \
@@ -908,7 +910,6 @@ libbitcoinkernel_la_SOURCES = \
deploymentinfo.cpp \
deploymentstatus.cpp \
flatfile.cpp \
- fs.cpp \
hash.cpp \
kernel/chain.cpp \
kernel/checks.cpp \
@@ -951,6 +952,8 @@ libbitcoinkernel_la_SOURCES = \
uint256.cpp \
util/check.cpp \
util/exception.cpp \
+ util/fs.cpp \
+ util/fs_helpers.cpp \
util/getuniquepath.cpp \
util/hasher.cpp \
util/moneystr.cpp \
diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index 9ae8244d1c..8ecccd4d22 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -9,7 +9,6 @@
#include <chainparams.h>
#include <clientversion.h>
#include <cstdint>
-#include <fs.h>
#include <hash.h>
#include <logging.h>
#include <logging/timer.h>
@@ -19,6 +18,8 @@
#include <streams.h>
#include <tinyformat.h>
#include <univalue.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/settings.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/addrdb.h b/src/addrdb.h
index 627ef3ac3c..08d86d0f01 100644
--- a/src/addrdb.h
+++ b/src/addrdb.h
@@ -6,9 +6,9 @@
#ifndef BITCOIN_ADDRDB_H
#define BITCOIN_ADDRDB_H
-#include <fs.h>
#include <net_types.h> // For banmap_t
#include <univalue.h>
+#include <util/fs.h>
#include <optional>
#include <vector>
diff --git a/src/banman.h b/src/banman.h
index 241f01dd2e..5a5f5677b0 100644
--- a/src/banman.h
+++ b/src/banman.h
@@ -7,9 +7,9 @@
#include <addrdb.h>
#include <common/bloom.h>
-#include <fs.h>
#include <net_types.h> // For banmap_t
#include <sync.h>
+#include <util/fs.h>
#include <chrono>
#include <cstdint>
diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp
index 4374a63250..84b66bc4b2 100644
--- a/src/bench/bench.cpp
+++ b/src/bench/bench.cpp
@@ -4,8 +4,8 @@
#include <bench/bench.h>
-#include <fs.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <util/string.h>
#include <chrono>
diff --git a/src/bench/bench.h b/src/bench/bench.h
index 22c63a797b..78196134e7 100644
--- a/src/bench/bench.h
+++ b/src/bench/bench.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_BENCH_BENCH_H
#define BITCOIN_BENCH_BENCH_H
-#include <fs.h>
+#include <util/fs.h>
#include <util/macros.h>
#include <chrono>
diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp
index 06e32f684f..7faaa1fb14 100644
--- a/src/bench/bench_bitcoin.cpp
+++ b/src/bench/bench_bitcoin.cpp
@@ -6,7 +6,7 @@
#include <clientversion.h>
#include <crypto/sha256.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index f36b6054bb..a05443a2e5 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -12,7 +12,6 @@
#include <consensus/amount.h>
#include <consensus/consensus.h>
#include <core_io.h>
-#include <fs.h>
#include <key_io.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
@@ -21,6 +20,7 @@
#include <script/signingprovider.h>
#include <univalue.h>
#include <util/exception.h>
+#include <util/fs.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/strencodings.h>
diff --git a/src/common/init.cpp b/src/common/init.cpp
index 159eb7e2ef..e8fa7a14fd 100644
--- a/src/common/init.cpp
+++ b/src/common/init.cpp
@@ -2,10 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <common/init.h>
#include <chainparams.h>
-#include <fs.h>
+#include <common/init.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/compat/assumptions.h b/src/compat/assumptions.h
index 92615b582a..4488db0886 100644
--- a/src/compat/assumptions.h
+++ b/src/compat/assumptions.h
@@ -8,6 +8,7 @@
#ifndef BITCOIN_COMPAT_ASSUMPTIONS_H
#define BITCOIN_COMPAT_ASSUMPTIONS_H
+#include <cstddef>
#include <limits>
// Assumption: We assume that the macro NDEBUG is not defined.
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index 0c6debfa80..2aade14ef4 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -4,12 +4,12 @@
#include <dbwrapper.h>
-#include <fs.h>
#include <logging.h>
#include <random.h>
#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <algorithm>
#include <cassert>
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index 578d9880ac..35782edca6 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -6,11 +6,11 @@
#define BITCOIN_DBWRAPPER_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <serialize.h>
#include <span.h>
#include <streams.h>
+#include <util/fs.h>
#include <cstddef>
#include <cstdint>
diff --git a/src/flatfile.cpp b/src/flatfile.cpp
index d6e84d02c1..59861a08ad 100644
--- a/src/flatfile.cpp
+++ b/src/flatfile.cpp
@@ -8,7 +8,7 @@
#include <flatfile.h>
#include <logging.h>
#include <tinyformat.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
FlatFileSeq::FlatFileSeq(fs::path dir, const char* prefix, size_t chunk_size) :
m_dir(std::move(dir)),
diff --git a/src/flatfile.h b/src/flatfile.h
index e4be9a9cb1..26b466db71 100644
--- a/src/flatfile.h
+++ b/src/flatfile.h
@@ -8,8 +8,8 @@
#include <string>
-#include <fs.h>
#include <serialize.h>
+#include <util/fs.h>
struct FlatFilePos
{
diff --git a/src/i2p.cpp b/src/i2p.cpp
index a3bfc23a65..76fbb89536 100644
--- a/src/i2p.cpp
+++ b/src/i2p.cpp
@@ -6,13 +6,13 @@
#include <compat/compat.h>
#include <compat/endian.h>
#include <crypto/sha256.h>
-#include <fs.h>
#include <i2p.h>
#include <logging.h>
#include <netaddress.h>
#include <netbase.h>
#include <random.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/readwritefile.h>
#include <util/sock.h>
#include <util/spanparsing.h>
diff --git a/src/i2p.h b/src/i2p.h
index 6e7bafc945..c9c99292d9 100644
--- a/src/i2p.h
+++ b/src/i2p.h
@@ -6,9 +6,9 @@
#define BITCOIN_I2P_H
#include <compat/compat.h>
-#include <fs.h>
#include <netaddress.h>
#include <sync.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/threadinterrupt.h>
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 59bf6d34cf..43c2215338 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -8,6 +8,7 @@
#include <hash.h>
#include <index/blockfilterindex.h>
#include <node/blockstorage.h>
+#include <util/fs_helpers.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/init.cpp b/src/init.cpp
index 16909f7e47..1122496539 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -20,7 +20,6 @@
#include <chainparams.h>
#include <consensus/amount.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <hash.h>
#include <httprpc.h>
#include <httpserver.h>
@@ -70,6 +69,8 @@
#include <txmempool.h>
#include <util/asmap.h>
#include <util/check.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
diff --git a/src/init/common.cpp b/src/init/common.cpp
index a7829c5d99..33a5cec3f1 100644
--- a/src/init/common.cpp
+++ b/src/init/common.cpp
@@ -7,10 +7,11 @@
#endif
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <node/interface_ui.h>
#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/string.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index 86707b20b1..b37763e686 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -6,11 +6,11 @@
#define BITCOIN_INTERFACES_WALLET_H
#include <consensus/amount.h>
-#include <fs.h>
#include <interfaces/chain.h> // For ChainClient
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString
+#include <util/fs.h>
#include <util/message.h>
#include <util/result.h>
#include <util/ui_change_type.h>
diff --git a/src/ipc/interfaces.cpp b/src/ipc/interfaces.cpp
index 396f3ddf25..d804d9d291 100644
--- a/src/ipc/interfaces.cpp
+++ b/src/ipc/interfaces.cpp
@@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <interfaces/init.h>
#include <interfaces/ipc.h>
#include <ipc/capnp/protocol.h>
@@ -10,6 +9,7 @@
#include <ipc/protocol.h>
#include <logging.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/system.h>
#include <cstdio>
diff --git a/src/ipc/process.cpp b/src/ipc/process.cpp
index 4dc88ae44b..9657dcd092 100644
--- a/src/ipc/process.cpp
+++ b/src/ipc/process.cpp
@@ -2,11 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <ipc/process.h>
#include <ipc/protocol.h>
#include <mp/util.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <cstdint>
diff --git a/src/ipc/process.h b/src/ipc/process.h
index 4bb2930d9c..40f2d2acf6 100644
--- a/src/ipc/process.h
+++ b/src/ipc/process.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_IPC_PROCESS_H
#define BITCOIN_IPC_PROCESS_H
+#include <util/fs.h>
+
#include <memory>
#include <string>
diff --git a/src/kernel/mempool_persist.cpp b/src/kernel/mempool_persist.cpp
index a14b2e6163..71f3aac366 100644
--- a/src/kernel/mempool_persist.cpp
+++ b/src/kernel/mempool_persist.cpp
@@ -6,7 +6,6 @@
#include <clientversion.h>
#include <consensus/amount.h>
-#include <fs.h>
#include <logging.h>
#include <primitives/transaction.h>
#include <serialize.h>
@@ -15,7 +14,8 @@
#include <sync.h>
#include <txmempool.h>
#include <uint256.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/time.h>
#include <validation.h>
diff --git a/src/kernel/mempool_persist.h b/src/kernel/mempool_persist.h
index ca4917e38b..cb09119e4a 100644
--- a/src/kernel/mempool_persist.h
+++ b/src/kernel/mempool_persist.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_KERNEL_MEMPOOL_PERSIST_H
#define BITCOIN_KERNEL_MEMPOOL_PERSIST_H
-#include <fs.h>
+#include <util/fs.h>
class Chainstate;
class CTxMemPool;
diff --git a/src/logging.cpp b/src/logging.cpp
index a9b2a2b33a..6a7991255d 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <logging.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/threadnames.h>
#include <util/time.h>
diff --git a/src/logging.h b/src/logging.h
index 954731d214..e7c554e79f 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -6,9 +6,9 @@
#ifndef BITCOIN_LOGGING_H
#define BITCOIN_LOGGING_H
-#include <fs.h>
#include <threadsafety.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/string.h>
#include <atomic>
diff --git a/src/net.cpp b/src/net.cpp
index 7023cb0f49..4f4c0a4079 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -16,7 +16,6 @@
#include <compat/compat.h>
#include <consensus/consensus.h>
#include <crypto/sha256.h>
-#include <fs.h>
#include <i2p.h>
#include <logging.h>
#include <net_permissions.h>
@@ -27,6 +26,7 @@
#include <protocol.h>
#include <random.h>
#include <scheduler.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/strencodings.h>
#include <util/syscall_sandbox.h>
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 53721b807c..af84e6d7e7 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -8,7 +8,6 @@
#include <clientversion.h>
#include <consensus/validation.h>
#include <flatfile.h>
-#include <fs.h>
#include <hash.h>
#include <logging.h>
#include <kernel/chainparams.h>
@@ -18,6 +17,7 @@
#include <signet.h>
#include <streams.h>
#include <undo.h>
+#include <util/fs.h>
#include <util/syscall_sandbox.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
index 5ba0045b8b..3eb27cc72d 100644
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -7,12 +7,12 @@
#include <attributes.h>
#include <chain.h>
-#include <fs.h>
#include <kernel/blockmanager_opts.h>
#include <kernel/cs_main.h>
#include <protocol.h>
#include <sync.h>
#include <txdb.h>
+#include <util/fs.h>
#include <atomic>
#include <cstdint>
diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp
index cfd3472592..f60ff83a0d 100644
--- a/src/node/chainstate.cpp
+++ b/src/node/chainstate.cpp
@@ -16,6 +16,7 @@
#include <tinyformat.h>
#include <txdb.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/time.h>
#include <util/translation.h>
#include <validation.h>
diff --git a/src/node/mempool_persist_args.cpp b/src/node/mempool_persist_args.cpp
index 4e775869c6..78e3472644 100644
--- a/src/node/mempool_persist_args.cpp
+++ b/src/node/mempool_persist_args.cpp
@@ -4,7 +4,7 @@
#include <node/mempool_persist_args.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/node/mempool_persist_args.h b/src/node/mempool_persist_args.h
index f719ec62ab..3b101f0930 100644
--- a/src/node/mempool_persist_args.h
+++ b/src/node/mempool_persist_args.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_NODE_MEMPOOL_PERSIST_ARGS_H
#define BITCOIN_NODE_MEMPOOL_PERSIST_ARGS_H
-#include <fs.h>
+#include <util/fs.h>
class ArgsManager;
diff --git a/src/node/utxo_snapshot.cpp b/src/node/utxo_snapshot.cpp
index cccf95e552..591c1dad6e 100644
--- a/src/node/utxo_snapshot.cpp
+++ b/src/node/utxo_snapshot.cpp
@@ -4,13 +4,13 @@
#include <node/utxo_snapshot.h>
-#include <fs.h>
#include <logging.h>
#include <streams.h>
#include <sync.h>
#include <tinyformat.h>
#include <txdb.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/node/utxo_snapshot.h b/src/node/utxo_snapshot.h
index c5c018c9e8..44ddd77dc3 100644
--- a/src/node/utxo_snapshot.h
+++ b/src/node/utxo_snapshot.h
@@ -6,11 +6,11 @@
#ifndef BITCOIN_NODE_UTXO_SNAPSHOT_H
#define BITCOIN_NODE_UTXO_SNAPSHOT_H
-#include <fs.h>
#include <kernel/cs_main.h>
#include <serialize.h>
#include <sync.h>
#include <uint256.h>
+#include <util/fs.h>
#include <cstdint>
#include <optional>
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index d244de1bb2..6121224979 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -7,7 +7,6 @@
#include <clientversion.h>
#include <consensus/amount.h>
-#include <fs.h>
#include <kernel/mempool_entry.h>
#include <logging.h>
#include <policy/feerate.h>
@@ -18,6 +17,7 @@
#include <sync.h>
#include <tinyformat.h>
#include <uint256.h>
+#include <util/fs.h>
#include <util/serfloat.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/policy/fees.h b/src/policy/fees.h
index 1c24b8c7c3..775a72a764 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -6,12 +6,12 @@
#define BITCOIN_POLICY_FEES_H
#include <consensus/amount.h>
-#include <fs.h>
#include <policy/feerate.h>
#include <random.h>
#include <sync.h>
#include <threadsafety.h>
#include <uint256.h>
+#include <util/fs.h>
#include <array>
#include <map>
diff --git a/src/policy/fees_args.h b/src/policy/fees_args.h
index 6b65ce0aa9..ef5cf144af 100644
--- a/src/policy/fees_args.h
+++ b/src/policy/fees_args.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_POLICY_FEES_ARGS_H
#define BITCOIN_POLICY_FEES_ARGS_H
-#include <fs.h>
+#include <util/fs.h>
class ArgsManager;
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 96fe091b60..e98d953fd2 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -12,7 +12,6 @@
#include <base58.h>
#include <chainparams.h>
-#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <policy/policy.h>
@@ -21,6 +20,8 @@
#include <script/script.h>
#include <script/standard.h>
#include <util/exception.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/system.h>
#include <util/time.h>
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 87a323bde9..7f06fdfe37 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -6,10 +6,10 @@
#define BITCOIN_QT_GUIUTIL_H
#include <consensus/amount.h>
-#include <fs.h>
#include <net.h>
#include <netaddress.h>
#include <util/check.h>
+#include <util/fs.h>
#include <QApplication>
#include <QEvent>
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 64c2890fc1..6423e457aa 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -7,15 +7,16 @@
#endif
#include <chainparams.h>
-#include <fs.h>
#include <qt/intro.h>
#include <qt/forms/ui_intro.h>
+#include <util/fs.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <interfaces/node.h>
+#include <util/fs_helpers.h>
#include <util/system.h>
#include <validation.h>
diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp
index 0994e0080a..fe52e11157 100644
--- a/src/qt/psbtoperationsdialog.cpp
+++ b/src/qt/psbtoperationsdialog.cpp
@@ -5,7 +5,6 @@
#include <qt/psbtoperationsdialog.h>
#include <core_io.h>
-#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <node/psbt.h>
@@ -14,6 +13,7 @@
#include <qt/forms/ui_psbtoperationsdialog.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <fstream>
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 43411370a2..7a8a053900 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -4,7 +4,6 @@
#include <qt/walletframe.h>
-#include <fs.h>
#include <node/interface_ui.h>
#include <psbt.h>
#include <qt/guiutil.h>
@@ -12,7 +11,8 @@
#include <qt/psbtoperationsdialog.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <cassert>
#include <fstream>
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 1a9b265fbe..fb22321d90 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -15,7 +15,6 @@
#include <core_io.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
@@ -39,6 +38,7 @@
#include <undo.h>
#include <univalue.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index 9ccb87b78a..0a86085db0 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -7,9 +7,9 @@
#include <consensus/amount.h>
#include <core_io.h>
-#include <fs.h>
#include <streams.h>
#include <sync.h>
+#include <util/fs.h>
#include <validation.h>
#include <any>
diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp
index 3a69e2d8a2..927b4ce1fc 100644
--- a/src/rpc/mempool.cpp
+++ b/src/rpc/mempool.cpp
@@ -9,7 +9,6 @@
#include <chainparams.h>
#include <core_io.h>
-#include <fs.h>
#include <kernel/mempool_entry.h>
#include <node/mempool_persist_args.h>
#include <policy/rbf.h>
@@ -21,6 +20,7 @@
#include <script/standard.h>
#include <txmempool.h>
#include <univalue.h>
+#include <util/fs.h>
#include <util/moneystr.h>
#include <util/time.h>
diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
index b6ef1909c9..4c5ccbbdad 100644
--- a/src/rpc/request.cpp
+++ b/src/rpc/request.cpp
@@ -5,12 +5,13 @@
#include <rpc/request.h>
-#include <fs.h>
+#include <util/fs.h>
#include <random.h>
#include <rpc/protocol.h>
-#include <util/system.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
+#include <util/system.h>
#include <fstream>
#include <stdexcept>
diff --git a/src/test/argsman_tests.cpp b/src/test/argsman_tests.cpp
index d00876bc70..5bade94f37 100644
--- a/src/test/argsman_tests.cpp
+++ b/src/test/argsman_tests.cpp
@@ -2,14 +2,14 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
-#include <fs.h>
#include <sync.h>
#include <test/util/logging.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
-#include <util/strencodings.h>
#include <univalue.h>
+#include <util/fs.h>
+#include <util/strencodings.h>
+#include <util/system.h>
#include <array>
#include <optional>
diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
index 7e7d630daa..7cfecb2b22 100644
--- a/src/test/fs_tests.cpp
+++ b/src/test/fs_tests.cpp
@@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
-#include <fs.h>
#include <test/util/setup_common.h>
-#include <util/system.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
index 273dcfd850..b4a93499ed 100644
--- a/src/test/fuzz/banman.cpp
+++ b/src/test/fuzz/banman.cpp
@@ -3,13 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <banman.h>
-#include <fs.h>
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <util/readwritefile.h>
#include <util/system.h>
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 9683f32d84..0bbfb206d5 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -4,11 +4,11 @@
#include <test/fuzz/fuzz.h>
-#include <fs.h>
#include <netaddress.h>
#include <netbase.h>
#include <test/util/setup_common.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/sock.h>
#include <util/time.h>
diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp
index 7119643b45..be34906025 100644
--- a/src/test/fuzz/utxo_snapshot.cpp
+++ b/src/test/fuzz/utxo_snapshot.cpp
@@ -4,13 +4,13 @@
#include <chainparams.h>
#include <consensus/validation.h>
-#include <fs.h>
#include <node/utxo_snapshot.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 45d9f2cf29..d8898743b0 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -6,7 +6,6 @@
#include <test/data/bip341_wallet_vectors.json.h>
#include <core_io.h>
-#include <fs.h>
#include <key.h>
#include <rpc/util.h>
#include <script/script.h>
@@ -19,6 +18,7 @@
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/transaction_utils.h>
+#include <util/fs.h>
#include <util/strencodings.h>
#include <util/system.h>
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index ad12c46561..4d0d42ae38 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -4,9 +4,9 @@
#include <util/settings.h>
-#include <fs.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
+#include <util/fs.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index a9b5251ad3..a0392570f1 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -2,10 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <streams.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <boost/test/unit_test.hpp>
diff --git a/src/test/util/chainstate.h b/src/test/util/chainstate.h
index e664435e03..bf8f8b5819 100644
--- a/src/test/util/chainstate.h
+++ b/src/test/util/chainstate.h
@@ -6,12 +6,12 @@
#define BITCOIN_TEST_UTIL_CHAINSTATE_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <node/context.h>
#include <node/utxo_snapshot.h>
#include <rpc/blockchain.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <univalue.h>
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 8874db7e75..948ebc097c 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -6,7 +6,6 @@
#define BITCOIN_TEST_UTIL_SETUP_COMMON_H
#include <chainparamsbase.h>
-#include <fs.h>
#include <key.h>
#include <node/caches.h>
#include <node/context.h>
@@ -15,6 +14,7 @@
#include <random.h>
#include <stdexcept>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/system.h>
#include <util/vector.h>
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index a13552653e..3a5126f8a8 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -2,16 +2,16 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/system.h>
-
#include <clientversion.h>
-#include <fs.h>
#include <hash.h> // For Hash()
#include <key.h> // For CKey
#include <sync.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <uint256.h>
+#include <util/bitdeque.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC
#include <util/moneystr.h>
@@ -22,7 +22,6 @@
#include <util/string.h>
#include <util/time.h>
#include <util/vector.h>
-#include <util/bitdeque.h>
#include <array>
#include <cmath>
diff --git a/src/torcontrol.h b/src/torcontrol.h
index 6563a2ef42..afc5413db0 100644
--- a/src/torcontrol.h
+++ b/src/torcontrol.h
@@ -8,8 +8,8 @@
#ifndef BITCOIN_TORCONTROL_H
#define BITCOIN_TORCONTROL_H
-#include <fs.h>
#include <netaddress.h>
+#include <util/fs.h>
#include <boost/signals2/signal.hpp>
diff --git a/src/txdb.h b/src/txdb.h
index 8a876349fb..63c7152097 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -10,7 +10,7 @@
#include <dbwrapper.h>
#include <kernel/cs_main.h>
#include <sync.h>
-#include <fs.h>
+#include <util/fs.h>
#include <memory>
#include <optional>
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
index 4b548c5a4d..360573cbae 100644
--- a/src/util/asmap.cpp
+++ b/src/util/asmap.cpp
@@ -6,10 +6,10 @@
#include <clientversion.h>
#include <crypto/common.h>
-#include <fs.h>
#include <logging.h>
#include <serialize.h>
#include <streams.h>
+#include <util/fs.h>
#include <algorithm>
#include <cassert>
diff --git a/src/util/asmap.h b/src/util/asmap.h
index 844037f816..08a88f1b3c 100644
--- a/src/util/asmap.h
+++ b/src/util/asmap.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_ASMAP_H
#define BITCOIN_UTIL_ASMAP_H
-#include <fs.h>
+#include <util/fs.h>
#include <cstdint>
#include <vector>
diff --git a/src/fs.cpp b/src/util/fs.cpp
index 64411fe41f..e8fb72670f 100644
--- a/src/fs.cpp
+++ b/src/util/fs.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <util/fs.h>
#include <util/syserror.h>
#ifndef WIN32
diff --git a/src/fs.h b/src/util/fs.h
index 0ece256acb..886a30394e 100644
--- a/src/fs.h
+++ b/src/util/fs.h
@@ -2,8 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_FS_H
-#define BITCOIN_FS_H
+#ifndef BITCOIN_UTIL_FS_H
+#define BITCOIN_UTIL_FS_H
#include <tinyformat.h>
@@ -248,4 +248,4 @@ template<> inline void formatValue(std::ostream&, const char*, const char*, int,
template<> inline void formatValue(std::ostream&, const char*, const char*, int, const fs::path&) = delete;
} // namespace tinyformat
-#endif // BITCOIN_FS_H
+#endif // BITCOIN_UTIL_FS_H
diff --git a/src/util/fs_helpers.cpp b/src/util/fs_helpers.cpp
new file mode 100644
index 0000000000..d05cb8a63d
--- /dev/null
+++ b/src/util/fs_helpers.cpp
@@ -0,0 +1,295 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2023 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <util/fs_helpers.h>
+
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
+
+#include <logging.h>
+#include <sync.h>
+#include <tinyformat.h>
+#include <util/fs.h>
+#include <util/getuniquepath.h>
+
+#include <cerrno>
+#include <filesystem>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+
+#ifndef WIN32
+// for posix_fallocate, in configure.ac we check if it is present after this
+#ifdef __linux__
+
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#define _POSIX_C_SOURCE 200112L
+
+#endif // __linux__
+
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#else
+#include <io.h> /* For _get_osfhandle, _chsize */
+#include <shlobj.h> /* For SHGetSpecialFolderPathW */
+#endif // WIN32
+
+/** Mutex to protect dir_locks. */
+static GlobalMutex cs_dir_locks;
+/** A map that contains all the currently held directory locks. After
+ * successful locking, these will be held here until the global destructor
+ * cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
+ * is called.
+ */
+static std::map<std::string, std::unique_ptr<fsbridge::FileLock>> dir_locks GUARDED_BY(cs_dir_locks);
+
+bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only)
+{
+ LOCK(cs_dir_locks);
+ fs::path pathLockFile = directory / lockfile_name;
+
+ // If a lock for this directory already exists in the map, don't try to re-lock it
+ if (dir_locks.count(fs::PathToString(pathLockFile))) {
+ return true;
+ }
+
+ // Create empty lock file if it doesn't exist.
+ FILE* file = fsbridge::fopen(pathLockFile, "a");
+ if (file) fclose(file);
+ auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
+ if (!lock->TryLock()) {
+ return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason());
+ }
+ if (!probe_only) {
+ // Lock successful and we're not just probing, put it into the map
+ dir_locks.emplace(fs::PathToString(pathLockFile), std::move(lock));
+ }
+ return true;
+}
+
+void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name)
+{
+ LOCK(cs_dir_locks);
+ dir_locks.erase(fs::PathToString(directory / lockfile_name));
+}
+
+void ReleaseDirectoryLocks()
+{
+ LOCK(cs_dir_locks);
+ dir_locks.clear();
+}
+
+bool DirIsWritable(const fs::path& directory)
+{
+ fs::path tmpFile = GetUniquePath(directory);
+
+ FILE* file = fsbridge::fopen(tmpFile, "a");
+ if (!file) return false;
+
+ fclose(file);
+ remove(tmpFile);
+
+ return true;
+}
+
+bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
+{
+ constexpr uint64_t min_disk_space = 52428800; // 50 MiB
+
+ uint64_t free_bytes_available = fs::space(dir).available;
+ return free_bytes_available >= min_disk_space + additional_bytes;
+}
+
+std::streampos GetFileSize(const char* path, std::streamsize max)
+{
+ std::ifstream file{path, std::ios::binary};
+ file.ignore(max);
+ return file.gcount();
+}
+
+bool FileCommit(FILE* file)
+{
+ if (fflush(file) != 0) { // harmless if redundantly called
+ LogPrintf("%s: fflush failed: %d\n", __func__, errno);
+ return false;
+ }
+#ifdef WIN32
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ if (FlushFileBuffers(hFile) == 0) {
+ LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError());
+ return false;
+ }
+#elif defined(MAC_OSX) && defined(F_FULLFSYNC)
+ if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success
+ LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno);
+ return false;
+ }
+#elif HAVE_FDATASYNC
+ if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync
+ LogPrintf("%s: fdatasync failed: %d\n", __func__, errno);
+ return false;
+ }
+#else
+ if (fsync(fileno(file)) != 0 && errno != EINVAL) {
+ LogPrintf("%s: fsync failed: %d\n", __func__, errno);
+ return false;
+ }
+#endif
+ return true;
+}
+
+void DirectoryCommit(const fs::path& dirname)
+{
+#ifndef WIN32
+ FILE* file = fsbridge::fopen(dirname, "r");
+ if (file) {
+ fsync(fileno(file));
+ fclose(file);
+ }
+#endif
+}
+
+bool TruncateFile(FILE* file, unsigned int length)
+{
+#if defined(WIN32)
+ return _chsize(_fileno(file), length) == 0;
+#else
+ return ftruncate(fileno(file), length) == 0;
+#endif
+}
+
+/**
+ * this function tries to raise the file descriptor limit to the requested number.
+ * It returns the actual file descriptor limit (which may be more or less than nMinFD)
+ */
+int RaiseFileDescriptorLimit(int nMinFD)
+{
+#if defined(WIN32)
+ return 2048;
+#else
+ struct rlimit limitFD;
+ if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
+ if (limitFD.rlim_cur < (rlim_t)nMinFD) {
+ limitFD.rlim_cur = nMinFD;
+ if (limitFD.rlim_cur > limitFD.rlim_max)
+ limitFD.rlim_cur = limitFD.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &limitFD);
+ getrlimit(RLIMIT_NOFILE, &limitFD);
+ }
+ return limitFD.rlim_cur;
+ }
+ return nMinFD; // getrlimit failed, assume it's fine
+#endif
+}
+
+/**
+ * this function tries to make a particular range of a file allocated (corresponding to disk space)
+ * it is advisory, and the range specified in the arguments will never contain live data
+ */
+void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length)
+{
+#if defined(WIN32)
+ // Windows-specific version
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ LARGE_INTEGER nFileSize;
+ int64_t nEndPos = (int64_t)offset + length;
+ nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
+ nFileSize.u.HighPart = nEndPos >> 32;
+ SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
+ SetEndOfFile(hFile);
+#elif defined(MAC_OSX)
+ // OSX specific version
+ // NOTE: Contrary to other OS versions, the OSX version assumes that
+ // NOTE: offset is the size of the file.
+ fstore_t fst;
+ fst.fst_flags = F_ALLOCATECONTIG;
+ fst.fst_posmode = F_PEOFPOSMODE;
+ fst.fst_offset = 0;
+ fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
+ fst.fst_bytesalloc = 0;
+ if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
+ fst.fst_flags = F_ALLOCATEALL;
+ fcntl(fileno(file), F_PREALLOCATE, &fst);
+ }
+ ftruncate(fileno(file), static_cast<off_t>(offset) + length);
+#else
+#if defined(HAVE_POSIX_FALLOCATE)
+ // Version using posix_fallocate
+ off_t nEndPos = (off_t)offset + length;
+ if (0 == posix_fallocate(fileno(file), 0, nEndPos)) return;
+#endif
+ // Fallback version
+ // TODO: just write one byte per block
+ static const char buf[65536] = {};
+ if (fseek(file, offset, SEEK_SET)) {
+ return;
+ }
+ while (length > 0) {
+ unsigned int now = 65536;
+ if (length < now)
+ now = length;
+ fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
+ length -= now;
+ }
+#endif
+}
+
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
+{
+ WCHAR pszPath[MAX_PATH] = L"";
+
+ if (SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate)) {
+ return fs::path(pszPath);
+ }
+
+ LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
+ return fs::path("");
+}
+#endif
+
+bool RenameOver(fs::path src, fs::path dest)
+{
+#ifdef __MINGW64__
+ // This is a workaround for a bug in libstdc++ which
+ // implements std::filesystem::rename with _wrename function.
+ // This bug has been fixed in upstream:
+ // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
+ // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
+ // For more details see the commits mentioned above.
+ return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
+ MOVEFILE_REPLACE_EXISTING) != 0;
+#else
+ std::error_code error;
+ fs::rename(src, dest, error);
+ return !error;
+#endif
+}
+
+/**
+ * Ignores exceptions thrown by create_directories if the requested directory exists.
+ * Specifically handles case where path p exists, but it wasn't possible for the user to
+ * write to the parent directory.
+ */
+bool TryCreateDirectories(const fs::path& p)
+{
+ try {
+ return fs::create_directories(p);
+ } catch (const fs::filesystem_error&) {
+ if (!fs::exists(p) || !fs::is_directory(p))
+ throw;
+ }
+
+ // create_directories didn't create the directory, it had to have existed already
+ return false;
+}
diff --git a/src/util/fs_helpers.h b/src/util/fs_helpers.h
new file mode 100644
index 0000000000..e7db01a89b
--- /dev/null
+++ b/src/util/fs_helpers.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2023 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_FS_HELPERS_H
+#define BITCOIN_UTIL_FS_HELPERS_H
+
+#include <util/fs.h>
+
+#include <cstdint>
+#include <cstdio>
+#include <iosfwd>
+#include <limits>
+
+/**
+ * Ensure file contents are fully committed to disk, using a platform-specific
+ * feature analogous to fsync().
+ */
+bool FileCommit(FILE* file);
+
+/**
+ * Sync directory contents. This is required on some environments to ensure that
+ * newly created files are committed to disk.
+ */
+void DirectoryCommit(const fs::path& dirname);
+
+bool TruncateFile(FILE* file, unsigned int length);
+int RaiseFileDescriptorLimit(int nMinFD);
+void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
+
+/**
+ * Rename src to dest.
+ * @return true if the rename was successful.
+ */
+[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
+
+bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false);
+void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
+bool DirIsWritable(const fs::path& directory);
+bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
+
+/** Get the size of a file by scanning it.
+ *
+ * @param[in] path The file path
+ * @param[in] max Stop seeking beyond this limit
+ * @return The file size or max
+ */
+std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
+
+/** Release all directory locks. This is used for unit testing only, at runtime
+ * the global destructor will take care of the locks.
+ */
+void ReleaseDirectoryLocks();
+
+bool TryCreateDirectories(const fs::path& p);
+fs::path GetDefaultDataDir();
+
+#ifdef WIN32
+fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
+
+#endif // BITCOIN_UTIL_FS_HELPERS_H
diff --git a/src/util/getuniquepath.cpp b/src/util/getuniquepath.cpp
index 42c5dee0ed..105b4d52d2 100644
--- a/src/util/getuniquepath.cpp
+++ b/src/util/getuniquepath.cpp
@@ -3,7 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <random.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/strencodings.h>
fs::path GetUniquePath(const fs::path& base)
diff --git a/src/util/getuniquepath.h b/src/util/getuniquepath.h
index e0c6147876..1563652300 100644
--- a/src/util/getuniquepath.h
+++ b/src/util/getuniquepath.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_GETUNIQUEPATH_H
#define BITCOIN_UTIL_GETUNIQUEPATH_H
-#include <fs.h>
+#include <util/fs.h>
/**
* Helper function for getting a unique path
diff --git a/src/util/readwritefile.cpp b/src/util/readwritefile.cpp
index cc555adf45..773d7ad1cc 100644
--- a/src/util/readwritefile.cpp
+++ b/src/util/readwritefile.cpp
@@ -5,7 +5,7 @@
#include <util/readwritefile.h>
-#include <fs.h>
+#include <util/fs.h>
#include <algorithm>
#include <cstdio>
diff --git a/src/util/readwritefile.h b/src/util/readwritefile.h
index 73437baf1b..6ddfcb4f35 100644
--- a/src/util/readwritefile.h
+++ b/src/util/readwritefile.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_READWRITEFILE_H
#define BITCOIN_UTIL_READWRITEFILE_H
-#include <fs.h>
+#include <util/fs.h>
#include <limits>
#include <string>
diff --git a/src/util/settings.cpp b/src/util/settings.cpp
index a2e30098dc..bb257c0584 100644
--- a/src/util/settings.cpp
+++ b/src/util/settings.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
+#include <util/fs.h>
#include <util/settings.h>
#include <tinyformat.h>
diff --git a/src/util/settings.h b/src/util/settings.h
index b0d8acb711..27e87a4751 100644
--- a/src/util/settings.h
+++ b/src/util/settings.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_SETTINGS_H
#define BITCOIN_UTIL_SETTINGS_H
-#include <fs.h>
+#include <util/fs.h>
#include <map>
#include <string>
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 98e89f82e7..630eff99e0 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -6,9 +6,10 @@
#include <util/system.h>
#include <chainparamsbase.h>
-#include <fs.h>
#include <sync.h>
#include <util/check.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/getuniquepath.h>
#include <util/strencodings.h>
#include <util/string.h>
@@ -22,17 +23,6 @@
#endif
#ifndef WIN32
-// for posix_fallocate, in configure.ac we check if it is present after this
-#ifdef __linux__
-
-#ifdef _POSIX_C_SOURCE
-#undef _POSIX_C_SOURCE
-#endif
-
-#define _POSIX_C_SOURCE 200112L
-
-#endif // __linux__
-
#include <algorithm>
#include <cassert>
#include <fcntl.h>
@@ -44,7 +34,6 @@
#include <codecvt>
-#include <io.h> /* for _commit */
#include <shellapi.h>
#include <shlobj.h>
#endif
@@ -72,78 +61,6 @@ const char * const BITCOIN_SETTINGS_FILENAME = "settings.json";
ArgsManager gArgs;
-/** Mutex to protect dir_locks. */
-static GlobalMutex cs_dir_locks;
-/** A map that contains all the currently held directory locks. After
- * successful locking, these will be held here until the global destructor
- * cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
- * is called.
- */
-static std::map<std::string, std::unique_ptr<fsbridge::FileLock>> dir_locks GUARDED_BY(cs_dir_locks);
-
-bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only)
-{
- LOCK(cs_dir_locks);
- fs::path pathLockFile = directory / lockfile_name;
-
- // If a lock for this directory already exists in the map, don't try to re-lock it
- if (dir_locks.count(fs::PathToString(pathLockFile))) {
- return true;
- }
-
- // Create empty lock file if it doesn't exist.
- FILE* file = fsbridge::fopen(pathLockFile, "a");
- if (file) fclose(file);
- auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
- if (!lock->TryLock()) {
- return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason());
- }
- if (!probe_only) {
- // Lock successful and we're not just probing, put it into the map
- dir_locks.emplace(fs::PathToString(pathLockFile), std::move(lock));
- }
- return true;
-}
-
-void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name)
-{
- LOCK(cs_dir_locks);
- dir_locks.erase(fs::PathToString(directory / lockfile_name));
-}
-
-void ReleaseDirectoryLocks()
-{
- LOCK(cs_dir_locks);
- dir_locks.clear();
-}
-
-bool DirIsWritable(const fs::path& directory)
-{
- fs::path tmpFile = GetUniquePath(directory);
-
- FILE* file = fsbridge::fopen(tmpFile, "a");
- if (!file) return false;
-
- fclose(file);
- remove(tmpFile);
-
- return true;
-}
-
-bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
-{
- constexpr uint64_t min_disk_space = 52428800; // 50 MiB
-
- uint64_t free_bytes_available = fs::space(dir).available;
- return free_bytes_available >= min_disk_space + additional_bytes;
-}
-
-std::streampos GetFileSize(const char* path, std::streamsize max) {
- std::ifstream file{path, std::ios::binary};
- file.ignore(max);
- return file.gcount();
-}
-
/**
* Interpret a string argument as a boolean.
*
@@ -1091,182 +1008,6 @@ void ArgsManager::LogArgs() const
logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
}
-bool RenameOver(fs::path src, fs::path dest)
-{
-#ifdef __MINGW64__
- // This is a workaround for a bug in libstdc++ which
- // implements std::filesystem::rename with _wrename function.
- // This bug has been fixed in upstream:
- // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
- // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
- // For more details see the commits mentioned above.
- return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
- MOVEFILE_REPLACE_EXISTING) != 0;
-#else
- std::error_code error;
- fs::rename(src, dest, error);
- return !error;
-#endif
-}
-
-/**
- * Ignores exceptions thrown by create_directories if the requested directory exists.
- * Specifically handles case where path p exists, but it wasn't possible for the user to
- * write to the parent directory.
- */
-bool TryCreateDirectories(const fs::path& p)
-{
- try
- {
- return fs::create_directories(p);
- } catch (const fs::filesystem_error&) {
- if (!fs::exists(p) || !fs::is_directory(p))
- throw;
- }
-
- // create_directories didn't create the directory, it had to have existed already
- return false;
-}
-
-bool FileCommit(FILE *file)
-{
- if (fflush(file) != 0) { // harmless if redundantly called
- LogPrintf("%s: fflush failed: %d\n", __func__, errno);
- return false;
- }
-#ifdef WIN32
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
- if (FlushFileBuffers(hFile) == 0) {
- LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError());
- return false;
- }
-#elif defined(MAC_OSX) && defined(F_FULLFSYNC)
- if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success
- LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno);
- return false;
- }
-#elif HAVE_FDATASYNC
- if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync
- LogPrintf("%s: fdatasync failed: %d\n", __func__, errno);
- return false;
- }
-#else
- if (fsync(fileno(file)) != 0 && errno != EINVAL) {
- LogPrintf("%s: fsync failed: %d\n", __func__, errno);
- return false;
- }
-#endif
- return true;
-}
-
-void DirectoryCommit(const fs::path &dirname)
-{
-#ifndef WIN32
- FILE* file = fsbridge::fopen(dirname, "r");
- if (file) {
- fsync(fileno(file));
- fclose(file);
- }
-#endif
-}
-
-bool TruncateFile(FILE *file, unsigned int length) {
-#if defined(WIN32)
- return _chsize(_fileno(file), length) == 0;
-#else
- return ftruncate(fileno(file), length) == 0;
-#endif
-}
-
-/**
- * this function tries to raise the file descriptor limit to the requested number.
- * It returns the actual file descriptor limit (which may be more or less than nMinFD)
- */
-int RaiseFileDescriptorLimit(int nMinFD) {
-#if defined(WIN32)
- return 2048;
-#else
- struct rlimit limitFD;
- if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
- if (limitFD.rlim_cur < (rlim_t)nMinFD) {
- limitFD.rlim_cur = nMinFD;
- if (limitFD.rlim_cur > limitFD.rlim_max)
- limitFD.rlim_cur = limitFD.rlim_max;
- setrlimit(RLIMIT_NOFILE, &limitFD);
- getrlimit(RLIMIT_NOFILE, &limitFD);
- }
- return limitFD.rlim_cur;
- }
- return nMinFD; // getrlimit failed, assume it's fine
-#endif
-}
-
-/**
- * this function tries to make a particular range of a file allocated (corresponding to disk space)
- * it is advisory, and the range specified in the arguments will never contain live data
- */
-void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
-#if defined(WIN32)
- // Windows-specific version
- HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
- LARGE_INTEGER nFileSize;
- int64_t nEndPos = (int64_t)offset + length;
- nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
- nFileSize.u.HighPart = nEndPos >> 32;
- SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
- SetEndOfFile(hFile);
-#elif defined(MAC_OSX)
- // OSX specific version
- // NOTE: Contrary to other OS versions, the OSX version assumes that
- // NOTE: offset is the size of the file.
- fstore_t fst;
- fst.fst_flags = F_ALLOCATECONTIG;
- fst.fst_posmode = F_PEOFPOSMODE;
- fst.fst_offset = 0;
- fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
- fst.fst_bytesalloc = 0;
- if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
- fst.fst_flags = F_ALLOCATEALL;
- fcntl(fileno(file), F_PREALLOCATE, &fst);
- }
- ftruncate(fileno(file), static_cast<off_t>(offset) + length);
-#else
- #if defined(HAVE_POSIX_FALLOCATE)
- // Version using posix_fallocate
- off_t nEndPos = (off_t)offset + length;
- if (0 == posix_fallocate(fileno(file), 0, nEndPos)) return;
- #endif
- // Fallback version
- // TODO: just write one byte per block
- static const char buf[65536] = {};
- if (fseek(file, offset, SEEK_SET)) {
- return;
- }
- while (length > 0) {
- unsigned int now = 65536;
- if (length < now)
- now = length;
- fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
- length -= now;
- }
-#endif
-}
-
-#ifdef WIN32
-fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
-{
- WCHAR pszPath[MAX_PATH] = L"";
-
- if(SHGetSpecialFolderPathW(nullptr, pszPath, nFolder, fCreate))
- {
- return fs::path(pszPath);
- }
-
- LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
- return fs::path("");
-}
-#endif
-
#ifndef WIN32
std::string ShellEscape(const std::string& arg)
{
@@ -1290,7 +1031,6 @@ void runCommand(const std::string& strCommand)
}
#endif
-
void SetupEnvironment()
{
#ifdef HAVE_MALLOPT_ARENA_MAX
diff --git a/src/util/system.h b/src/util/system.h
index 7292262bea..ff3155b498 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -14,11 +14,11 @@
#include <config/bitcoin-config.h>
#endif
-#include <compat/compat.h>
#include <compat/assumptions.h>
-#include <fs.h>
+#include <compat/compat.h>
#include <logging.h>
#include <sync.h>
+#include <util/fs.h>
#include <util/settings.h>
#include <util/time.h>
@@ -42,55 +42,9 @@ extern const char * const BITCOIN_SETTINGS_FILENAME;
void SetupEnvironment();
bool SetupNetworking();
-
-/**
- * Ensure file contents are fully committed to disk, using a platform-specific
- * feature analogous to fsync().
- */
-bool FileCommit(FILE *file);
-
-/**
- * Sync directory contents. This is required on some environments to ensure that
- * newly created files are committed to disk.
- */
-void DirectoryCommit(const fs::path &dirname);
-
-bool TruncateFile(FILE *file, unsigned int length);
-int RaiseFileDescriptorLimit(int nMinFD);
-void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
-
-/**
- * Rename src to dest.
- * @return true if the rename was successful.
- */
-[[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
-
-bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only=false);
-void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
-bool DirIsWritable(const fs::path& directory);
-bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
-
-/** Get the size of a file by scanning it.
- *
- * @param[in] path The file path
- * @param[in] max Stop seeking beyond this limit
- * @return The file size or max
- */
-std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
-
-/** Release all directory locks. This is used for unit testing only, at runtime
- * the global destructor will take care of the locks.
- */
-void ReleaseDirectoryLocks();
-
-bool TryCreateDirectories(const fs::path& p);
-fs::path GetDefaultDataDir();
// Return true if -datadir option points to a valid directory or is not specified.
bool CheckDataDirOption(const ArgsManager& args);
fs::path GetConfigFile(const ArgsManager& args, const fs::path& configuration_file_path);
-#ifdef WIN32
-fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
-#endif
#ifndef WIN32
std::string ShellEscape(const std::string& arg);
#endif
diff --git a/src/validation.cpp b/src/validation.cpp
index e82fead89e..1fd8f0e326 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -19,7 +19,6 @@
#include <consensus/validation.h>
#include <cuckoocache.h>
#include <flatfile.h>
-#include <fs.h>
#include <hash.h>
#include <kernel/chainparams.h>
#include <kernel/mempool_entry.h>
@@ -46,6 +45,8 @@
#include <uint256.h>
#include <undo.h>
#include <util/check.h> // For NDEBUG compile time check
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/hasher.h>
#include <util/moneystr.h>
#include <util/rbf.h>
diff --git a/src/validation.h b/src/validation.h
index 0044004b79..fd0e2115f7 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -15,7 +15,6 @@
#include <chain.h>
#include <consensus/amount.h>
#include <deploymentstatus.h>
-#include <fs.h>
#include <kernel/chainparams.h>
#include <kernel/chainstatemanager_opts.h>
#include <kernel/cs_main.h> // IWYU pragma: export
@@ -30,6 +29,7 @@
#include <txmempool.h> // For CTxMemPool::cs
#include <uint256.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/hasher.h>
#include <util/translation.h>
#include <versionbits.h>
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 4d3285333f..5fafd478ee 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -4,11 +4,12 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <compat/compat.h>
-#include <fs.h>
+#include <util/fs.h>
#include <wallet/bdb.h>
#include <wallet/db.h>
#include <util/check.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
#include <util/translation.h>
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index 06c98972b0..fbec0bb90b 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -7,9 +7,9 @@
#define BITCOIN_WALLET_BDB_H
#include <clientversion.h>
-#include <fs.h>
#include <serialize.h>
#include <streams.h>
+#include <util/fs.h>
#include <util/system.h>
#include <wallet/db.h>
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 8e79ee678e..92e1d61ac4 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -4,8 +4,8 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
-#include <fs.h>
#include <logging.h>
+#include <util/fs.h>
#include <util/system.h>
#include <wallet/db.h>
diff --git a/src/wallet/db.h b/src/wallet/db.h
index d4c590fac7..2da94885be 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -7,9 +7,9 @@
#define BITCOIN_WALLET_DB_H
#include <clientversion.h>
-#include <fs.h>
#include <streams.h>
#include <support/allocators/secure.h>
+#include <util/fs.h>
#include <atomic>
#include <memory>
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 69208c19dc..31b6eb4ae1 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -4,7 +4,7 @@
#include <wallet/dump.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/translation.h>
#include <wallet/wallet.h>
diff --git a/src/wallet/dump.h b/src/wallet/dump.h
index ff0d94e4b2..5034f95479 100644
--- a/src/wallet/dump.h
+++ b/src/wallet/dump.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_WALLET_DUMP_H
#define BITCOIN_WALLET_DUMP_H
-#include <fs.h>
+#include <util/fs.h>
#include <string>
#include <vector>
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 8c60a2da72..2103fc64e4 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -5,10 +5,10 @@
#include <wallet/load.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <scheduler.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index 9b6b3d629c..f4ea66c833 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -5,7 +5,6 @@
#include <chain.h>
#include <clientversion.h>
#include <core_io.h>
-#include <fs.h>
#include <hash.h>
#include <interfaces/chain.h>
#include <key_io.h>
@@ -17,6 +16,7 @@
#include <sync.h>
#include <uint256.h>
#include <util/bip32.h>
+#include <util/fs.h>
#include <util/time.h>
#include <util/translation.h>
#include <wallet/rpc/util.h>
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index e2b4dbf4c2..06c8c8bb37 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <streams.h>
+#include <util/fs.h>
#include <util/translation.h>
#include <wallet/bdb.h>
#include <wallet/salvage.h>
diff --git a/src/wallet/salvage.h b/src/wallet/salvage.h
index ce918aec2d..fbf152ec79 100644
--- a/src/wallet/salvage.h
+++ b/src/wallet/salvage.h
@@ -6,8 +6,8 @@
#ifndef BITCOIN_WALLET_SALVAGE_H
#define BITCOIN_WALLET_SALVAGE_H
-#include <fs.h>
#include <streams.h>
+#include <util/fs.h>
class ArgsManager;
struct bilingual_str;
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 8d8a7ab2a2..d6259e095e 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -8,8 +8,8 @@
#include <crypto/common.h>
#include <logging.h>
#include <sync.h>
+#include <util/fs_helpers.h>
#include <util/strencodings.h>
-#include <util/system.h>
#include <util/translation.h>
#include <wallet/db.h>
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index 7e26656b86..7761308bbc 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -4,8 +4,8 @@
#include <boost/test/unit_test.hpp>
-#include <fs.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <wallet/bdb.h>
#include <fstream>
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
index 60b1bab8ac..1db2a06bf8 100644
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <fs.h>
#include <univalue.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/system.h>
#include <fstream>
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index ef8fb29e64..50405b78fe 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -11,7 +11,6 @@
#include <consensus/consensus.h>
#include <consensus/validation.h>
#include <external_signer.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <interfaces/wallet.h>
#include <key.h>
@@ -32,6 +31,8 @@
#include <util/check.h>
#include <util/error.h>
#include <util/fees.h>
+#include <util/fs.h>
+#include <util/fs_helpers.h>
#include <util/moneystr.h>
#include <util/rbf.h>
#include <util/string.h>
@@ -39,8 +40,8 @@
#include <util/translation.h>
#include <wallet/coincontrol.h>
#include <wallet/context.h>
-#include <wallet/fees.h>
#include <wallet/external_signer_scriptpubkeyman.h>
+#include <wallet/fees.h>
#include <univalue.h>
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index e8c18dbb67..23c2de8191 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -7,7 +7,6 @@
#define BITCOIN_WALLET_WALLET_H
#include <consensus/amount.h>
-#include <fs.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
#include <logging.h>
@@ -15,6 +14,7 @@
#include <policy/feerate.h>
#include <psbt.h>
#include <tinyformat.h>
+#include <util/fs.h>
#include <util/hasher.h>
#include <util/message.h>
#include <util/result.h>
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 2cd35ae40e..3c0ed21b66 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -5,12 +5,12 @@
#include <wallet/walletdb.h>
-#include <fs.h>
#include <key_io.h>
#include <protocol.h>
#include <serialize.h>
#include <sync.h>
#include <util/bip32.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/time.h>
#include <util/translation.h>
diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp
index f389676204..acd817a311 100644
--- a/src/wallet/wallettool.cpp
+++ b/src/wallet/wallettool.cpp
@@ -8,7 +8,7 @@
#include <wallet/wallettool.h>
-#include <fs.h>
+#include <util/fs.h>
#include <util/system.h>
#include <util/translation.h>
#include <wallet/dump.h>
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index 8434d64fb5..f639078de5 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -5,8 +5,8 @@
#ifndef BITCOIN_WALLET_WALLETUTIL_H
#define BITCOIN_WALLET_WALLETUTIL_H
-#include <fs.h>
#include <script/descriptor.h>
+#include <util/fs.h>
#include <vector>